From 7288e8e454487406bb8e5a56e6f747cececcbaac Mon Sep 17 00:00:00 2001 From: John Tortugo Date: Tue, 16 Jul 2024 19:44:38 -0700 Subject: [PATCH 1/6] just the defaults. --- src/hotspot/share/c1/c1_GraphBuilder.cpp | 4 +- src/hotspot/share/c1/c1_LIRGenerator.cpp | 4 +- src/hotspot/share/ci/ciMethod.cpp | 10 +- src/hotspot/share/ci/ciMethod.hpp | 4 +- src/hotspot/share/code/nmethod.cpp | 6 +- .../share/compiler/compilationPolicy.cpp | 4 +- src/hotspot/share/compiler/compileBroker.cpp | 6 +- src/hotspot/share/compiler/compileTask.cpp | 3 +- .../share/compiler/compilerDirectives.cpp | 67 +++++---- .../share/compiler/compilerDirectives.hpp | 121 ++++++++-------- src/hotspot/share/compiler/compilerOracle.cpp | 72 +++++----- src/hotspot/share/compiler/compilerOracle.hpp | 136 +++++++++--------- .../share/compiler/directivesParser.cpp | 2 +- src/hotspot/share/compiler/methodMatcher.cpp | 36 +++-- src/hotspot/share/compiler/methodMatcher.hpp | 10 +- .../share/jvmci/jvmciCodeInstaller.cpp | 2 +- src/hotspot/share/jvmci/jvmciCompilerToVM.cpp | 4 +- src/hotspot/share/jvmci/jvmciEnv.cpp | 2 +- src/hotspot/share/oops/methodCounters.cpp | 2 +- src/hotspot/share/oops/methodData.cpp | 17 +-- src/hotspot/share/opto/bytecodeInfo.cpp | 6 +- src/hotspot/share/opto/compile.cpp | 4 +- src/hotspot/share/opto/compile.hpp | 4 +- src/hotspot/share/opto/runtime.cpp | 2 +- src/hotspot/share/prims/whitebox.cpp | 34 ++--- src/hotspot/share/runtime/java.cpp | 11 +- src/hotspot/share/runtime/sharedRuntime.cpp | 2 +- 27 files changed, 293 insertions(+), 282 deletions(-) diff --git a/src/hotspot/share/c1/c1_GraphBuilder.cpp b/src/hotspot/share/c1/c1_GraphBuilder.cpp index db025883b78ba..9dd06175abdf7 100644 --- a/src/hotspot/share/c1/c1_GraphBuilder.cpp +++ b/src/hotspot/share/c1/c1_GraphBuilder.cpp @@ -3588,7 +3588,7 @@ const char* GraphBuilder::check_can_parse(ciMethod* callee) const { // negative filter: should callee NOT be inlined? returns null, ok to inline, or rejection msg const char* GraphBuilder::should_not_inline(ciMethod* callee) const { - if ( compilation()->directive()->should_not_inline(callee)) return "disallowed by CompileCommand"; + if ( compilation()->directive()->should_not_inline(callee, compilation()->env()->comp_level())) return "disallowed by CompileCommand"; if ( callee->dont_inline()) return "don't inline by annotation"; return nullptr; } @@ -3918,7 +3918,7 @@ bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known, bool ign } // now perform tests that are based on flag settings - bool inlinee_by_directive = compilation()->directive()->should_inline(callee); + bool inlinee_by_directive = compilation()->directive()->should_inline(callee, compilation()->env()->comp_level()); if (callee->force_inline() || inlinee_by_directive) { if (inline_level() > MaxForceInlineLevel ) INLINE_BAILOUT("MaxForceInlineLevel"); if (recursive_inline_level(callee) > C1MaxRecursiveInlineLevel) INLINE_BAILOUT("recursive inlining too deep"); diff --git a/src/hotspot/share/c1/c1_LIRGenerator.cpp b/src/hotspot/share/c1/c1_LIRGenerator.cpp index cd08413565808..2991db8c91ec6 100644 --- a/src/hotspot/share/c1/c1_LIRGenerator.cpp +++ b/src/hotspot/share/c1/c1_LIRGenerator.cpp @@ -3217,7 +3217,7 @@ void LIRGenerator::do_ProfileInvoke(ProfileInvoke* x) { // Notify the runtime very infrequently only to take care of counter overflows int freq_log = Tier23InlineeNotifyFreqLog; double scale; - if (_method->has_option_value(CompileCommandEnum::CompileThresholdScaling, scale)) { + if (_method->has_option_value(CompileCommandEnum::CompileThresholdScaling, compilation()->env()->comp_level(), scale)) { freq_log = CompilerConfig::scaled_freq_log(freq_log, scale); } increment_event_counter_impl(info, x->inlinee(), LIR_OprFact::intConst(InvocationCounter::count_increment), right_n_bits(freq_log), InvocationEntryBci, false, true); @@ -3258,7 +3258,7 @@ void LIRGenerator::increment_event_counter(CodeEmitInfo* info, LIR_Opr step, int } // Increment the appropriate invocation/backedge counter and notify the runtime. double scale; - if (_method->has_option_value(CompileCommandEnum::CompileThresholdScaling, scale)) { + if (_method->has_option_value(CompileCommandEnum::CompileThresholdScaling, compilation()->env()->comp_level(), scale)) { freq_log = CompilerConfig::scaled_freq_log(freq_log, scale); } increment_event_counter_impl(info, info->scope()->method(), step, right_n_bits(freq_log), bci, backedge, true); diff --git a/src/hotspot/share/ci/ciMethod.cpp b/src/hotspot/share/ci/ciMethod.cpp index aac2a553cda31..0cdb90b7e0ee0 100644 --- a/src/hotspot/share/ci/ciMethod.cpp +++ b/src/hotspot/share/ci/ciMethod.cpp @@ -103,7 +103,7 @@ ciMethod::ciMethod(const methodHandle& h_m, ciInstanceKlass* holder) : #endif // COMPILER2 // Check for blackhole intrinsic and then populate the intrinsic ID. - CompilerOracle::tag_blackhole_if_possible(h_m); + CompilerOracle::tag_blackhole_if_possible(h_m, CURRENT_ENV->comp_level()); _intrinsic_id = h_m->intrinsic_id(); ciEnv *env = CURRENT_ENV; @@ -1063,21 +1063,21 @@ MethodCounters* ciMethod::ensure_method_counters() { // ------------------------------------------------------------------ // ciMethod::has_option // -bool ciMethod::has_option(CompileCommandEnum option) { +bool ciMethod::has_option(CompileCommandEnum option, int comp_level) { check_is_loaded(); VM_ENTRY_MARK; methodHandle mh(THREAD, get_Method()); - return CompilerOracle::has_option(mh, option); + return CompilerOracle::has_option(mh, option, comp_level); } // ------------------------------------------------------------------ // ciMethod::has_option_value // -bool ciMethod::has_option_value(CompileCommandEnum option, double& value) { +bool ciMethod::has_option_value(CompileCommandEnum option, int comp_level, double& value) { check_is_loaded(); VM_ENTRY_MARK; methodHandle mh(THREAD, get_Method()); - return CompilerOracle::has_option_value(mh, option, value); + return CompilerOracle::has_option_value(mh, option, comp_level, value); } // ------------------------------------------------------------------ // ciMethod::can_be_compiled diff --git a/src/hotspot/share/ci/ciMethod.hpp b/src/hotspot/share/ci/ciMethod.hpp index a7c18b09f13eb..0432c994db5a7 100644 --- a/src/hotspot/share/ci/ciMethod.hpp +++ b/src/hotspot/share/ci/ciMethod.hpp @@ -303,8 +303,8 @@ class ciMethod : public ciMetadata { // Find the proper vtable index to invoke this method. int resolve_vtable_index(ciKlass* caller, ciKlass* receiver); - bool has_option(CompileCommandEnum option); - bool has_option_value(CompileCommandEnum option, double& value); + bool has_option(CompileCommandEnum option, int comp_level); + bool has_option_value(CompileCommandEnum option, int comp_level, double& value); bool can_be_compiled(); bool can_be_parsed() const { return _can_be_parsed; } bool has_compiled_code(); diff --git a/src/hotspot/share/code/nmethod.cpp b/src/hotspot/share/code/nmethod.cpp index fab77fbbdb23f..1de0992f5f981 100644 --- a/src/hotspot/share/code/nmethod.cpp +++ b/src/hotspot/share/code/nmethod.cpp @@ -1688,15 +1688,15 @@ void nmethod::print_nmethod(bool printmethod) { #if defined(SUPPORT_DATA_STRUCTS) if (AbstractDisassembler::show_structs()) { methodHandle mh(Thread::current(), _method); - if (printmethod || PrintDebugInfo || CompilerOracle::has_option(mh, CompileCommandEnum::PrintDebugInfo)) { + if (printmethod || PrintDebugInfo || CompilerOracle::has_option(mh, CompileCommandEnum::PrintDebugInfo, _comp_level)) { print_scopes(); tty->print_cr("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - "); } - if (printmethod || PrintRelocations || CompilerOracle::has_option(mh, CompileCommandEnum::PrintRelocations)) { + if (printmethod || PrintRelocations || CompilerOracle::has_option(mh, CompileCommandEnum::PrintRelocations, _comp_level)) { print_relocations(); tty->print_cr("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - "); } - if (printmethod || PrintDependencies || CompilerOracle::has_option(mh, CompileCommandEnum::PrintDependencies)) { + if (printmethod || PrintDependencies || CompilerOracle::has_option(mh, CompileCommandEnum::PrintDependencies, _comp_level)) { print_dependencies_on(tty); tty->print_cr("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - "); } diff --git a/src/hotspot/share/compiler/compilationPolicy.cpp b/src/hotspot/share/compiler/compilationPolicy.cpp index 0e6d8f6a6c91b..d3da40259372c 100644 --- a/src/hotspot/share/compiler/compilationPolicy.cpp +++ b/src/hotspot/share/compiler/compilationPolicy.cpp @@ -229,7 +229,7 @@ class LoopPredicate : AllStatic { public: static bool apply_scaled(const methodHandle& method, CompLevel cur_level, int i, int b, double scale) { double threshold_scaling; - if (CompilerOracle::has_option_value(method, CompileCommandEnum::CompileThresholdScaling, threshold_scaling)) { + if (CompilerOracle::has_option_value(method, CompileCommandEnum::CompileThresholdScaling, cur_level, threshold_scaling)) { scale *= threshold_scaling; } switch(cur_level) { @@ -267,7 +267,7 @@ class CallPredicate : AllStatic { public: static bool apply_scaled(const methodHandle& method, CompLevel cur_level, int i, int b, double scale) { double threshold_scaling; - if (CompilerOracle::has_option_value(method, CompileCommandEnum::CompileThresholdScaling, threshold_scaling)) { + if (CompilerOracle::has_option_value(method, CompileCommandEnum::CompileThresholdScaling, cur_level, threshold_scaling)) { scale *= threshold_scaling; } switch(cur_level) { diff --git a/src/hotspot/share/compiler/compileBroker.cpp b/src/hotspot/share/compiler/compileBroker.cpp index 45b0b331e2513..f43965168d45c 100644 --- a/src/hotspot/share/compiler/compileBroker.cpp +++ b/src/hotspot/share/compiler/compileBroker.cpp @@ -1333,17 +1333,17 @@ nmethod* CompileBroker::compile_method(const methodHandle& method, int osr_bci, return nullptr; } +#if INCLUDE_JVMCI AbstractCompiler *comp = CompileBroker::compiler(comp_level); assert(comp != nullptr, "Ensure we have a compiler"); -#if INCLUDE_JVMCI if (comp->is_jvmci() && !JVMCI::can_initialize_JVMCI()) { // JVMCI compilation is not yet initializable. return nullptr; } #endif - DirectiveSet* directive = DirectivesStack::getMatchingDirective(method, comp); + DirectiveSet* directive = DirectivesStack::getMatchingDirective(method, comp_level); // CompileBroker::compile_method can trap and can have pending async exception. nmethod* nm = CompileBroker::compile_method(method, osr_bci, comp_level, hot_method, hot_count, compile_reason, directive, THREAD); DirectivesStack::release(directive); @@ -1547,7 +1547,7 @@ bool CompileBroker::compilation_is_prohibited(const methodHandle& method, int os // The method may be explicitly excluded by the user. double scale; - if (excluded || (CompilerOracle::has_option_value(method, CompileCommandEnum::CompileThresholdScaling, scale) && scale == 0)) { + if (excluded || (CompilerOracle::has_option_value(method, CompileCommandEnum::CompileThresholdScaling, comp_level, scale) && scale == 0)) { bool quietly = CompilerOracle::be_quiet(); if (PrintCompilation && !quietly) { // This does not happen quietly... diff --git a/src/hotspot/share/compiler/compileTask.cpp b/src/hotspot/share/compiler/compileTask.cpp index 1a2af5721665f..f81c63617e61d 100644 --- a/src/hotspot/share/compiler/compileTask.cpp +++ b/src/hotspot/share/compiler/compileTask.cpp @@ -117,8 +117,7 @@ void CompileTask::initialize(int compile_id, _time_started = 0; _compile_reason = compile_reason; _nm_content_size = 0; - AbstractCompiler* comp = compiler(); - _directive = DirectivesStack::getMatchingDirective(method, comp); + _directive = DirectivesStack::getMatchingDirective(method, comp_level); _nm_insts_size = 0; _nm_total_size = 0; _failure_reason = nullptr; diff --git a/src/hotspot/share/compiler/compilerDirectives.cpp b/src/hotspot/share/compiler/compilerDirectives.cpp index b48eb4fb817d8..c8acccc541382 100644 --- a/src/hotspot/share/compiler/compilerDirectives.cpp +++ b/src/hotspot/share/compiler/compilerDirectives.cpp @@ -142,14 +142,14 @@ CompilerDirectives* CompilerDirectives::next() { return _next; } -bool CompilerDirectives::match(const methodHandle& method) { +bool CompilerDirectives::match(const methodHandle& method, int comp_level) { if (is_default_directive()) { return true; } if (method == nullptr) { return false; } - if (_match->match(method)) { + if (_match->match(method, comp_level)) { return true; } return false; @@ -182,15 +182,12 @@ int CompilerDirectives::refcount() { return _ref_count; } -DirectiveSet* CompilerDirectives::get_for(AbstractCompiler *comp) { +DirectiveSet* CompilerDirectives::get_for(int comp_level) { assert(DirectivesStack_lock->owned_by_self(), ""); - if (comp == nullptr) { // Xint - return _c1_store; - } else if (comp->is_c2()) { + if (comp_level >= CompLevel::CompLevel_full_optimization) { return _c2_store; } else { // use c1_store as default - assert(comp->is_c1() || comp->is_jvmci(), ""); return _c1_store; } } @@ -304,7 +301,7 @@ DirectiveSet::DirectiveSet(CompilerDirectives* d) : _ideal_phase_name_set(PHASE_NUM_TYPES, mtCompiler), _trace_auto_vectorization_tags(TRACE_AUTO_VECTORIZATION_TAG_NUM, mtCompiler) { -#define init_defaults_definition(name, type, dvalue, compiler) this->name##Option = dvalue; +#define init_defaults_definition(name, type, dvalue, compiler, clevel) this->name##Option = dvalue; compilerdirectives_common_flags(init_defaults_definition) compilerdirectives_c2_flags(init_defaults_definition) compilerdirectives_c1_flags(init_defaults_definition) @@ -322,7 +319,7 @@ DirectiveSet::~DirectiveSet() { tmp = next; } -#define free_string_flags(name, type, dvalue, cc_flag) if (_modified[name##Index]) os::free(const_cast(name##Option)); +#define free_string_flags(name, type, dvalue, cc_flag, clevel) if (_modified[name##Index]) os::free(const_cast(name##Option)); compilerdirectives_common_string_flags(free_string_flags) compilerdirectives_c2_string_flags(free_string_flags) compilerdirectives_c1_string_flags(free_string_flags) @@ -377,7 +374,7 @@ class DirectiveSetPtr { // - if some option is changed we need to copy directiveset since it no longer can be shared // - Need to free copy after use // - Requires a modified bit so we don't overwrite options that is set by directives -DirectiveSet* DirectiveSet::compilecommand_compatibility_init(const methodHandle& method) { +DirectiveSet* DirectiveSet::compilecommand_compatibility_init(const methodHandle& method, int comp_level) { // Early bail out - checking all options is expensive - we rely on them not being used // Only set a flag if it has not been modified and value changes. // Only copy set if a flag needs to be set @@ -396,7 +393,7 @@ DirectiveSet* DirectiveSet::compilecommand_compatibility_init(const methodHandle // All CompileCommands are not equal so this gets a bit verbose // When CompileCommands have been refactored less clutter will remain. - if (CompilerOracle::should_break_at(method)) { + if (CompilerOracle::should_break_at(method, comp_level)) { // If the directives didn't have 'BreakAtCompile' or 'BreakAtExecute', // the sub-command 'Break' of the 'CompileCommand' would become effective. if (!_modified[BreakAtCompileIndex]) { @@ -407,26 +404,26 @@ DirectiveSet* DirectiveSet::compilecommand_compatibility_init(const methodHandle } } if (!_modified[LogIndex]) { - bool log = CompilerOracle::should_log(method); + bool log = CompilerOracle::should_log(method, comp_level); if (log != set->LogOption) { set.cloned()->LogOption = log; } } - if (CompilerOracle::should_print(method)) { + if (CompilerOracle::should_print(method, comp_level)) { if (!_modified[PrintAssemblyIndex]) { set.cloned()->PrintAssemblyOption = true; } } // Exclude as in should not compile == Enabled - if (CompilerOracle::should_exclude(method)) { + if (CompilerOracle::should_exclude(method, comp_level)) { if (!_modified[ExcludeIndex]) { set.cloned()->ExcludeOption = true; } } // inline and dontinline (including exclude) are implemented in the directiveset accessors -#define init_default_cc(name, type, dvalue, cc_flag) { type v; if (!_modified[name##Index] && CompileCommandEnum::cc_flag != CompileCommandEnum::Unknown && CompilerOracle::has_option_value(method, CompileCommandEnum::cc_flag, v) && v != this->name##Option) { set.cloned()->name##Option = v; } } +#define init_default_cc(name, type, dvalue, cc_flag, clevel) { type v; if (!_modified[name##Index] && CompileCommandEnum::cc_flag != CompileCommandEnum::Unknown && CompilerOracle::has_option_value(method, CompileCommandEnum::cc_flag, clevel, v) && v != this->name##Option) { set.cloned()->name##Option = v; } } compilerdirectives_common_flags(init_default_cc) compilerdirectives_c2_flags(init_default_cc) compilerdirectives_c1_flags(init_default_cc) @@ -438,7 +435,7 @@ DirectiveSet* DirectiveSet::compilecommand_compatibility_init(const methodHandle if (!_modified[TraceAutoVectorizationIndex]) { // Parse ccstr and create mask ccstrlist option; - if (CompilerOracle::has_option_value(method, CompileCommandEnum::TraceAutoVectorization, option)) { + if (CompilerOracle::has_option_value(method, CompileCommandEnum::TraceAutoVectorization, comp_level, option)) { TraceAutoVectorizationTagValidator validator(option, false); if (validator.is_valid()) { set.cloned()->set_trace_auto_vectorization_tags(validator.tags()); @@ -448,7 +445,7 @@ DirectiveSet* DirectiveSet::compilecommand_compatibility_init(const methodHandle if (!_modified[PrintIdealPhaseIndex]) { // Parse ccstr and create set ccstrlist option; - if (CompilerOracle::has_option_value(method, CompileCommandEnum::PrintIdealPhase, option)) { + if (CompilerOracle::has_option_value(method, CompileCommandEnum::PrintIdealPhase, comp_level, option)) { PhaseNameValidator validator(option); if (validator.is_valid()) { assert(!validator.phase_name_set().is_empty(), "Phase name set must be non-empty"); @@ -464,7 +461,7 @@ DirectiveSet* DirectiveSet::compilecommand_compatibility_init(const methodHandle bool need_reset = true; // if Control/DisableIntrinsic redefined, only need to reset control_words once if (!_modified[ControlIntrinsicIndex] && - CompilerOracle::has_option_value(method, CompileCommandEnum::ControlIntrinsic, option_value)) { + CompilerOracle::has_option_value(method, CompileCommandEnum::ControlIntrinsic, comp_level, option_value)) { ControlIntrinsicIter iter(option_value); if (need_reset) { @@ -484,7 +481,7 @@ DirectiveSet* DirectiveSet::compilecommand_compatibility_init(const methodHandle if (!_modified[DisableIntrinsicIndex] && - CompilerOracle::has_option_value(method, CompileCommandEnum::DisableIntrinsic, option_value)) { + CompilerOracle::has_option_value(method, CompileCommandEnum::DisableIntrinsic, comp_level, option_value)) { ControlIntrinsicIter iter(option_value, true/*disable_all*/); if (need_reset) { @@ -513,39 +510,39 @@ CompilerDirectives* DirectiveSet::directive() { return _directive; } -bool DirectiveSet::matches_inline(const methodHandle& method, int inline_action) { +bool DirectiveSet::matches_inline(const methodHandle& method, int comp_level, int inline_action) { if (_inlinematchers != nullptr) { - if (_inlinematchers->match(method, inline_action)) { + if (_inlinematchers->match(method, comp_level, inline_action)) { return true; } } return false; } -bool DirectiveSet::should_inline(ciMethod* inlinee) { +bool DirectiveSet::should_inline(ciMethod* inlinee, int comp_level) { inlinee->check_is_loaded(); VM_ENTRY_MARK; methodHandle mh(THREAD, inlinee->get_Method()); if (_inlinematchers != nullptr) { - return matches_inline(mh, InlineMatcher::force_inline); + return matches_inline(mh, comp_level, InlineMatcher::force_inline); } if (!CompilerDirectivesIgnoreCompileCommandsOption) { - return CompilerOracle::should_inline(mh); + return CompilerOracle::should_inline(mh, comp_level); } return false; } -bool DirectiveSet::should_not_inline(ciMethod* inlinee) { +bool DirectiveSet::should_not_inline(ciMethod* inlinee, int comp_level) { inlinee->check_is_loaded(); VM_ENTRY_MARK; methodHandle mh(THREAD, inlinee->get_Method()); if (_inlinematchers != nullptr) { - return matches_inline(mh, InlineMatcher::dont_inline); + return matches_inline(mh, comp_level, InlineMatcher::dont_inline); } if (!CompilerDirectivesIgnoreCompileCommandsOption) { - return CompilerOracle::should_not_inline(mh); + return CompilerOracle::should_not_inline(mh, comp_level); } return false; } @@ -617,13 +614,13 @@ DirectiveSet* DirectiveSet::clone(DirectiveSet const* src) { tmp = tmp->next(); } - #define copy_members_definition(name, type, dvalue, cc_flag) set->name##Option = src->name##Option; + #define copy_members_definition(name, type, dvalue, cc_flag, clevel) set->name##Option = src->name##Option; compilerdirectives_common_other_flags(copy_members_definition) compilerdirectives_c2_other_flags(copy_members_definition) compilerdirectives_c1_other_flags(copy_members_definition) #undef copy_members_definition -#define copy_string_members_definition(name, type, dvalue, cc_flag) \ +#define copy_string_members_definition(name, type, dvalue, cc_flag, clevel) \ if (src->_modified[name##Index]) { \ set->name##Option = os::strdup_check_oom(src->name##Option, mtCompiler); \ } else { \ @@ -657,12 +654,12 @@ void DirectivesStack::init() { push(_default_directives); } -DirectiveSet* DirectivesStack::getDefaultDirective(AbstractCompiler* comp) { +DirectiveSet* DirectivesStack::getDefaultDirective(int comp_level) { MutexLocker locker(DirectivesStack_lock, Mutex::_no_safepoint_check_flag); assert(_bottom != nullptr, "Must never be empty"); _bottom->inc_refcount(); - return _bottom->get_for(comp); + return _bottom->get_for(comp_level); } void DirectivesStack::push(CompilerDirectives* directive) { @@ -747,7 +744,7 @@ void DirectivesStack::release(CompilerDirectives* dir) { } } -DirectiveSet* DirectivesStack::getMatchingDirective(const methodHandle& method, AbstractCompiler *comp) { +DirectiveSet* DirectivesStack::getMatchingDirective(const methodHandle& method, int comp_level) { assert(_depth > 0, "Must never be empty"); DirectiveSet* match = nullptr; @@ -758,8 +755,8 @@ DirectiveSet* DirectivesStack::getMatchingDirective(const methodHandle& method, assert(dir != nullptr, "Must be initialized"); while (dir != nullptr) { - if (dir->is_default_directive() || dir->match(method)) { - match = dir->get_for(comp); + if (dir->is_default_directive() || dir->match(method, comp_level)) { + match = dir->get_for(comp_level); assert(match != nullptr, "Consistency"); if (match->EnableOption) { // The directiveSet for this compile is also enabled -> success @@ -773,5 +770,5 @@ DirectiveSet* DirectivesStack::getMatchingDirective(const methodHandle& method, guarantee(match != nullptr, "There should always be a default directive that matches"); // Check for legacy compile commands update, without DirectivesStack_lock - return match->compilecommand_compatibility_init(method); + return match->compilecommand_compatibility_init(method, comp_level); } diff --git a/src/hotspot/share/compiler/compilerDirectives.hpp b/src/hotspot/share/compiler/compilerDirectives.hpp index bf15fe9c71397..f19ad0ea4ccae 100644 --- a/src/hotspot/share/compiler/compilerDirectives.hpp +++ b/src/hotspot/share/compiler/compilerDirectives.hpp @@ -35,28 +35,30 @@ #include "utilities/exceptions.hpp" #include "utilities/tribool.hpp" - // Directives flag name, type, default value, compile command name - #define compilerdirectives_common_other_flags(cflags) \ - cflags(Enable, bool, false, Unknown) \ - cflags(Exclude, bool, false, Unknown) \ - cflags(BreakAtExecute, bool, false, BreakAtExecute) \ - cflags(BreakAtCompile, bool, false, BreakAtCompile) \ - cflags(Log, bool, LogCompilation, Unknown) \ - cflags(MemLimit, intx, 0, MemLimit) \ - cflags(MemStat, uintx, 0, MemStat) \ - cflags(PrintAssembly, bool, PrintAssembly, PrintAssembly) \ - cflags(PrintCompilation, bool, PrintCompilation, PrintCompilation) \ - cflags(PrintInlining, bool, PrintInlining, PrintInlining) \ - cflags(PrintNMethods, bool, PrintNMethods, PrintNMethods) \ - cflags(BackgroundCompilation, bool, BackgroundCompilation, BackgroundCompilation) \ - cflags(ReplayInline, bool, false, ReplayInline) \ - cflags(DumpReplay, bool, false, DumpReplay) \ - cflags(DumpInline, bool, false, DumpInline) \ - cflags(CompilerDirectivesIgnoreCompileCommands, bool, CompilerDirectivesIgnoreCompileCommands, Unknown) \ - cflags(RepeatCompilation, intx, RepeatCompilation, RepeatCompilation) -#define compilerdirectives_common_string_flags(cflags) \ - cflags(DisableIntrinsic, ccstrlist, DisableIntrinsic, DisableIntrinsic) \ - cflags(ControlIntrinsic, ccstrlist, ControlIntrinsic, ControlIntrinsic) +// Directives flag name, type, default value, compile command name, compilation level +#define compilerdirectives_common_other_flags(cflags) \ + cflags(Enable, bool, false, Unknown, CompLevel::CompLevel_all) \ + cflags(Exclude, bool, false, Unknown, CompLevel::CompLevel_all) \ + cflags(BreakAtExecute, bool, false, BreakAtExecute, CompLevel::CompLevel_all) \ + cflags(BreakAtCompile, bool, false, BreakAtCompile, CompLevel::CompLevel_all) \ + cflags(Log, bool, LogCompilation, Unknown, CompLevel::CompLevel_all) \ + cflags(MemLimit, intx, 0, MemLimit, CompLevel::CompLevel_all) \ + cflags(MemStat, uintx, 0, MemStat, CompLevel::CompLevel_all) \ + cflags(PrintAssembly, bool, PrintAssembly, PrintAssembly, CompLevel::CompLevel_all) \ + cflags(PrintCompilation, bool, PrintCompilation, PrintCompilation, CompLevel::CompLevel_all) \ + cflags(PrintInlining, bool, PrintInlining, PrintInlining, CompLevel::CompLevel_all) \ + cflags(PrintNMethods, bool, PrintNMethods, PrintNMethods, CompLevel::CompLevel_all) \ + cflags(BackgroundCompilation, bool, BackgroundCompilation, BackgroundCompilation, CompLevel::CompLevel_all) \ + cflags(ReplayInline, bool, false, ReplayInline, CompLevel::CompLevel_all) \ + cflags(DumpReplay, bool, false, DumpReplay, CompLevel::CompLevel_all) \ + cflags(DumpInline, bool, false, DumpInline, CompLevel::CompLevel_all) \ + cflags(CompilerDirectivesIgnoreCompileCommands, bool, CompilerDirectivesIgnoreCompileCommands, Unknown, CompLevel::CompLevel_all) \ + cflags(RepeatCompilation, intx, RepeatCompilation, RepeatCompilation, CompLevel::CompLevel_all) + +#define compilerdirectives_common_string_flags(cflags) \ + cflags(DisableIntrinsic, ccstrlist, DisableIntrinsic, DisableIntrinsic, CompLevel::CompLevel_all) \ + cflags(ControlIntrinsic, ccstrlist, ControlIntrinsic, ControlIntrinsic, CompLevel::CompLevel_all) + #define compilerdirectives_common_flags(cflags) \ compilerdirectives_common_other_flags(cflags) \ compilerdirectives_common_string_flags(cflags) @@ -74,23 +76,24 @@ compilerdirectives_c1_string_flags(cflags) #ifdef COMPILER2 - #define compilerdirectives_c2_other_flags(cflags) \ - cflags(BlockLayoutByFrequency, bool, BlockLayoutByFrequency, BlockLayoutByFrequency) \ - cflags(PrintOptoAssembly, bool, PrintOptoAssembly, PrintOptoAssembly) \ - cflags(PrintIntrinsics, bool, PrintIntrinsics, PrintIntrinsics) \ -NOT_PRODUCT(cflags(TraceOptoPipelining, bool, TraceOptoPipelining, TraceOptoPipelining)) \ -NOT_PRODUCT(cflags(TraceOptoOutput, bool, TraceOptoOutput, TraceOptoOutput)) \ -NOT_PRODUCT(cflags(TraceEscapeAnalysis, bool, false, TraceEscapeAnalysis)) \ -NOT_PRODUCT(cflags(PrintIdeal, bool, PrintIdeal, PrintIdeal)) \ - cflags(TraceSpilling, bool, TraceSpilling, TraceSpilling) \ - cflags(Vectorize, bool, false, Vectorize) \ - cflags(CloneMapDebug, bool, false, CloneMapDebug) \ -NOT_PRODUCT(cflags(IGVPrintLevel, intx, PrintIdealGraphLevel, IGVPrintLevel)) \ - cflags(IncrementalInlineForceCleanup, bool, IncrementalInlineForceCleanup, IncrementalInlineForceCleanup) \ - cflags(MaxNodeLimit, intx, MaxNodeLimit, MaxNodeLimit) -#define compilerdirectives_c2_string_flags(cflags) \ -NOT_PRODUCT(cflags(TraceAutoVectorization, ccstrlist, "", TraceAutoVectorization)) \ -NOT_PRODUCT(cflags(PrintIdealPhase, ccstrlist, "", PrintIdealPhase)) +#define compilerdirectives_c2_other_flags(cflags) \ + cflags(BlockLayoutByFrequency, bool, BlockLayoutByFrequency, BlockLayoutByFrequency, CompLevel::CompLevel_all) \ + cflags(PrintOptoAssembly, bool, PrintOptoAssembly, PrintOptoAssembly, CompLevel::CompLevel_all) \ + cflags(PrintIntrinsics, bool, PrintIntrinsics, PrintIntrinsics, CompLevel::CompLevel_all) \ +NOT_PRODUCT(cflags(TraceOptoPipelining, bool, TraceOptoPipelining, TraceOptoPipelining, CompLevel::CompLevel_all)) \ +NOT_PRODUCT(cflags(TraceOptoOutput, bool, TraceOptoOutput, TraceOptoOutput, CompLevel::CompLevel_all)) \ +NOT_PRODUCT(cflags(TraceEscapeAnalysis, bool, false, TraceEscapeAnalysis, CompLevel::CompLevel_all)) \ +NOT_PRODUCT(cflags(PrintIdeal, bool, PrintIdeal, PrintIdeal, CompLevel::CompLevel_all)) \ + cflags(TraceSpilling, bool, TraceSpilling, TraceSpilling, CompLevel::CompLevel_all) \ + cflags(Vectorize, bool, false, Vectorize, CompLevel::CompLevel_all) \ + cflags(CloneMapDebug, bool, false, CloneMapDebug, CompLevel::CompLevel_all) \ +NOT_PRODUCT(cflags(IGVPrintLevel, intx, PrintIdealGraphLevel, IGVPrintLevel, CompLevel::CompLevel_all)) \ + cflags(IncrementalInlineForceCleanup, bool, IncrementalInlineForceCleanup, IncrementalInlineForceCleanup, CompLevel::CompLevel_all) \ + cflags(MaxNodeLimit, intx, MaxNodeLimit, MaxNodeLimit, CompLevel::CompLevel_all) + +#define compilerdirectives_c2_string_flags(cflags) \ +NOT_PRODUCT(cflags(TraceAutoVectorization, ccstrlist, "", TraceAutoVectorization, CompLevel::CompLevel_all)) \ +NOT_PRODUCT(cflags(PrintIdealPhase, ccstrlist, "", PrintIdealPhase, CompLevel::CompLevel_all)) #else #define compilerdirectives_c2_other_flags(cflags) #define compilerdirectives_c2_string_flags(cflags) @@ -113,8 +116,8 @@ class DirectivesStack : AllStatic { static void pop_inner(); // no lock version of pop public: static void init(); - static DirectiveSet* getMatchingDirective(const methodHandle& mh, AbstractCompiler* comp); - static DirectiveSet* getDefaultDirective(AbstractCompiler* comp); + static DirectiveSet* getMatchingDirective(const methodHandle& mh, int comp_level); + static DirectiveSet* getDefaultDirective(int comp_level); static void push(CompilerDirectives* directive); static void pop(int count); static bool check_capacity(int request_size, outputStream* st); @@ -139,12 +142,12 @@ class DirectiveSet : public CHeapObj { CompilerDirectives* directive(); bool parse_and_add_inline(char* str, const char*& error_msg); void append_inline(InlineMatcher* m); - bool should_inline(ciMethod* inlinee); - bool should_not_inline(ciMethod* inlinee); + bool should_inline(ciMethod* inlinee, int comp_level); + bool should_not_inline(ciMethod* inlinee, int comp_level); void print_inline(outputStream* st); - DirectiveSet* compilecommand_compatibility_init(const methodHandle& method); + DirectiveSet* compilecommand_compatibility_init(const methodHandle& method, int comp_level); bool is_exclusive_copy() { return _directive == nullptr; } - bool matches_inline(const methodHandle& method, int inline_action); + bool matches_inline(const methodHandle& method, int comp_level, int inline_action); static DirectiveSet* clone(DirectiveSet const* src); bool is_intrinsic_disabled(vmIntrinsicID id); static ccstrlist canonicalize_control_intrinsic(ccstrlist option_value); @@ -157,7 +160,7 @@ class DirectiveSet : public CHeapObj { bool should_crash_at_mem_limit() const; // true: crash false: stop compilation typedef enum { -#define enum_of_flags(name, type, dvalue, cc_flag) name##Index, +#define enum_of_flags(name, type, dvalue, cc_flag, clevel) name##Index, compilerdirectives_common_flags(enum_of_flags) compilerdirectives_c2_flags(enum_of_flags) compilerdirectives_c1_flags(enum_of_flags) @@ -168,14 +171,14 @@ class DirectiveSet : public CHeapObj { private: bool _modified[number_of_flags]; // Records what options where set by a directive public: -#define flag_store_definition(name, type, dvalue, cc_flag) type name##Option; +#define flag_store_definition(name, type, dvalue, cc_flag, clevel) type name##Option; compilerdirectives_common_flags(flag_store_definition) compilerdirectives_c2_flags(flag_store_definition) compilerdirectives_c1_flags(flag_store_definition) #undef flag_store_definition // Casting to get the same function signature for all setters. Used from parser. -#define set_function_definition(name, type, dvalue, cc_flag) void set_##name(void* value) { type val = *(type*)value; name##Option = val; _modified[name##Index] = true; } +#define set_function_definition(name, type, dvalue, cc_flag, clevel) void set_##name(void* value) { type val = *(type*)value; name##Option = val; _modified[name##Index] = true; } compilerdirectives_common_other_flags(set_function_definition) compilerdirectives_c2_other_flags(set_function_definition) compilerdirectives_c1_other_flags(set_function_definition) @@ -185,14 +188,14 @@ class DirectiveSet : public CHeapObj { // // IMPORTANT: Takes ownership, will use os::free. Ensure the memory was dynamically allocated on the // C heap. -#define set_string_function_definition(name, type, dvalue, cc_flag) \ -void set_##name(void* value) { \ - if (_modified[name##Index]) { \ - os::free(const_cast(name##Option)); \ - } \ - type val = *(type*)value; \ - name##Option = val; \ - _modified[name##Index] = true; \ +#define set_string_function_definition(name, type, dvalue, cc_flag, clevel) \ +void set_##name(void* value) { \ + if (_modified[name##Index]) { \ + os::free(const_cast(name##Option)); \ + } \ + type val = *(type*)value; \ + name##Option = val; \ + _modified[name##Index] = true; \ } compilerdirectives_common_string_flags(set_string_function_definition) compilerdirectives_c2_string_flags(set_string_function_definition) @@ -222,7 +225,7 @@ void set_##name(void* value) { \ void print(outputStream* st) { print_inline(st); st->print(" "); -#define print_function_definition(name, type, dvalue, cc_flag) print_##type(st, #name, this->name##Option, true); +#define print_function_definition(name, type, dvalue, cc_flag, clevel) print_##type(st, #name, this->name##Option, true); compilerdirectives_common_flags(print_function_definition) compilerdirectives_c2_flags(print_function_definition) compilerdirectives_c1_flags(print_function_definition) @@ -302,10 +305,10 @@ class CompilerDirectives : public CHeapObj { CompilerDirectives* next(); void set_next(CompilerDirectives* next) {_next = next; } - bool match(const methodHandle& method); + bool match(const methodHandle& method, int comp_level); BasicMatcher* match() { return _match; } bool add_match(char* str, const char*& error_msg); - DirectiveSet* get_for(AbstractCompiler *comp); + DirectiveSet* get_for(int comp_level); void print(outputStream* st); bool is_default_directive() { return _next == nullptr; } void finalize(outputStream* st); diff --git a/src/hotspot/share/compiler/compilerOracle.cpp b/src/hotspot/share/compiler/compilerOracle.cpp index a81d60c9fc422..39e66cbb2197d 100644 --- a/src/hotspot/share/compiler/compilerOracle.cpp +++ b/src/hotspot/share/compiler/compilerOracle.cpp @@ -164,7 +164,7 @@ class TypedMethodOptionMatcher : public MethodMatcher { ~TypedMethodOptionMatcher(); static TypedMethodOptionMatcher* parse_method_pattern(char*& line, char* errorbuf, const int buf_size); - TypedMethodOptionMatcher* match(const methodHandle &method, CompileCommandEnum option); + TypedMethodOptionMatcher* match(const methodHandle &method, CompileCommandEnum option, int comp_level); void init(CompileCommandEnum option, TypedMethodOptionMatcher* next) { _next = next; @@ -173,8 +173,8 @@ class TypedMethodOptionMatcher : public MethodMatcher { void init_matcher(Symbol* class_name, Mode class_mode, Symbol* method_name, Mode method_mode, - Symbol* signature) { - MethodMatcher::init(class_name, class_mode, method_name, method_mode, signature); + Symbol* signature, int comp_level) { + MethodMatcher::init(class_name, class_mode, method_name, method_mode, signature, comp_level); } void set_next(TypedMethodOptionMatcher* next) {_next = next; } @@ -304,11 +304,11 @@ TypedMethodOptionMatcher* TypedMethodOptionMatcher::parse_method_pattern(char*& return tom; } -TypedMethodOptionMatcher* TypedMethodOptionMatcher::match(const methodHandle& method, CompileCommandEnum option) { +TypedMethodOptionMatcher* TypedMethodOptionMatcher::match(const methodHandle& method, CompileCommandEnum option, int comp_level) { TypedMethodOptionMatcher* current = this; while (current != nullptr) { if (current->_option == option) { - if (current->matches(method)) { + if (current->matches(method, comp_level)) { return current; } } @@ -351,13 +351,13 @@ static void register_command(TypedMethodOptionMatcher* matcher, } template -bool CompilerOracle::has_option_value(const methodHandle& method, CompileCommandEnum option, T& value) { +bool CompilerOracle::has_option_value(const methodHandle& method, CompileCommandEnum option, int comp_level, T& value) { assert(option_matches_type(option, value), "Value must match option type"); if (!has_command(option)) { return false; } if (option_list != nullptr) { - TypedMethodOptionMatcher* m = option_list->match(method, option); + TypedMethodOptionMatcher* m = option_list->match(method, option, comp_level); if (m != nullptr) { value = m->value(); return true; @@ -366,12 +366,12 @@ bool CompilerOracle::has_option_value(const methodHandle& method, CompileCommand return false; } -static bool resolve_inlining_predicate(CompileCommandEnum option, const methodHandle& method) { +static bool resolve_inlining_predicate(CompileCommandEnum option, const methodHandle& method, int comp_level) { assert(option == CompileCommandEnum::Inline || option == CompileCommandEnum::DontInline, "Sanity"); bool v1 = false; bool v2 = false; - bool has_inline = CompilerOracle::has_option_value(method, CompileCommandEnum::Inline, v1); - bool has_dnotinline = CompilerOracle::has_option_value(method, CompileCommandEnum::DontInline, v2); + bool has_inline = CompilerOracle::has_option_value(method, CompileCommandEnum::Inline, comp_level, v1); + bool has_dnotinline = CompilerOracle::has_option_value(method, CompileCommandEnum::DontInline, comp_level, v2); if (has_inline && has_dnotinline) { if (v1 && v2) { // Conflict options detected @@ -382,7 +382,7 @@ static bool resolve_inlining_predicate(CompileCommandEnum option, const methodHa while (current != nullptr) { last_one = current->option(); if (last_one == CompileCommandEnum::Inline || last_one == CompileCommandEnum::DontInline) { - if (current->matches(method)) { + if (current->matches(method, comp_level)) { return last_one == option; } } @@ -403,14 +403,14 @@ static bool resolve_inlining_predicate(CompileCommandEnum option, const methodHa } } -static bool check_predicate(CompileCommandEnum option, const methodHandle& method) { +static bool check_predicate(CompileCommandEnum option, const methodHandle& method, int comp_level) { // Special handling for Inline and DontInline since conflict options may be specified if (option == CompileCommandEnum::Inline || option == CompileCommandEnum::DontInline) { - return resolve_inlining_predicate(option, method); + return resolve_inlining_predicate(option, method, comp_level); } bool value = false; - if (CompilerOracle::has_option_value(method, option, value)) { + if (CompilerOracle::has_option_value(method, option, comp_level, value)) { return value; } return false; @@ -421,11 +421,11 @@ bool CompilerOracle::has_any_command_set() { } // Explicit instantiation for all OptionTypes supported. -template bool CompilerOracle::has_option_value(const methodHandle& method, CompileCommandEnum option, intx& value); -template bool CompilerOracle::has_option_value(const methodHandle& method, CompileCommandEnum option, uintx& value); -template bool CompilerOracle::has_option_value(const methodHandle& method, CompileCommandEnum option, bool& value); -template bool CompilerOracle::has_option_value(const methodHandle& method, CompileCommandEnum option, ccstr& value); -template bool CompilerOracle::has_option_value(const methodHandle& method, CompileCommandEnum option, double& value); +template bool CompilerOracle::has_option_value(const methodHandle& method, CompileCommandEnum option, int comp_level, intx& value); +template bool CompilerOracle::has_option_value(const methodHandle& method, CompileCommandEnum option, int comp_level, uintx& value); +template bool CompilerOracle::has_option_value(const methodHandle& method, CompileCommandEnum option, int comp_level, bool& value); +template bool CompilerOracle::has_option_value(const methodHandle& method, CompileCommandEnum option, int comp_level, ccstr& value); +template bool CompilerOracle::has_option_value(const methodHandle& method, CompileCommandEnum option, int comp_level, double& value); template bool CompilerOracle::option_matches_type(CompileCommandEnum option, T& value) { @@ -445,32 +445,32 @@ template bool CompilerOracle::option_matches_type(CompileCommandEnum optio template bool CompilerOracle::option_matches_type(CompileCommandEnum option, ccstr& value); template bool CompilerOracle::option_matches_type(CompileCommandEnum option, double& value); -bool CompilerOracle::has_option(const methodHandle& method, CompileCommandEnum option) { +bool CompilerOracle::has_option(const methodHandle& method, CompileCommandEnum option, int comp_level) { bool value = false; - has_option_value(method, option, value); + has_option_value(method, option, comp_level, value); return value; } -bool CompilerOracle::should_exclude(const methodHandle& method) { - if (check_predicate(CompileCommandEnum::Exclude, method)) { +bool CompilerOracle::should_exclude(const methodHandle& method, int comp_level) { + if (check_predicate(CompileCommandEnum::Exclude, method, comp_level)) { return true; } if (has_command(CompileCommandEnum::CompileOnly)) { - return !check_predicate(CompileCommandEnum::CompileOnly, method); + return !check_predicate(CompileCommandEnum::CompileOnly, method, comp_level); } return false; } -bool CompilerOracle::should_inline(const methodHandle& method) { - return (check_predicate(CompileCommandEnum::Inline, method)); +bool CompilerOracle::should_inline(const methodHandle& method, int comp_level) { + return (check_predicate(CompileCommandEnum::Inline, method, comp_level)); } -bool CompilerOracle::should_not_inline(const methodHandle& method) { - return check_predicate(CompileCommandEnum::DontInline, method) || check_predicate(CompileCommandEnum::Exclude, method); +bool CompilerOracle::should_not_inline(const methodHandle& method, int comp_level) { + return check_predicate(CompileCommandEnum::DontInline, method, comp_level) || check_predicate(CompileCommandEnum::Exclude, method, comp_level); } -bool CompilerOracle::should_print(const methodHandle& method) { - return check_predicate(CompileCommandEnum::Print, method); +bool CompilerOracle::should_print(const methodHandle& method, int comp_level) { + return check_predicate(CompileCommandEnum::Print, method, comp_level); } bool CompilerOracle::should_print_methods() { @@ -486,20 +486,20 @@ bool CompilerOracle::should_print_final_memstat_report() { return print_final_memstat_report; } -bool CompilerOracle::should_log(const methodHandle& method) { +bool CompilerOracle::should_log(const methodHandle& method, int comp_level) { if (!LogCompilation) return false; if (!has_command(CompileCommandEnum::Log)) { return true; // by default, log all } - return (check_predicate(CompileCommandEnum::Log, method)); + return check_predicate(CompileCommandEnum::Log, method, comp_level); } -bool CompilerOracle::should_break_at(const methodHandle& method) { - return check_predicate(CompileCommandEnum::Break, method); +bool CompilerOracle::should_break_at(const methodHandle& method, int comp_level) { + return check_predicate(CompileCommandEnum::Break, method, comp_level); } -void CompilerOracle::tag_blackhole_if_possible(const methodHandle& method) { - if (!check_predicate(CompileCommandEnum::Blackhole, method)) { +void CompilerOracle::tag_blackhole_if_possible(const methodHandle& method, int comp_level) { + if (!check_predicate(CompileCommandEnum::Blackhole, method, comp_level)) { return; } guarantee(UnlockExperimentalVMOptions, "Checked during initial parsing"); diff --git a/src/hotspot/share/compiler/compilerOracle.hpp b/src/hotspot/share/compiler/compilerOracle.hpp index 1a85e0629f93e..82bb27acfc8da 100644 --- a/src/hotspot/share/compiler/compilerOracle.hpp +++ b/src/hotspot/share/compiler/compilerOracle.hpp @@ -44,63 +44,63 @@ class methodHandle; type(Ccstrlist, "ccstrlist") \ type(Double, "double") -// COMPILECOMMAND_OPTIONS: option, name, variant, type -#define COMPILECOMMAND_OPTIONS(option) \ - option(Help, "help", Unknown) \ - option(Quiet, "quiet", Unknown) \ - option(Log, "log", Bool) \ - option(Print, "print", Bool) \ - option(Inline, "inline", Bool) \ - option(DontInline, "dontinline", Bool) \ - option(Blackhole, "blackhole", Bool) \ - option(CompileOnly, "compileonly", Bool)\ - option(Exclude, "exclude", Bool) \ - option(Break, "break", Bool) \ - option(BreakAtExecute, "BreakAtExecute", Bool) \ - option(BreakAtCompile, "BreakAtCompile", Bool) \ - option(MemLimit, "MemLimit", Intx) \ - option(MemStat, "MemStat", Uintx) \ - option(PrintAssembly, "PrintAssembly", Bool) \ - option(PrintCompilation, "PrintCompilation", Bool) \ - option(PrintInlining, "PrintInlining", Bool) \ - option(PrintIntrinsics, "PrintIntrinsics", Bool) \ - option(PrintNMethods, "PrintNMethods", Bool) \ - option(PrintOptoAssembly, "PrintOptoAssembly", Bool) \ - option(PrintDebugInfo, "PrintDebugInfo", Bool) \ - option(PrintRelocations, "PrintRelocations", Bool) \ - option(PrintDependencies, "PrintDependencies", Bool) \ - option(BackgroundCompilation, "BackgroundCompilation", Bool) \ - option(RepeatCompilation, "RepeatCompilation", Intx) \ - option(ReplayInline, "ReplayInline", Bool) \ - option(DumpReplay, "DumpReplay", Bool) \ - option(DumpInline, "DumpInline", Bool) \ - option(CompileThresholdScaling, "CompileThresholdScaling", Double) \ - option(ControlIntrinsic, "ControlIntrinsic", Ccstrlist) \ - option(DisableIntrinsic, "DisableIntrinsic", Ccstrlist) \ - option(NoRTMLockEliding, "NoRTMLockEliding", Bool) \ - option(UseRTMLockEliding, "UseRTMLockEliding", Bool) \ - option(BlockLayoutByFrequency, "BlockLayoutByFrequency", Bool) \ - option(TraceOptoPipelining, "TraceOptoPipelining", Bool) \ - option(TraceOptoOutput, "TraceOptoOutput", Bool) \ - option(TraceSpilling, "TraceSpilling", Bool) \ -NOT_PRODUCT(option(TraceEscapeAnalysis, "TraceEscapeAnalysis", Bool)) \ -NOT_PRODUCT(option(PrintIdeal, "PrintIdeal", Bool)) \ -NOT_PRODUCT(option(PrintIdealPhase, "PrintIdealPhase", Ccstrlist)) \ -NOT_PRODUCT(option(IGVPrintLevel, "IGVPrintLevel", Intx)) \ -NOT_PRODUCT(option(TraceAutoVectorization, "TraceAutoVectorization", Ccstrlist)) \ - option(Vectorize, "Vectorize", Bool) \ - option(CloneMapDebug, "CloneMapDebug", Bool) \ - option(IncrementalInlineForceCleanup, "IncrementalInlineForceCleanup", Bool) \ - option(MaxNodeLimit, "MaxNodeLimit", Intx) \ -NOT_PRODUCT(option(TestOptionInt, "TestOptionInt", Intx)) \ -NOT_PRODUCT(option(TestOptionUint, "TestOptionUint", Uintx)) \ -NOT_PRODUCT(option(TestOptionBool, "TestOptionBool", Bool)) \ -NOT_PRODUCT(option(TestOptionBool2, "TestOptionBool2", Bool)) \ -NOT_PRODUCT(option(TestOptionStr, "TestOptionStr", Ccstr)) \ -NOT_PRODUCT(option(TestOptionList, "TestOptionList", Ccstrlist)) \ -NOT_PRODUCT(option(TestOptionDouble, "TestOptionDouble", Double)) \ - option(Option, "option", Unknown) \ - option(Unknown, "unknown", Unknown) +// COMPILECOMMAND_OPTIONS: option, name, type +#define COMPILECOMMAND_OPTIONS(option) \ + option(Help, "help", Unknown) \ + option(Quiet, "quiet", Unknown) \ + option(Log, "log", Bool) \ + option(Print, "print", Bool) \ + option(Inline, "inline", Bool) \ + option(DontInline, "dontinline", Bool) \ + option(Blackhole, "blackhole", Bool) \ + option(CompileOnly, "compileonly", Bool) \ + option(Exclude, "exclude", Bool) \ + option(Break, "break", Bool) \ + option(BreakAtExecute, "BreakAtExecute", Bool) \ + option(BreakAtCompile, "BreakAtCompile", Bool) \ + option(MemLimit, "MemLimit", Intx) \ + option(MemStat, "MemStat", Uintx) \ + option(PrintAssembly, "PrintAssembly", Bool) \ + option(PrintCompilation, "PrintCompilation", Bool) \ + option(PrintInlining, "PrintInlining", Bool) \ + option(PrintIntrinsics, "PrintIntrinsics", Bool) \ + option(PrintNMethods, "PrintNMethods", Bool) \ + option(PrintOptoAssembly, "PrintOptoAssembly", Bool) \ + option(PrintDebugInfo, "PrintDebugInfo", Bool) \ + option(PrintRelocations, "PrintRelocations", Bool) \ + option(PrintDependencies, "PrintDependencies", Bool) \ + option(BackgroundCompilation, "BackgroundCompilation", Bool) \ + option(RepeatCompilation, "RepeatCompilation", Intx) \ + option(ReplayInline, "ReplayInline", Bool) \ + option(DumpReplay, "DumpReplay", Bool) \ + option(DumpInline, "DumpInline", Bool) \ + option(CompileThresholdScaling, "CompileThresholdScaling", Double) \ + option(ControlIntrinsic, "ControlIntrinsic", Ccstrlist) \ + option(DisableIntrinsic, "DisableIntrinsic", Ccstrlist) \ + option(NoRTMLockEliding, "NoRTMLockEliding", Bool) \ + option(UseRTMLockEliding, "UseRTMLockEliding", Bool) \ + option(BlockLayoutByFrequency, "BlockLayoutByFrequency", Bool) \ + option(TraceOptoPipelining, "TraceOptoPipelining", Bool) \ + option(TraceOptoOutput, "TraceOptoOutput", Bool) \ + option(TraceSpilling, "TraceSpilling", Bool) \ + option(Vectorize, "Vectorize", Bool) \ + option(CloneMapDebug, "CloneMapDebug", Bool) \ + option(IncrementalInlineForceCleanup, "IncrementalInlineForceCleanup", Bool) \ + option(MaxNodeLimit, "MaxNodeLimit", Intx) \ +NOT_PRODUCT(option(TraceEscapeAnalysis, "TraceEscapeAnalysis", Bool)) \ +NOT_PRODUCT(option(PrintIdeal, "PrintIdeal", Bool)) \ +NOT_PRODUCT(option(PrintIdealPhase, "PrintIdealPhase", Ccstrlist)) \ +NOT_PRODUCT(option(IGVPrintLevel, "IGVPrintLevel", Intx)) \ +NOT_PRODUCT(option(TraceAutoVectorization, "TraceAutoVectorization", Ccstrlist)) \ +NOT_PRODUCT(option(TestOptionInt, "TestOptionInt", Intx)) \ +NOT_PRODUCT(option(TestOptionUint, "TestOptionUint", Uintx)) \ +NOT_PRODUCT(option(TestOptionBool, "TestOptionBool", Bool)) \ +NOT_PRODUCT(option(TestOptionBool2, "TestOptionBool2", Bool)) \ +NOT_PRODUCT(option(TestOptionStr, "TestOptionStr", Ccstr)) \ +NOT_PRODUCT(option(TestOptionList, "TestOptionList", Ccstrlist)) \ +NOT_PRODUCT(option(TestOptionDouble, "TestOptionDouble", Double)) \ + option(Option, "option", Unknown) \ + option(Unknown, "unknown", Unknown) enum class CompileCommandEnum : int { #define enum_of_options(option, name, ctype) option, @@ -140,27 +140,27 @@ class CompilerOracle : AllStatic { // Reads from file and adds to lists static bool parse_from_file(); - // Tells whether we to exclude compilation of method - static bool should_exclude(const methodHandle& method); + // Tells whether we want to exclude compilation of this method + static bool should_exclude(const methodHandle& method, int comp_level); static bool be_quiet() { return _quiet; } // Tells whether we want to inline this method - static bool should_inline(const methodHandle& method); + static bool should_inline(const methodHandle& method, int comp_level); // Tells whether we want to disallow inlining of this method - static bool should_not_inline(const methodHandle& method); + static bool should_not_inline(const methodHandle& method, int comp_level); // Tells whether this method changes Thread.currentThread() - static bool changes_current_thread(const methodHandle& method); + static bool changes_current_thread(const methodHandle& method, int comp_level); // Tells whether we should print the assembly for this method - static bool should_print(const methodHandle& method); + static bool should_print(const methodHandle& method, int comp_level); // Tells whether we should log the compilation data for this method - static bool should_log(const methodHandle& method); + static bool should_log(const methodHandle& method, int comp_level); // Tells whether to break when compiling method - static bool should_break_at(const methodHandle& method); + static bool should_break_at(const methodHandle& method, int comp_level); // Tells whether there are any methods to print for print_method_statistics() static bool should_print_methods(); @@ -170,15 +170,15 @@ class CompilerOracle : AllStatic { static bool should_print_final_memstat_report(); // Tags the method as blackhole candidate, if possible. - static void tag_blackhole_if_possible(const methodHandle& method); + static void tag_blackhole_if_possible(const methodHandle& method, int comp_level); // A wrapper for checking bool options - static bool has_option(const methodHandle& method, CompileCommandEnum option); + static bool has_option(const methodHandle& method, CompileCommandEnum option, int comp_level); // Check if method has option and value set. If yes, overwrite value and return true, // otherwise leave value unchanged and return false. template - static bool has_option_value(const methodHandle& method, CompileCommandEnum option, T& value); + static bool has_option_value(const methodHandle& method, CompileCommandEnum option, int comp_level, T& value); // This check is currently only needed by whitebox API template diff --git a/src/hotspot/share/compiler/directivesParser.cpp b/src/hotspot/share/compiler/directivesParser.cpp index 5501490028349..c2cbaa5ade03b 100644 --- a/src/hotspot/share/compiler/directivesParser.cpp +++ b/src/hotspot/share/compiler/directivesParser.cpp @@ -156,7 +156,7 @@ const DirectivesParser::key DirectivesParser::keys[] = { { "inline", type_inline, 1, mask(type_directives) | mask(type_c1) | mask(type_c2), nullptr, UnknownFlagType }, // Global flags - #define common_flag_key(name, type, dvalue, compiler) \ + #define common_flag_key(name, type, dvalue, compiler, clevel) \ { #name, type_flag, 0, mask(type_directives) | mask(type_c1) | mask(type_c2), &DirectiveSet::set_##name, type##Flag}, compilerdirectives_common_flags(common_flag_key) compilerdirectives_c2_flags(common_flag_key) diff --git a/src/hotspot/share/compiler/methodMatcher.cpp b/src/hotspot/share/compiler/methodMatcher.cpp index 1a0ade2fadbd3..76753b6e03819 100644 --- a/src/hotspot/share/compiler/methodMatcher.cpp +++ b/src/hotspot/share/compiler/methodMatcher.cpp @@ -76,7 +76,8 @@ MethodMatcher::MethodMatcher(): , _method_name(nullptr) , _signature(nullptr) , _class_mode(Exact) - , _method_mode(Exact) { + , _method_mode(Exact) + , _comp_level(-1) { } MethodMatcher::~MethodMatcher() { @@ -93,12 +94,13 @@ MethodMatcher::~MethodMatcher() { void MethodMatcher::init(Symbol* class_name, Mode class_mode, Symbol* method_name, Mode method_mode, - Symbol* signature) { + Symbol* signature, int comp_level) { _class_mode = class_mode; _method_mode = method_mode; _class_name = class_name; _method_name = method_name; _signature = signature; + _comp_level = comp_level; } bool MethodMatcher::canonicalize(char * line, const char *& error_msg) { @@ -217,6 +219,21 @@ bool MethodMatcher::match(Symbol* candidate, Symbol* match, Mode match_mode) con } } +bool MethodMatcher::match(int comp_level_param) const { + // If Match is valid for all levels, then return true + if (_comp_level == CompLevel::CompLevel_all) { + return true; + } + + // If we are checking if Match is allowed at any level and + // Match is configured for some level, then return true + if (comp_level_param == CompLevel::CompLevel_any && _comp_level != 0) { + return true; + } + + return comp_level_param == _comp_level; +} + static MethodMatcher::Mode check_mode(char name[], const char*& error_msg) { int match = MethodMatcher::Exact; if (name[0] == '*') { @@ -339,19 +356,20 @@ void MethodMatcher::parse_method_pattern(char*& line, const char*& error_msg, Me Symbol* c_name = SymbolTable::new_symbol(class_name); Symbol* m_name = SymbolTable::new_symbol(method_name); - matcher->init(c_name, c_match, m_name, m_match, signature); + matcher->init(c_name, c_match, m_name, m_match, signature, CompLevel::CompLevel_any); return; } else { error_msg = "Could not parse method pattern"; } } -bool MethodMatcher::matches(const methodHandle& method) const { +bool MethodMatcher::matches(const methodHandle& method, int comp_level) const { Symbol* class_name = method->method_holder()->name(); Symbol* method_name = method->name(); Symbol* signature = method->signature(); - if (match(class_name, this->class_name(), _class_mode) && + if (match(comp_level) && + match(class_name, this->class_name(), _class_mode) && match(method_name, this->method_name(), _method_mode) && ((this->signature() == nullptr) || match(signature, this->signature(), Prefix))) { return true; @@ -403,9 +421,9 @@ BasicMatcher* BasicMatcher::parse_method_pattern(char* line, const char*& error_ return bm; } -bool BasicMatcher::match(const methodHandle& method) { +bool BasicMatcher::match(const methodHandle& method, int comp_level) { for (BasicMatcher* current = this; current != nullptr; current = current->next()) { - if (current->matches(method)) { + if (current->matches(method, comp_level)) { return true; } } @@ -432,9 +450,9 @@ InlineMatcher* InlineMatcher::parse_method_pattern(char* line, const char*& erro return im; } -bool InlineMatcher::match(const methodHandle& method, int inline_action) { +bool InlineMatcher::match(const methodHandle& method, int comp_level, int inline_action) { for (InlineMatcher* current = this; current != nullptr; current = current->next()) { - if (current->matches(method)) { + if (current->matches(method, comp_level)) { return (current->_inline_action == inline_action); } } diff --git a/src/hotspot/share/compiler/methodMatcher.hpp b/src/hotspot/share/compiler/methodMatcher.hpp index bb34c81db7bfe..779fa8a5db0e7 100644 --- a/src/hotspot/share/compiler/methodMatcher.hpp +++ b/src/hotspot/share/compiler/methodMatcher.hpp @@ -46,6 +46,7 @@ class MethodMatcher : public CHeapObj { Symbol* _signature; Mode _class_mode; Mode _method_mode; + int _comp_level; /* Each bit i (0 <= i <= 4) represents a CompLevel. */ public: Symbol* class_name() const { return _class_name; } @@ -57,15 +58,16 @@ class MethodMatcher : public CHeapObj { MethodMatcher(); ~MethodMatcher(); - void init(Symbol* class_name, Mode class_mode, Symbol* method_name, Mode method_mode, Symbol* signature); + void init(Symbol* class_name, Mode class_mode, Symbol* method_name, Mode method_mode, Symbol* signature, int comp_level); static void parse_method_pattern(char*& line, const char*& error_msg, MethodMatcher* m); static void print_symbol(outputStream* st, Symbol* h, Mode mode); - bool matches(const methodHandle& method) const; + bool matches(const methodHandle& method, int comp_level) const; void print_base(outputStream* st); private: static bool canonicalize(char * line, const char *& error_msg); bool match(Symbol* candidate, Symbol* match, Mode match_mode) const; + bool match(int comp_level) const; }; class BasicMatcher : public MethodMatcher { @@ -82,7 +84,7 @@ class BasicMatcher : public MethodMatcher { } static BasicMatcher* parse_method_pattern(char* line, const char*& error_msg, bool expect_trailing_chars); - bool match(const methodHandle& method); + bool match(const methodHandle& method, int comp_level); void set_next(BasicMatcher* next) { _next = next; } BasicMatcher* next() { return _next; } @@ -113,7 +115,7 @@ class InlineMatcher : public MethodMatcher { public: static InlineMatcher* parse_method_pattern(char* line, const char*& error_msg); - bool match(const methodHandle& method, int inline_action); + bool match(const methodHandle& method, int comp_level, int inline_action); void print(outputStream* st); void set_next(InlineMatcher* next) { _next = next; } InlineMatcher* next() { return _next; } diff --git a/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp b/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp index 52a060427d5d4..06c8c0645bc52 100644 --- a/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp +++ b/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp @@ -808,7 +808,7 @@ JVMCI::CodeInstallResult CodeInstaller::install(JVMCICompiler* compiler, cb = nm; if (compile_state == nullptr) { // This compile didn't come through the CompileBroker so perform the printing here - DirectiveSet* directive = DirectivesStack::getMatchingDirective(method, compiler); + DirectiveSet* directive = DirectivesStack::getMatchingDirective(method, CompLevel::CompLevel_full_optimization); nm->maybe_print_nmethod(directive); DirectivesStack::release(directive); } diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp index fb06abe9174ef..d28525aa4744f 100644 --- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp +++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp @@ -568,12 +568,12 @@ C2V_END C2V_VMENTRY_0(jboolean, hasNeverInlineDirective,(JNIEnv* env, jobject, ARGUMENT_PAIR(method))) methodHandle method (THREAD, UNPACK_PAIR(Method, method)); - return !Inline || CompilerOracle::should_not_inline(method) || method->dont_inline(); + return !Inline || CompilerOracle::should_not_inline(method, CompLevel::CompLevel_full_optimization) || method->dont_inline(); C2V_END C2V_VMENTRY_0(jboolean, shouldInlineMethod,(JNIEnv* env, jobject, ARGUMENT_PAIR(method))) methodHandle method (THREAD, UNPACK_PAIR(Method, method)); - return CompilerOracle::should_inline(method) || method->force_inline(); + return CompilerOracle::should_inline(method, CompLevel::CompLevel_full_optimization) || method->force_inline(); C2V_END C2V_VMENTRY_NULL(jobject, lookupType, (JNIEnv* env, jobject, jstring jname, ARGUMENT_PAIR(accessing_klass), jint accessing_klass_loader, jboolean resolve)) diff --git a/src/hotspot/share/jvmci/jvmciEnv.cpp b/src/hotspot/share/jvmci/jvmciEnv.cpp index 624b25b9e2c7b..ec895ee54bf1c 100644 --- a/src/hotspot/share/jvmci/jvmciEnv.cpp +++ b/src/hotspot/share/jvmci/jvmciEnv.cpp @@ -1288,7 +1288,7 @@ JVMCIObject JVMCIEnv::get_jvmci_method(const methodHandle& method, JVMCI_TRAPS) JVMCIKlassHandle holder_klass(THREAD, method->method_holder()); JVMCIObject holder = get_jvmci_type(holder_klass, JVMCI_CHECK_(JVMCIObject())); - CompilerOracle::tag_blackhole_if_possible(method); + CompilerOracle::tag_blackhole_if_possible(method, CompLevel::CompLevel_full_optimization); jmetadata handle = _runtime->allocate_handle(method); jboolean exception = false; diff --git a/src/hotspot/share/oops/methodCounters.cpp b/src/hotspot/share/oops/methodCounters.cpp index 00096c5012cbd..f21d870bfa21b 100644 --- a/src/hotspot/share/oops/methodCounters.cpp +++ b/src/hotspot/share/oops/methodCounters.cpp @@ -42,7 +42,7 @@ MethodCounters::MethodCounters(const methodHandle& mh) : // Set per-method thresholds. double scale = 1.0; - CompilerOracle::has_option_value(mh, CompileCommandEnum::CompileThresholdScaling, scale); + CompilerOracle::has_option_value(mh, CompileCommandEnum::CompileThresholdScaling, CompLevel::CompLevel_any, scale); _invoke_mask = right_n_bits(CompilerConfig::scaled_freq_log(Tier0InvokeNotifyFreqLog, scale)) << InvocationCounter::count_shift; _backedge_mask = right_n_bits(CompilerConfig::scaled_freq_log(Tier0BackedgeNotifyFreqLog, scale)) << InvocationCounter::count_shift; diff --git a/src/hotspot/share/oops/methodData.cpp b/src/hotspot/share/oops/methodData.cpp index 08dfc1fe95a36..06811ef703510 100644 --- a/src/hotspot/share/oops/methodData.cpp +++ b/src/hotspot/share/oops/methodData.cpp @@ -1319,7 +1319,7 @@ void MethodData::init() { // Set per-method invoke- and backedge mask. double scale = 1.0; methodHandle mh(Thread::current(), _method); - CompilerOracle::has_option_value(mh, CompileCommandEnum::CompileThresholdScaling, scale); + CompilerOracle::has_option_value(mh, CompileCommandEnum::CompileThresholdScaling, CompLevel::CompLevel_any, scale); _invoke_mask = (int)right_n_bits(CompilerConfig::scaled_freq_log(Tier0InvokeNotifyFreqLog, scale)) << InvocationCounter::count_shift; _backedge_mask = (int)right_n_bits(CompilerConfig::scaled_freq_log(Tier0BackedgeNotifyFreqLog, scale)) << InvocationCounter::count_shift; @@ -1333,21 +1333,6 @@ void MethodData::init() { _failed_speculations = nullptr; #endif -#if INCLUDE_RTM_OPT - _rtm_state = NoRTM; // No RTM lock eliding by default - if (UseRTMLocking && - !CompilerOracle::has_option(mh, CompileCommandEnum::NoRTMLockEliding)) { - if (CompilerOracle::has_option(mh, CompileCommandEnum::UseRTMLockEliding) || !UseRTMDeopt) { - // Generate RTM lock eliding code without abort ratio calculation code. - _rtm_state = UseRTM; - } else if (UseRTMDeopt) { - // Generate RTM lock eliding code and include abort ratio calculation - // code if UseRTMDeopt is on. - _rtm_state = ProfileRTM; - } - } -#endif - // Initialize escape flags. clear_escape_info(); } diff --git a/src/hotspot/share/opto/bytecodeInfo.cpp b/src/hotspot/share/opto/bytecodeInfo.cpp index 3b1e9cbd855e6..ae4061f47f44c 100644 --- a/src/hotspot/share/opto/bytecodeInfo.cpp +++ b/src/hotspot/share/opto/bytecodeInfo.cpp @@ -116,7 +116,7 @@ static bool is_unboxing_method(ciMethod* callee_method, Compile* C) { bool InlineTree::should_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, bool& should_delay, ciCallProfile& profile) { // Allows targeted inlining - if (C->directive()->should_inline(callee_method)) { + if (C->directive()->should_inline(callee_method, C->env()->comp_level())) { set_msg("force inline by CompileCommand"); _forced_inline = true; return true; @@ -231,12 +231,12 @@ bool InlineTree::should_not_inline(ciMethod* callee_method, ciMethod* caller_met } // ignore heuristic controls on inlining - if (C->directive()->should_inline(callee_method)) { + if (C->directive()->should_inline(callee_method, C->env()->comp_level())) { set_msg("force inline by CompileCommand"); return false; } - if (C->directive()->should_not_inline(callee_method)) { + if (C->directive()->should_not_inline(callee_method, C->env()->comp_level())) { set_msg("disallowed by CompileCommand"); return true; } diff --git a/src/hotspot/share/opto/compile.cpp b/src/hotspot/share/opto/compile.cpp index 25c7ced8aebfe..8fa4bc9398f32 100644 --- a/src/hotspot/share/opto/compile.cpp +++ b/src/hotspot/share/opto/compile.cpp @@ -1081,10 +1081,10 @@ void Compile::Init(bool aliasing) { #if INCLUDE_RTM_OPT if (UseRTMLocking && has_method() && (method()->method_data_or_null() != nullptr)) { int rtm_state = method()->method_data()->rtm_state(); - if (method_has_option(CompileCommandEnum::NoRTMLockEliding) || ((rtm_state & NoRTM) != 0)) { + if (method_has_option(CompileCommandEnum::NoRTMLockEliding, env()->comp_level()) || ((rtm_state & NoRTM) != 0)) { // Don't generate RTM lock eliding code. set_rtm_state(NoRTM); - } else if (method_has_option(CompileCommandEnum::UseRTMLockEliding) || ((rtm_state & UseRTM) != 0) || !UseRTMDeopt) { + } else if (method_has_option(CompileCommandEnum::UseRTMLockEliding, env()->comp_level()) || ((rtm_state & UseRTM) != 0) || !UseRTMDeopt) { // Generate RTM lock eliding code without abort ratio calculation code. set_rtm_state(UseRTM); } else if (UseRTMDeopt) { diff --git a/src/hotspot/share/opto/compile.hpp b/src/hotspot/share/opto/compile.hpp index e1d9b61f7f8d1..2ce234a59b0b6 100644 --- a/src/hotspot/share/opto/compile.hpp +++ b/src/hotspot/share/opto/compile.hpp @@ -679,8 +679,8 @@ class Compile : public Phase { void set_has_monitors(bool v) { _has_monitors = v; } // check the CompilerOracle for special behaviours for this compile - bool method_has_option(CompileCommandEnum option) { - return method() != nullptr && method()->has_option(option); + bool method_has_option(CompileCommandEnum option, int comp_level) { + return method() != nullptr && method()->has_option(option, comp_level); } #ifndef PRODUCT diff --git a/src/hotspot/share/opto/runtime.cpp b/src/hotspot/share/opto/runtime.cpp index d8e5cdbab0409..76b784eca0516 100644 --- a/src/hotspot/share/opto/runtime.cpp +++ b/src/hotspot/share/opto/runtime.cpp @@ -180,7 +180,7 @@ address OptoRuntime::generate_stub(ciEnv* env, bool return_pc) { // Matching the default directive, we currently have no method to match. - DirectiveSet* directive = DirectivesStack::getDefaultDirective(CompileBroker::compiler(CompLevel_full_optimization)); + DirectiveSet* directive = DirectivesStack::getDefaultDirective(CompLevel::CompLevel_full_optimization); ResourceMark rm; Compile C(env, gen, C_function, name, is_fancy_jump, pass_tls, return_pc, directive); DirectivesStack::release(directive); diff --git a/src/hotspot/share/prims/whitebox.cpp b/src/hotspot/share/prims/whitebox.cpp index 9a4c07568892a..cbe1ca86a6430 100644 --- a/src/hotspot/share/prims/whitebox.cpp +++ b/src/hotspot/share/prims/whitebox.cpp @@ -847,11 +847,8 @@ WB_ENTRY(jboolean, WB_IsMethodCompiled(JNIEnv* env, jobject o, jobject method, j return !code->is_marked_for_deoptimization(); WB_END -static bool is_excluded_for_compiler(AbstractCompiler* comp, methodHandle& mh) { - if (comp == nullptr) { - return true; - } - DirectiveSet* directive = DirectivesStack::getMatchingDirective(mh, comp); +static bool is_excluded_for_compiler(int comp_level, methodHandle& mh) { + DirectiveSet* directive = DirectivesStack::getMatchingDirective(mh, comp_level); bool exclude = directive->ExcludeOption; DirectivesStack::release(directive); return exclude; @@ -879,8 +876,10 @@ WB_ENTRY(jboolean, WB_IsMethodCompilable(JNIEnv* env, jobject o, jobject method, // to exclude a compilation of 'method'. if (comp_level == CompLevel_any) { // Both compilers could have ExcludeOption set. Check all combinations. - bool excluded_c1 = is_excluded_for_compiler(CompileBroker::compiler1(), mh); - bool excluded_c2 = is_excluded_for_compiler(CompileBroker::compiler2(), mh); + bool excluded_c1 = is_excluded_for_compiler(CompLevel::CompLevel_simple, mh) && + is_excluded_for_compiler(CompLevel::CompLevel_limited_profile, mh) && + is_excluded_for_compiler(CompLevel::CompLevel_full_profile, mh); + bool excluded_c2 = is_excluded_for_compiler(CompLevel::CompLevel_full_optimization, mh); if (excluded_c1 && excluded_c2) { // Compilation of 'method' excluded by both compilers. return false; @@ -893,7 +892,7 @@ WB_ENTRY(jboolean, WB_IsMethodCompilable(JNIEnv* env, jobject o, jobject method, // C2 only has ExcludeOption set: Check if compilable with C1. return can_be_compiled_at_level(mh, is_osr, CompLevel_simple); } - } else if (comp_level > CompLevel_none && is_excluded_for_compiler(CompileBroker::compiler((int)comp_level), mh)) { + } else if (comp_level > CompLevel_none && is_excluded_for_compiler(comp_level, mh)) { // Compilation of 'method' excluded by compiler used for 'comp_level'. return false; } @@ -925,10 +924,10 @@ WB_ENTRY(jboolean, WB_IsIntrinsicAvailable(JNIEnv* env, jobject o, jobject metho compilation_context_id = reflected_method_to_jmid(thread, env, compilation_context); CHECK_JNI_EXCEPTION_(env, JNI_FALSE); methodHandle cch(THREAD, Method::checked_resolve_jmethod_id(compilation_context_id)); - directive = DirectivesStack::getMatchingDirective(cch, comp); + directive = DirectivesStack::getMatchingDirective(cch, compLevel); } else { // Calling with null matches default directive - directive = DirectivesStack::getDefaultDirective(comp); + directive = DirectivesStack::getDefaultDirective(compLevel); } bool result = comp->is_intrinsic_available(mh, directive); DirectivesStack::release(directive); @@ -1085,7 +1084,7 @@ bool WhiteBox::compile_method(Method* method, int comp_level, int bci, JavaThrea // Check if compilation is blocking methodHandle mh(THREAD, method); - DirectiveSet* directive = DirectivesStack::getMatchingDirective(mh, comp); + DirectiveSet* directive = DirectivesStack::getMatchingDirective(mh, comp_level); bool is_blocking = !directive->BackgroundCompilationOption; DirectivesStack::release(directive); @@ -1134,7 +1133,7 @@ WB_ENTRY(jboolean, WB_ShouldPrintAssembly(JNIEnv* env, jobject o, jobject method CHECK_JNI_EXCEPTION_(env, JNI_FALSE); methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); - DirectiveSet* directive = DirectivesStack::getMatchingDirective(mh, CompileBroker::compiler(comp_level)); + DirectiveSet* directive = DirectivesStack::getMatchingDirective(mh, comp_level); bool result = directive->PrintAssemblyOption; DirectivesStack::release(directive); @@ -1159,10 +1158,11 @@ WB_ENTRY(jint, WB_MatchesInline(JNIEnv* env, jobject o, jobject method, jstring } // Pattern works - now check if it matches + // TODO: Maybe add a "comp_level" parameter? int result; - if (m->match(mh, InlineMatcher::force_inline)) { + if (m->match(mh, CompLevel::CompLevel_any, InlineMatcher::force_inline)) { result = 2; // Force inline match - } else if (m->match(mh, InlineMatcher::dont_inline)) { + } else if (m->match(mh, CompLevel::CompLevel_any, InlineMatcher::dont_inline)) { result = 1; // Dont inline match } else { result = 0; // No match @@ -1190,7 +1190,8 @@ WB_ENTRY(jint, WB_MatchesMethod(JNIEnv* env, jobject o, jobject method, jstring } // Pattern works - now check if it matches - int result = m->matches(mh); + // TODO: Maybe add a "comp_level" parameter + int result = m->matches(mh, CompLevel::CompLevel_any); delete m; assert(result == 0 || result == 1, "Result out of range"); return result; @@ -1993,7 +1994,8 @@ static bool GetMethodOption(JavaThread* thread, JNIEnv* env, jobject method, jst if (!CompilerOracle::option_matches_type(option, *value)) { return false; } - return CompilerOracle::has_option_value(mh, option, *value); + // TODO: Maybe add a "comp_level" parameter + return CompilerOracle::has_option_value(mh, option, CompLevel::CompLevel_any, *value); } WB_ENTRY(jobject, WB_GetMethodBooleaneOption(JNIEnv* env, jobject wb, jobject method, jstring name)) diff --git a/src/hotspot/share/runtime/java.cpp b/src/hotspot/share/runtime/java.cpp index d78e35c4e6812..be418d29c5b7d 100644 --- a/src/hotspot/share/runtime/java.cpp +++ b/src/hotspot/share/runtime/java.cpp @@ -112,9 +112,14 @@ static int compare_methods(Method** a, Method** b) { static void collect_profiled_methods(Method* m) { Thread* thread = Thread::current(); methodHandle mh(thread, m); - if ((m->method_data() != nullptr) && - (PrintMethodData || CompilerOracle::should_print(mh))) { - collected_profiled_methods->push(m); + if ((m->method_data() != nullptr)) { + bool should_print = PrintMethodData || + CompilerOracle::should_print(mh, CompLevel::CompLevel_simple) || + CompilerOracle::should_print(mh, CompLevel::CompLevel_limited_profile) || + CompilerOracle::should_print(mh, CompLevel::CompLevel_full_profile); + if (should_print) { + collected_profiled_methods->push(m); + } } } diff --git a/src/hotspot/share/runtime/sharedRuntime.cpp b/src/hotspot/share/runtime/sharedRuntime.cpp index 0a7f5c5467668..627af82c5e0b2 100644 --- a/src/hotspot/share/runtime/sharedRuntime.cpp +++ b/src/hotspot/share/runtime/sharedRuntime.cpp @@ -2781,7 +2781,7 @@ void AdapterHandlerLibrary::create_native_wrapper(const methodHandle& method) { } } - DirectiveSet* directive = DirectivesStack::getMatchingDirective(method, CompileBroker::compiler(CompLevel_simple)); + DirectiveSet* directive = DirectivesStack::getMatchingDirective(method, CompLevel::CompLevel_simple); if (directive->PrintAssemblyOption) { nm->print_code(); } From b4f6a56097003c11aabd1bba1be8c156f36e1ba4 Mon Sep 17 00:00:00 2001 From: John Tortugo Date: Tue, 30 Jul 2024 13:58:36 -0700 Subject: [PATCH 2/6] fix directives store used by jvmci. --- src/hotspot/share/compiler/compilerDirectives.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hotspot/share/compiler/compilerDirectives.cpp b/src/hotspot/share/compiler/compilerDirectives.cpp index c8acccc541382..4318ff2ca77e7 100644 --- a/src/hotspot/share/compiler/compilerDirectives.cpp +++ b/src/hotspot/share/compiler/compilerDirectives.cpp @@ -185,7 +185,8 @@ int CompilerDirectives::refcount() { DirectiveSet* CompilerDirectives::get_for(int comp_level) { assert(DirectivesStack_lock->owned_by_self(), ""); if (comp_level >= CompLevel::CompLevel_full_optimization) { - return _c2_store; + JVMCI_ONLY(return _c1_store;) + NOT_JVMCI(return _c2_store;) } else { // use c1_store as default return _c1_store; From e458499dc712169e624ea6aca1dfaee98bd796cd Mon Sep 17 00:00:00 2001 From: John Tortugo Date: Wed, 14 Aug 2024 19:12:12 -0700 Subject: [PATCH 3/6] Parsing comp_level, some tests are failing. --- src/hotspot/share/compiler/compilerOracle.cpp | 57 +++++++++++++++++-- src/hotspot/share/compiler/methodMatcher.cpp | 6 +- src/hotspot/share/compiler/methodMatcher.hpp | 4 +- 3 files changed, 59 insertions(+), 8 deletions(-) diff --git a/src/hotspot/share/compiler/compilerOracle.cpp b/src/hotspot/share/compiler/compilerOracle.cpp index 39e66cbb2197d..812e0ec8c57f8 100644 --- a/src/hotspot/share/compiler/compilerOracle.cpp +++ b/src/hotspot/share/compiler/compilerOracle.cpp @@ -923,6 +923,39 @@ class LineCopy : StackObj { } }; +static void read_comp_level(enum OptionType type, char* line, int& total_bytes_read, + TypedMethodOptionMatcher* matcher, CompileCommandEnum option, char* errorbuf, const int buf_size) { + + int bytes_read = 0; + const char* ccname = option2name(option); + const char* type_str = optiontype2name(type); + int skipped = skip_whitespace(line); + total_bytes_read += skipped; + + uintx comp_level; + bool success = false; + success = sscanf(line, "" UINTX_FORMAT "%n", &comp_level, &bytes_read) == 1; + + if (success) { + total_bytes_read += bytes_read; + line += bytes_read; + matcher->set_comp_level(comp_level); + } else { + jio_snprintf(errorbuf, buf_size, "Compilation level cannot be read for option '%s' of type '%s'", ccname, type_str); + } +} + +static void parse_comp_level_if_present(enum OptionType type, char* line, int& total_bytes_read, + TypedMethodOptionMatcher* matcher, CompileCommandEnum option, + LineCopy& original, char* errorbuf) { + int skipped = skip_whitespace(line); + total_bytes_read += skipped; + if (*line != '\0') { + skip_comma(line); + read_comp_level(type, line, total_bytes_read, matcher, option, errorbuf, sizeof(errorbuf)); + } +} + bool CompilerOracle::parse_from_line_quietly(char* line) { const bool quiet0 = _quiet; _quiet = true; @@ -965,8 +998,8 @@ bool CompilerOracle::parse_from_line(char* line) { // Two types of trailing options are // supported: // - // (1) CompileCommand=option,Klass::method,option - // (2) CompileCommand=option,Klass::method,type,option,value + // (1) CompileCommand=option,Klass::method,option[,] + // (2) CompileCommand=option,Klass::method,type,option,value[,] // // Type (1) is used to enable a boolean option for a method. // @@ -1022,8 +1055,8 @@ bool CompilerOracle::parse_from_line(char* line) { delete archetype; } else { // not an OptionCommand // Command has the following form: - // CompileCommand=