diff --git a/src/hotspot/share/c1/c1_GraphBuilder.cpp b/src/hotspot/share/c1/c1_GraphBuilder.cpp index 780ced7f433b2..97d3f28849eea 100644 --- a/src/hotspot/share/c1/c1_GraphBuilder.cpp +++ b/src/hotspot/share/c1/c1_GraphBuilder.cpp @@ -3593,7 +3593,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; } @@ -3923,7 +3923,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 7b519804bfecd..c2412f172c14b 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 b2ac3a8b2175c..b636cbafea02d 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; @@ -1065,21 +1065,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 5a4a1dd1c7fc3..e51acfe6fed0e 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 0bab731ac565e..07a19a0c10d68 100644 --- a/src/hotspot/share/code/nmethod.cpp +++ b/src/hotspot/share/code/nmethod.cpp @@ -1684,15 +1684,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 74259c8e5d436..6e932fe793b74 100644 --- a/src/hotspot/share/compiler/compilerDirectives.cpp +++ b/src/hotspot/share/compiler/compilerDirectives.cpp @@ -26,6 +26,7 @@ #include "ci/ciMethod.hpp" #include "ci/ciUtilities.inline.hpp" #include "compiler/abstractCompiler.hpp" +#include "compiler/compileBroker.hpp" #include "compiler/compilerDefinitions.inline.hpp" #include "compiler/compilerDirectives.hpp" #include "compiler/compilerOracle.hpp" @@ -142,14 +143,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,8 +183,9 @@ 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(), ""); + AbstractCompiler *comp = CompileBroker::compiler(comp_level); if (comp == nullptr) { // Xint return _c1_store; } else if (comp->is_c2()) { @@ -304,7 +306,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 +324,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 +379,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 +398,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 +409,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 +440,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 +450,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 +466,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 +486,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 +515,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 +619,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 +659,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 +749,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 +760,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 || dir->is_default_directive()) { // The directiveSet for this compile is also enabled -> success @@ -773,5 +775,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..85eee1ed5e1db 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) \ + cflags(TraceSpilling, bool, TraceSpilling, TraceSpilling, CompLevel::CompLevel_all) \ + cflags(Vectorize, bool, false, Vectorize, CompLevel::CompLevel_all) \ + cflags(CloneMapDebug, bool, false, CloneMapDebug, CompLevel::CompLevel_all) \ + cflags(IncrementalInlineForceCleanup, bool, IncrementalInlineForceCleanup, IncrementalInlineForceCleanup, CompLevel::CompLevel_all) \ + cflags(MaxNodeLimit, intx, MaxNodeLimit, MaxNodeLimit, 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)) \ +NOT_PRODUCT(cflags(IGVPrintLevel, intx, PrintIdealGraphLevel, IGVPrintLevel, 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 d0479f3fdbb50..e99f3dce122cc 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,13 +366,13 @@ 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); - if (has_inline && has_dnotinline) { + bool has_inline = CompilerOracle::has_option_value(method, CompileCommandEnum::Inline, comp_level, v1); + bool has_dontinline = CompilerOracle::has_option_value(method, CompileCommandEnum::DontInline, comp_level, v2); + if (has_inline && has_dontinline) { if (v1 && v2) { // Conflict options detected // Find the last one for that method and return the predicate accordingly @@ -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; } } @@ -398,19 +398,19 @@ static bool resolve_inlining_predicate(CompileCommandEnum option, const methodHa if (option == CompileCommandEnum::Inline) { return has_inline ? v1 : false; } else { - return has_dnotinline ? v2 : false; + return has_dontinline ? v2 : false; } } } -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"); @@ -567,8 +567,8 @@ enum OptionType CompilerOracle::parse_option_type(const char* type_str) { static void print_tip() { // CMH Update info tty->cr(); - tty->print_cr("Usage: '-XX:CompileCommand=