8227003: Add high-level JIT compilation mode control mechanism
Add tiered mode to emulate non-tiered with special mode for JVMCI compiler. Add -XX:CompilationMode option. Reviewed-by: never, redestad
This commit is contained in:
parent
f29d1d172b
commit
83dda95d7f
@ -37,6 +37,32 @@ const char* compilertype2name_tab[compiler_number_of_types] = {
|
||||
"jvmci"
|
||||
};
|
||||
|
||||
#ifdef TIERED
|
||||
bool CompilationModeFlag::_quick_only = false;
|
||||
bool CompilationModeFlag::_high_only = false;
|
||||
bool CompilationModeFlag::_high_only_quick_internal = false;
|
||||
|
||||
|
||||
bool CompilationModeFlag::initialize() {
|
||||
if (CompilationMode != NULL) {
|
||||
if (strcmp(CompilationMode, "default") == 0) {
|
||||
// Do nothing, just support the "default" keyword.
|
||||
} else if (strcmp(CompilationMode, "quick-only") == 0) {
|
||||
_quick_only = true;
|
||||
} else if (strcmp(CompilationMode, "high-only") == 0) {
|
||||
_high_only = true;
|
||||
} else if (strcmp(CompilationMode, "high-only-quick-internal") == 0) {
|
||||
_high_only_quick_internal = true;
|
||||
} else {
|
||||
jio_fprintf(defaultStream::error_stream(), "Unsupported compilation mode '%s', supported modes are: quick-only, high-only, high-only-quick-internal\n", CompilationMode);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(COMPILER2)
|
||||
CompLevel CompLevel_highest_tier = CompLevel_full_optimization; // pure C2 and tiered or JVMCI and tiered
|
||||
#elif defined(COMPILER1)
|
||||
@ -208,6 +234,12 @@ void CompilerConfig::set_tiered_flags() {
|
||||
vm_exit_during_initialization("Negative value specified for CompileThresholdScaling", NULL);
|
||||
}
|
||||
|
||||
if (CompilationModeFlag::disable_intermediate()) {
|
||||
if (FLAG_IS_DEFAULT(Tier0ProfilingStartPercentage)) {
|
||||
FLAG_SET_DEFAULT(Tier0ProfilingStartPercentage, 33);
|
||||
}
|
||||
}
|
||||
|
||||
// Scale tiered compilation thresholds.
|
||||
// CompileThresholdScaling == 0.0 is equivalent to -Xint and leaves compilation thresholds unchanged.
|
||||
if (!FLAG_IS_DEFAULT(CompileThresholdScaling) && CompileThresholdScaling > 0.0) {
|
||||
@ -234,6 +266,29 @@ void CompilerConfig::set_tiered_flags() {
|
||||
FLAG_SET_ERGO(Tier4MinInvocationThreshold, scaled_compile_threshold(Tier4MinInvocationThreshold));
|
||||
FLAG_SET_ERGO(Tier4CompileThreshold, scaled_compile_threshold(Tier4CompileThreshold));
|
||||
FLAG_SET_ERGO(Tier4BackEdgeThreshold, scaled_compile_threshold(Tier4BackEdgeThreshold));
|
||||
|
||||
if (CompilationModeFlag::disable_intermediate()) {
|
||||
FLAG_SET_ERGO(Tier40InvocationThreshold, scaled_compile_threshold(Tier40InvocationThreshold));
|
||||
FLAG_SET_ERGO(Tier40MinInvocationThreshold, scaled_compile_threshold(Tier40MinInvocationThreshold));
|
||||
FLAG_SET_ERGO(Tier40CompileThreshold, scaled_compile_threshold(Tier40CompileThreshold));
|
||||
FLAG_SET_ERGO(Tier40BackEdgeThreshold, scaled_compile_threshold(Tier40BackEdgeThreshold));
|
||||
}
|
||||
|
||||
#if INCLUDE_AOT
|
||||
if (UseAOT) {
|
||||
FLAG_SET_ERGO(Tier3AOTInvocationThreshold, scaled_compile_threshold(Tier3AOTInvocationThreshold));
|
||||
FLAG_SET_ERGO(Tier3AOTMinInvocationThreshold, scaled_compile_threshold(Tier3AOTMinInvocationThreshold));
|
||||
FLAG_SET_ERGO(Tier3AOTCompileThreshold, scaled_compile_threshold(Tier3AOTCompileThreshold));
|
||||
FLAG_SET_ERGO(Tier3AOTBackEdgeThreshold, scaled_compile_threshold(Tier3AOTBackEdgeThreshold));
|
||||
|
||||
if (CompilationModeFlag::disable_intermediate()) {
|
||||
FLAG_SET_ERGO(Tier0AOTInvocationThreshold, scaled_compile_threshold(Tier0AOTInvocationThreshold));
|
||||
FLAG_SET_ERGO(Tier0AOTMinInvocationThreshold, scaled_compile_threshold(Tier0AOTMinInvocationThreshold));
|
||||
FLAG_SET_ERGO(Tier0AOTCompileThreshold, scaled_compile_threshold(Tier0AOTCompileThreshold));
|
||||
FLAG_SET_ERGO(Tier0AOTBackEdgeThreshold, scaled_compile_threshold(Tier0AOTBackEdgeThreshold));
|
||||
}
|
||||
}
|
||||
#endif // INCLUDE_AOT
|
||||
}
|
||||
}
|
||||
|
||||
@ -245,11 +300,6 @@ void set_jvmci_specific_flags() {
|
||||
if (FLAG_IS_DEFAULT(TypeProfileWidth)) {
|
||||
FLAG_SET_DEFAULT(TypeProfileWidth, 8);
|
||||
}
|
||||
if (TieredStopAtLevel != CompLevel_full_optimization) {
|
||||
// Currently JVMCI compiler can only work at the full optimization level
|
||||
warning("forcing TieredStopAtLevel to full optimization because JVMCI is enabled");
|
||||
FLAG_SET_ERGO(TieredStopAtLevel, CompLevel_full_optimization);
|
||||
}
|
||||
if (FLAG_IS_DEFAULT(TypeProfileLevel)) {
|
||||
FLAG_SET_DEFAULT(TypeProfileLevel, 0);
|
||||
}
|
||||
@ -270,11 +320,26 @@ void set_jvmci_specific_flags() {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
#ifdef TIERED
|
||||
if (!TieredCompilation) {
|
||||
warning("Disabling tiered compilation with non-native JVMCI compiler is not recommended. "
|
||||
"Turning on tiered compilation and disabling intermediate compilation levels instead. ");
|
||||
FLAG_SET_ERGO(TieredCompilation, true);
|
||||
if (CompilationModeFlag::normal()) {
|
||||
CompilationModeFlag::set_high_only_quick_internal(true);
|
||||
}
|
||||
if (CICompilerCount < 2 && CompilationModeFlag::quick_internal()) {
|
||||
warning("Increasing number of compiler threads for JVMCI compiler.");
|
||||
FLAG_SET_ERGO(CICompilerCount, 2);
|
||||
}
|
||||
}
|
||||
#else // TIERED
|
||||
// Adjust the on stack replacement percentage to avoid early
|
||||
// OSR compilations while JVMCI itself is warming up
|
||||
if (FLAG_IS_DEFAULT(OnStackReplacePercentage)) {
|
||||
FLAG_SET_DEFAULT(OnStackReplacePercentage, 933);
|
||||
}
|
||||
#endif // !TIERED
|
||||
// JVMCI needs values not less than defaults
|
||||
if (FLAG_IS_DEFAULT(ReservedCodeCacheSize)) {
|
||||
FLAG_SET_DEFAULT(ReservedCodeCacheSize, MAX2(64*M, ReservedCodeCacheSize));
|
||||
|
@ -62,6 +62,24 @@ enum CompLevel {
|
||||
CompLevel_full_optimization = 4 // C2 or JVMCI
|
||||
};
|
||||
|
||||
class CompilationModeFlag : AllStatic {
|
||||
static bool _quick_only;
|
||||
static bool _high_only;
|
||||
static bool _high_only_quick_internal;
|
||||
|
||||
public:
|
||||
static bool initialize();
|
||||
static bool normal() { return !quick_only() && !high_only() && !high_only_quick_internal(); }
|
||||
static bool quick_only() { return _quick_only; }
|
||||
static bool high_only() { return _high_only; }
|
||||
static bool high_only_quick_internal() { return _high_only_quick_internal; }
|
||||
|
||||
static bool disable_intermediate() { return high_only() || high_only_quick_internal(); }
|
||||
static bool quick_internal() { return !high_only(); }
|
||||
|
||||
static void set_high_only_quick_internal(bool x) { _high_only_quick_internal = x; }
|
||||
};
|
||||
|
||||
extern CompLevel CompLevel_highest_tier;
|
||||
extern CompLevel CompLevel_initial_compile;
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "compiler/tieredThresholdPolicy.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "runtime/arguments.hpp"
|
||||
#include "runtime/frame.inline.hpp"
|
||||
#include "runtime/handles.inline.hpp"
|
||||
#include "runtime/safepoint.hpp"
|
||||
#include "runtime/safepointVerifiers.hpp"
|
||||
@ -42,43 +43,61 @@
|
||||
#include "c1/c1_Compiler.hpp"
|
||||
#include "opto/c2compiler.hpp"
|
||||
|
||||
template<CompLevel level>
|
||||
bool TieredThresholdPolicy::call_predicate_helper(int i, int b, double scale, Method* method) {
|
||||
bool TieredThresholdPolicy::call_predicate_helper(Method* method, CompLevel cur_level, int i, int b, double scale) {
|
||||
double threshold_scaling;
|
||||
if (CompilerOracle::has_option_value(method, "CompileThresholdScaling", threshold_scaling)) {
|
||||
scale *= threshold_scaling;
|
||||
}
|
||||
switch(level) {
|
||||
switch(cur_level) {
|
||||
case CompLevel_aot:
|
||||
return (i >= Tier3AOTInvocationThreshold * scale) ||
|
||||
(i >= Tier3AOTMinInvocationThreshold * scale && i + b >= Tier3AOTCompileThreshold * scale);
|
||||
if (CompilationModeFlag::disable_intermediate()) {
|
||||
return (i >= Tier0AOTInvocationThreshold * scale) ||
|
||||
(i >= Tier0AOTMinInvocationThreshold * scale && i + b >= Tier0AOTCompileThreshold * scale);
|
||||
} else {
|
||||
return (i >= Tier3AOTInvocationThreshold * scale) ||
|
||||
(i >= Tier3AOTMinInvocationThreshold * scale && i + b >= Tier3AOTCompileThreshold * scale);
|
||||
}
|
||||
case CompLevel_none:
|
||||
if (CompilationModeFlag::disable_intermediate()) {
|
||||
return (i >= Tier40InvocationThreshold * scale) ||
|
||||
(i >= Tier40MinInvocationThreshold * scale && i + b >= Tier40CompileThreshold * scale);
|
||||
}
|
||||
// Fall through
|
||||
case CompLevel_limited_profile:
|
||||
return (i >= Tier3InvocationThreshold * scale) ||
|
||||
(i >= Tier3MinInvocationThreshold * scale && i + b >= Tier3CompileThreshold * scale);
|
||||
case CompLevel_full_profile:
|
||||
return (i >= Tier4InvocationThreshold * scale) ||
|
||||
(i >= Tier4MinInvocationThreshold * scale && i + b >= Tier4CompileThreshold * scale);
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<CompLevel level>
|
||||
bool TieredThresholdPolicy::loop_predicate_helper(int i, int b, double scale, Method* method) {
|
||||
bool TieredThresholdPolicy::loop_predicate_helper(Method* method, CompLevel cur_level, int i, int b, double scale) {
|
||||
double threshold_scaling;
|
||||
if (CompilerOracle::has_option_value(method, "CompileThresholdScaling", threshold_scaling)) {
|
||||
scale *= threshold_scaling;
|
||||
}
|
||||
switch(level) {
|
||||
switch(cur_level) {
|
||||
case CompLevel_aot:
|
||||
return b >= Tier3AOTBackEdgeThreshold * scale;
|
||||
if (CompilationModeFlag::disable_intermediate()) {
|
||||
return b >= Tier0AOTBackEdgeThreshold * scale;
|
||||
} else {
|
||||
return b >= Tier3AOTBackEdgeThreshold * scale;
|
||||
}
|
||||
case CompLevel_none:
|
||||
if (CompilationModeFlag::disable_intermediate()) {
|
||||
return b >= Tier40BackEdgeThreshold * scale;
|
||||
}
|
||||
// Fall through
|
||||
case CompLevel_limited_profile:
|
||||
return b >= Tier3BackEdgeThreshold * scale;
|
||||
case CompLevel_full_profile:
|
||||
return b >= Tier4BackEdgeThreshold * scale;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Simple methods are as good being compiled with C1 as C2.
|
||||
@ -91,18 +110,17 @@ bool TieredThresholdPolicy::is_trivial(Method* method) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TieredThresholdPolicy::should_compile_at_level_simple(Method* method) {
|
||||
if (TieredThresholdPolicy::is_trivial(method)) {
|
||||
return true;
|
||||
}
|
||||
bool TieredThresholdPolicy::force_comp_at_level_simple(Method* method) {
|
||||
if (CompilationModeFlag::quick_internal()) {
|
||||
#if INCLUDE_JVMCI
|
||||
if (UseJVMCICompiler) {
|
||||
AbstractCompiler* comp = CompileBroker::compiler(CompLevel_full_optimization);
|
||||
if (comp != NULL && comp->is_jvmci() && ((JVMCICompiler*) comp)->force_comp_at_level_simple(method)) {
|
||||
return true;
|
||||
if (UseJVMCICompiler) {
|
||||
AbstractCompiler* comp = CompileBroker::compiler(CompLevel_full_optimization);
|
||||
if (comp != NULL && comp->is_jvmci() && ((JVMCICompiler*) comp)->force_comp_at_level_simple(method)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -181,7 +199,12 @@ void TieredThresholdPolicy::print_event(EventType type, const methodHandle& mh,
|
||||
tty->print("@%d queues=%d,%d", bci, CompileBroker::queue_size(CompLevel_full_profile),
|
||||
CompileBroker::queue_size(CompLevel_full_optimization));
|
||||
|
||||
print_specific(type, mh, imh, bci, level);
|
||||
tty->print(" rate=");
|
||||
if (mh->prev_time() == 0) tty->print("n/a");
|
||||
else tty->print("%f", mh->rate());
|
||||
|
||||
tty->print(" k=%.2lf,%.2lf", threshold_scale(CompLevel_full_profile, Tier3LoadFeedback),
|
||||
threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback));
|
||||
|
||||
if (type != COMPILE) {
|
||||
print_counters("", mh);
|
||||
@ -216,9 +239,11 @@ void TieredThresholdPolicy::print_event(EventType type, const methodHandle& mh,
|
||||
tty->print_cr("]");
|
||||
}
|
||||
|
||||
|
||||
void TieredThresholdPolicy::initialize() {
|
||||
int count = CICompilerCount;
|
||||
bool c1_only = TieredStopAtLevel < CompLevel_full_optimization;
|
||||
bool c1_only = TieredStopAtLevel < CompLevel_full_optimization || CompilationModeFlag::quick_only();
|
||||
bool c2_only = CompilationModeFlag::high_only();
|
||||
#ifdef _LP64
|
||||
// Turn on ergonomic compiler count selection
|
||||
if (FLAG_IS_DEFAULT(CICompilerCountPerCPU) && FLAG_IS_DEFAULT(CICompilerCount)) {
|
||||
@ -257,6 +282,8 @@ void TieredThresholdPolicy::initialize() {
|
||||
if (c1_only) {
|
||||
// No C2 compiler thread required
|
||||
set_c1_count(count);
|
||||
} else if (c2_only) {
|
||||
set_c2_count(count);
|
||||
} else {
|
||||
set_c1_count(MAX2(count / 3, 1));
|
||||
set_c2_count(MAX2(count - c1_count(), 1));
|
||||
@ -413,7 +440,7 @@ nmethod* TieredThresholdPolicy::event(const methodHandle& method, const methodHa
|
||||
method_back_branch_event(method, inlinee, bci, comp_level, nm, thread);
|
||||
// Check if event led to a higher level OSR compilation
|
||||
CompLevel expected_comp_level = comp_level;
|
||||
if (inlinee->is_not_osr_compilable(expected_comp_level)) {
|
||||
if (!CompilationModeFlag::disable_intermediate() && inlinee->is_not_osr_compilable(expected_comp_level)) {
|
||||
// It's not possble to reach the expected level so fall back to simple.
|
||||
expected_comp_level = CompLevel_simple;
|
||||
}
|
||||
@ -430,7 +457,25 @@ nmethod* TieredThresholdPolicy::event(const methodHandle& method, const methodHa
|
||||
// Check if the method can be compiled, change level if necessary
|
||||
void TieredThresholdPolicy::compile(const methodHandle& mh, int bci, CompLevel level, JavaThread* thread) {
|
||||
assert(level <= TieredStopAtLevel, "Invalid compilation level");
|
||||
if (CompilationModeFlag::quick_only()) {
|
||||
assert(level <= CompLevel_simple, "Invalid compilation level");
|
||||
} else if (CompilationModeFlag::disable_intermediate()) {
|
||||
assert(level != CompLevel_full_profile && level != CompLevel_limited_profile, "C1 profiling levels shouldn't be used with intermediate levels disabled");
|
||||
}
|
||||
|
||||
if (level == CompLevel_none) {
|
||||
if (mh->has_compiled_code()) {
|
||||
// Happens when we switch from AOT to interpreter to profile.
|
||||
MutexLocker ml(Compile_lock);
|
||||
NoSafepointVerifier nsv;
|
||||
if (mh->has_compiled_code()) {
|
||||
mh->code()->make_not_used();
|
||||
}
|
||||
// Deoptimize immediately (we don't have to wait for a compile).
|
||||
RegisterMap map(thread, false);
|
||||
frame fr = thread->last_frame().sender(&map);
|
||||
Deoptimization::deoptimize_frame(thread, fr.id());
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (level == CompLevel_aot) {
|
||||
@ -452,26 +497,28 @@ void TieredThresholdPolicy::compile(const methodHandle& mh, int bci, CompLevel l
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the method can be compiled. If it cannot be compiled with C1, continue profiling
|
||||
// in the interpreter and then compile with C2 (the transition function will request that,
|
||||
// see common() ). If the method cannot be compiled with C2 but still can with C1, compile it with
|
||||
// pure C1.
|
||||
if ((bci == InvocationEntryBci && !can_be_compiled(mh, level))) {
|
||||
if (level == CompLevel_full_optimization && can_be_compiled(mh, CompLevel_simple)) {
|
||||
compile(mh, bci, CompLevel_simple, thread);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if ((bci != InvocationEntryBci && !can_be_osr_compiled(mh, level))) {
|
||||
if (level == CompLevel_full_optimization && can_be_osr_compiled(mh, CompLevel_simple)) {
|
||||
nmethod* osr_nm = mh->lookup_osr_nmethod_for(bci, CompLevel_simple, false);
|
||||
if (osr_nm != NULL && osr_nm->comp_level() > CompLevel_simple) {
|
||||
// Invalidate the existing OSR nmethod so that a compile at CompLevel_simple is permitted.
|
||||
osr_nm->make_not_entrant();
|
||||
if (!CompilationModeFlag::disable_intermediate()) {
|
||||
// Check if the method can be compiled. If it cannot be compiled with C1, continue profiling
|
||||
// in the interpreter and then compile with C2 (the transition function will request that,
|
||||
// see common() ). If the method cannot be compiled with C2 but still can with C1, compile it with
|
||||
// pure C1.
|
||||
if ((bci == InvocationEntryBci && !can_be_compiled(mh, level))) {
|
||||
if (level == CompLevel_full_optimization && can_be_compiled(mh, CompLevel_simple)) {
|
||||
compile(mh, bci, CompLevel_simple, thread);
|
||||
}
|
||||
compile(mh, bci, CompLevel_simple, thread);
|
||||
return;
|
||||
}
|
||||
if ((bci != InvocationEntryBci && !can_be_osr_compiled(mh, level))) {
|
||||
if (level == CompLevel_full_optimization && can_be_osr_compiled(mh, CompLevel_simple)) {
|
||||
nmethod* osr_nm = mh->lookup_osr_nmethod_for(bci, CompLevel_simple, false);
|
||||
if (osr_nm != NULL && osr_nm->comp_level() > CompLevel_simple) {
|
||||
// Invalidate the existing OSR nmethod so that a compile at CompLevel_simple is permitted.
|
||||
osr_nm->make_not_entrant();
|
||||
}
|
||||
compile(mh, bci, CompLevel_simple, thread);
|
||||
}
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (bci != InvocationEntryBci && mh->is_not_osr_compilable(level)) {
|
||||
return;
|
||||
@ -480,29 +527,12 @@ void TieredThresholdPolicy::compile(const methodHandle& mh, int bci, CompLevel l
|
||||
if (PrintTieredEvents) {
|
||||
print_event(COMPILE, mh, mh, bci, level);
|
||||
}
|
||||
submit_compile(mh, bci, level, thread);
|
||||
int hot_count = (bci == InvocationEntryBci) ? mh->invocation_count() : mh->backedge_count();
|
||||
update_rate(os::javaTimeMillis(), mh());
|
||||
CompileBroker::compile_method(mh, bci, level, mh, hot_count, CompileTask::Reason_Tiered, thread);
|
||||
}
|
||||
}
|
||||
|
||||
// Update the rate and submit compile
|
||||
void TieredThresholdPolicy::submit_compile(const methodHandle& mh, int bci, CompLevel level, JavaThread* thread) {
|
||||
int hot_count = (bci == InvocationEntryBci) ? mh->invocation_count() : mh->backedge_count();
|
||||
update_rate(os::javaTimeMillis(), mh());
|
||||
CompileBroker::compile_method(mh, bci, level, mh, hot_count, CompileTask::Reason_Tiered, thread);
|
||||
}
|
||||
|
||||
// Print an event.
|
||||
void TieredThresholdPolicy::print_specific(EventType type, const methodHandle& mh, const methodHandle& imh,
|
||||
int bci, CompLevel level) {
|
||||
tty->print(" rate=");
|
||||
if (mh->prev_time() == 0) tty->print("n/a");
|
||||
else tty->print("%f", mh->rate());
|
||||
|
||||
tty->print(" k=%.2lf,%.2lf", threshold_scale(CompLevel_full_profile, Tier3LoadFeedback),
|
||||
threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback));
|
||||
|
||||
}
|
||||
|
||||
// update_rate() is called from select_task() while holding a compile queue lock.
|
||||
void TieredThresholdPolicy::update_rate(jlong t, Method* m) {
|
||||
// Skip update if counters are absent.
|
||||
@ -585,27 +615,30 @@ bool TieredThresholdPolicy::is_method_profiled(Method* method) {
|
||||
if (mdo != NULL) {
|
||||
int i = mdo->invocation_count_delta();
|
||||
int b = mdo->backedge_count_delta();
|
||||
return call_predicate_helper<CompLevel_full_profile>(i, b, 1, method);
|
||||
return call_predicate_helper(method, CompilationModeFlag::disable_intermediate() ? CompLevel_none : CompLevel_full_profile, i, b, 1);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
double TieredThresholdPolicy::threshold_scale(CompLevel level, int feedback_k) {
|
||||
double queue_size = CompileBroker::queue_size(level);
|
||||
int comp_count = compiler_count(level);
|
||||
double k = queue_size / (feedback_k * comp_count) + 1;
|
||||
if (comp_count > 0) {
|
||||
double queue_size = CompileBroker::queue_size(level);
|
||||
double k = queue_size / (feedback_k * comp_count) + 1;
|
||||
|
||||
// Increase C1 compile threshold when the code cache is filled more
|
||||
// than specified by IncreaseFirstTierCompileThresholdAt percentage.
|
||||
// The main intention is to keep enough free space for C2 compiled code
|
||||
// to achieve peak performance if the code cache is under stress.
|
||||
if ((TieredStopAtLevel == CompLevel_full_optimization) && (level != CompLevel_full_optimization)) {
|
||||
double current_reverse_free_ratio = CodeCache::reverse_free_ratio(CodeCache::get_code_blob_type(level));
|
||||
if (current_reverse_free_ratio > _increase_threshold_at_ratio) {
|
||||
k *= exp(current_reverse_free_ratio - _increase_threshold_at_ratio);
|
||||
// Increase C1 compile threshold when the code cache is filled more
|
||||
// than specified by IncreaseFirstTierCompileThresholdAt percentage.
|
||||
// The main intention is to keep enough free space for C2 compiled code
|
||||
// to achieve peak performance if the code cache is under stress.
|
||||
if (!CompilationModeFlag::disable_intermediate() && TieredStopAtLevel == CompLevel_full_optimization && level != CompLevel_full_optimization) {
|
||||
double current_reverse_free_ratio = CodeCache::reverse_free_ratio(CodeCache::get_code_blob_type(level));
|
||||
if (current_reverse_free_ratio > _increase_threshold_at_ratio) {
|
||||
k *= exp(current_reverse_free_ratio - _increase_threshold_at_ratio);
|
||||
}
|
||||
}
|
||||
return k;
|
||||
}
|
||||
return k;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Call and loop predicates determine whether a transition to a higher
|
||||
@ -615,55 +648,71 @@ double TieredThresholdPolicy::threshold_scale(CompLevel level, int feedback_k) {
|
||||
// how many methods per compiler thread can be in the queue before
|
||||
// the threshold values double.
|
||||
bool TieredThresholdPolicy::loop_predicate(int i, int b, CompLevel cur_level, Method* method) {
|
||||
double k = 1;
|
||||
switch(cur_level) {
|
||||
case CompLevel_aot: {
|
||||
double k = threshold_scale(CompLevel_full_profile, Tier3LoadFeedback);
|
||||
return loop_predicate_helper<CompLevel_aot>(i, b, k, method);
|
||||
k = CompilationModeFlag::disable_intermediate() ? 1 : threshold_scale(CompLevel_full_profile, Tier3LoadFeedback);
|
||||
break;
|
||||
}
|
||||
case CompLevel_none:
|
||||
case CompLevel_none: {
|
||||
if (CompilationModeFlag::disable_intermediate()) {
|
||||
k = threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Fall through
|
||||
case CompLevel_limited_profile: {
|
||||
double k = threshold_scale(CompLevel_full_profile, Tier3LoadFeedback);
|
||||
return loop_predicate_helper<CompLevel_none>(i, b, k, method);
|
||||
k = threshold_scale(CompLevel_full_profile, Tier3LoadFeedback);
|
||||
break;
|
||||
}
|
||||
case CompLevel_full_profile: {
|
||||
double k = threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback);
|
||||
return loop_predicate_helper<CompLevel_full_profile>(i, b, k, method);
|
||||
k = threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
return loop_predicate_helper(method, cur_level, i, b, k);
|
||||
}
|
||||
|
||||
bool TieredThresholdPolicy::call_predicate(int i, int b, CompLevel cur_level, Method* method) {
|
||||
double k = 1;
|
||||
switch(cur_level) {
|
||||
case CompLevel_aot: {
|
||||
double k = threshold_scale(CompLevel_full_profile, Tier3LoadFeedback);
|
||||
return call_predicate_helper<CompLevel_aot>(i, b, k, method);
|
||||
k = CompilationModeFlag::disable_intermediate() ? 1 : threshold_scale(CompLevel_full_profile, Tier3LoadFeedback);
|
||||
break;
|
||||
}
|
||||
case CompLevel_none:
|
||||
case CompLevel_none: {
|
||||
if (CompilationModeFlag::disable_intermediate()) {
|
||||
k = threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Fall through
|
||||
case CompLevel_limited_profile: {
|
||||
double k = threshold_scale(CompLevel_full_profile, Tier3LoadFeedback);
|
||||
return call_predicate_helper<CompLevel_none>(i, b, k, method);
|
||||
k = threshold_scale(CompLevel_full_profile, Tier3LoadFeedback);
|
||||
break;
|
||||
}
|
||||
case CompLevel_full_profile: {
|
||||
double k = threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback);
|
||||
return call_predicate_helper<CompLevel_full_profile>(i, b, k, method);
|
||||
k = threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
return call_predicate_helper(method, cur_level, i, b, k);
|
||||
}
|
||||
|
||||
// Determine is a method is mature.
|
||||
bool TieredThresholdPolicy::is_mature(Method* method) {
|
||||
if (should_compile_at_level_simple(method)) return true;
|
||||
if (is_trivial(method) || force_comp_at_level_simple(method)) return true;
|
||||
MethodData* mdo = method->method_data();
|
||||
if (mdo != NULL) {
|
||||
int i = mdo->invocation_count();
|
||||
int b = mdo->backedge_count();
|
||||
double k = ProfileMaturityPercentage / 100.0;
|
||||
return call_predicate_helper<CompLevel_full_profile>(i, b, k, method) ||
|
||||
loop_predicate_helper<CompLevel_full_profile>(i, b, k, method);
|
||||
CompLevel main_profile_level = CompilationModeFlag::disable_intermediate() ? CompLevel_none : CompLevel_full_profile;
|
||||
return call_predicate_helper(method, main_profile_level, i, b, k) || loop_predicate_helper(method, main_profile_level, i, b, k);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -672,13 +721,16 @@ bool TieredThresholdPolicy::is_mature(Method* method) {
|
||||
// start profiling without waiting for the compiled method to arrive.
|
||||
// We also take the load on compilers into the account.
|
||||
bool TieredThresholdPolicy::should_create_mdo(Method* method, CompLevel cur_level) {
|
||||
if (cur_level == CompLevel_none &&
|
||||
CompileBroker::queue_size(CompLevel_full_optimization) <=
|
||||
Tier3DelayOn * compiler_count(CompLevel_full_optimization)) {
|
||||
int i = method->invocation_count();
|
||||
int b = method->backedge_count();
|
||||
double k = Tier0ProfilingStartPercentage / 100.0;
|
||||
return call_predicate_helper<CompLevel_none>(i, b, k, method) || loop_predicate_helper<CompLevel_none>(i, b, k, method);
|
||||
if (cur_level != CompLevel_none || force_comp_at_level_simple(method)) {
|
||||
return false;
|
||||
}
|
||||
int i = method->invocation_count();
|
||||
int b = method->backedge_count();
|
||||
double k = Tier0ProfilingStartPercentage / 100.0;
|
||||
|
||||
// If the top level compiler is not keeping up, delay profiling.
|
||||
if (CompileBroker::queue_size(CompLevel_full_optimization) <= (CompilationModeFlag::disable_intermediate() ? Tier0Delay : Tier3DelayOn) * compiler_count(CompLevel_full_optimization)) {
|
||||
return call_predicate_helper(method, CompLevel_none, i, b, k) || loop_predicate_helper(method, CompLevel_none, i, b, k);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -714,7 +766,7 @@ void TieredThresholdPolicy::create_mdo(const methodHandle& mh, JavaThread* THREA
|
||||
* 1 - pure C1 (CompLevel_simple)
|
||||
* 2 - C1 with invocation and backedge counting (CompLevel_limited_profile)
|
||||
* 3 - C1 with full profiling (CompLevel_full_profile)
|
||||
* 4 - C2 (CompLevel_full_optimization)
|
||||
* 4 - C2 or Graal (CompLevel_full_optimization)
|
||||
*
|
||||
* Common state transition patterns:
|
||||
* a. 0 -> 3 -> 4.
|
||||
@ -752,106 +804,129 @@ CompLevel TieredThresholdPolicy::common(Predicate p, Method* method, CompLevel c
|
||||
int i = method->invocation_count();
|
||||
int b = method->backedge_count();
|
||||
|
||||
if (should_compile_at_level_simple(method)) {
|
||||
if (force_comp_at_level_simple(method)) {
|
||||
next_level = CompLevel_simple;
|
||||
} else {
|
||||
switch(cur_level) {
|
||||
if (!CompilationModeFlag::disable_intermediate() && is_trivial(method)) {
|
||||
next_level = CompLevel_simple;
|
||||
} else {
|
||||
switch(cur_level) {
|
||||
default: break;
|
||||
case CompLevel_aot: {
|
||||
// If we were at full profile level, would we switch to full opt?
|
||||
if (common(p, method, CompLevel_full_profile, disable_feedback) == CompLevel_full_optimization) {
|
||||
next_level = CompLevel_full_optimization;
|
||||
} else if (disable_feedback || (CompileBroker::queue_size(CompLevel_full_optimization) <=
|
||||
Tier3DelayOff * compiler_count(CompLevel_full_optimization) &&
|
||||
(this->*p)(i, b, cur_level, method))) {
|
||||
next_level = CompLevel_full_profile;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CompLevel_none:
|
||||
// If we were at full profile level, would we switch to full opt?
|
||||
if (common(p, method, CompLevel_full_profile, disable_feedback) == CompLevel_full_optimization) {
|
||||
next_level = CompLevel_full_optimization;
|
||||
} else if ((this->*p)(i, b, cur_level, method)) {
|
||||
#if INCLUDE_JVMCI
|
||||
if (EnableJVMCI && UseJVMCICompiler) {
|
||||
// Since JVMCI takes a while to warm up, its queue inevitably backs up during
|
||||
// early VM execution. As of 2014-06-13, JVMCI's inliner assumes that the root
|
||||
// compilation method and all potential inlinees have mature profiles (which
|
||||
// includes type profiling). If it sees immature profiles, JVMCI's inliner
|
||||
// can perform pathologically bad (e.g., causing OutOfMemoryErrors due to
|
||||
// exploring/inlining too many graphs). Since a rewrite of the inliner is
|
||||
// in progress, we simply disable the dialing back heuristic for now and will
|
||||
// revisit this decision once the new inliner is completed.
|
||||
next_level = CompLevel_full_profile;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
// C1-generated fully profiled code is about 30% slower than the limited profile
|
||||
// code that has only invocation and backedge counters. The observation is that
|
||||
// if C2 queue is large enough we can spend too much time in the fully profiled code
|
||||
// while waiting for C2 to pick the method from the queue. To alleviate this problem
|
||||
// we introduce a feedback on the C2 queue size. If the C2 queue is sufficiently long
|
||||
// we choose to compile a limited profiled version and then recompile with full profiling
|
||||
// when the load on C2 goes down.
|
||||
if (!disable_feedback && CompileBroker::queue_size(CompLevel_full_optimization) >
|
||||
Tier3DelayOn * compiler_count(CompLevel_full_optimization)) {
|
||||
next_level = CompLevel_limited_profile;
|
||||
} else {
|
||||
next_level = CompLevel_full_profile;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CompLevel_limited_profile:
|
||||
if (is_method_profiled(method)) {
|
||||
// Special case: we got here because this method was fully profiled in the interpreter.
|
||||
next_level = CompLevel_full_optimization;
|
||||
} else {
|
||||
MethodData* mdo = method->method_data();
|
||||
if (mdo != NULL) {
|
||||
if (mdo->would_profile()) {
|
||||
if (disable_feedback || (CompileBroker::queue_size(CompLevel_full_optimization) <=
|
||||
Tier3DelayOff * compiler_count(CompLevel_full_optimization) &&
|
||||
(this->*p)(i, b, cur_level, method))) {
|
||||
next_level = CompLevel_full_profile;
|
||||
}
|
||||
} else {
|
||||
next_level = CompLevel_full_optimization;
|
||||
case CompLevel_aot:
|
||||
if (CompilationModeFlag::disable_intermediate()) {
|
||||
if (disable_feedback || (CompileBroker::queue_size(CompLevel_full_optimization) <=
|
||||
Tier0Delay * compiler_count(CompLevel_full_optimization) &&
|
||||
(this->*p)(i, b, cur_level, method))) {
|
||||
next_level = CompLevel_none;
|
||||
}
|
||||
} else {
|
||||
// If there is no MDO we need to profile
|
||||
if (disable_feedback || (CompileBroker::queue_size(CompLevel_full_optimization) <=
|
||||
Tier3DelayOff * compiler_count(CompLevel_full_optimization) &&
|
||||
(this->*p)(i, b, cur_level, method))) {
|
||||
// If we were at full profile level, would we switch to full opt?
|
||||
if (common(p, method, CompLevel_full_profile, disable_feedback) == CompLevel_full_optimization) {
|
||||
next_level = CompLevel_full_optimization;
|
||||
} else if (disable_feedback || (CompileBroker::queue_size(CompLevel_full_optimization) <=
|
||||
Tier3DelayOff * compiler_count(CompLevel_full_optimization) &&
|
||||
(this->*p)(i, b, cur_level, method))) {
|
||||
next_level = CompLevel_full_profile;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CompLevel_full_profile:
|
||||
{
|
||||
MethodData* mdo = method->method_data();
|
||||
if (mdo != NULL) {
|
||||
if (mdo->would_profile()) {
|
||||
break;
|
||||
case CompLevel_none:
|
||||
if (CompilationModeFlag::disable_intermediate()) {
|
||||
MethodData* mdo = method->method_data();
|
||||
if (mdo != NULL) {
|
||||
// If mdo exists that means we are in a normal profiling mode.
|
||||
int mdo_i = mdo->invocation_count_delta();
|
||||
int mdo_b = mdo->backedge_count_delta();
|
||||
if ((this->*p)(mdo_i, mdo_b, cur_level, method)) {
|
||||
next_level = CompLevel_full_optimization;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
} else {
|
||||
// If we were at full profile level, would we switch to full opt?
|
||||
if (common(p, method, CompLevel_full_profile, disable_feedback) == CompLevel_full_optimization) {
|
||||
next_level = CompLevel_full_optimization;
|
||||
} else if ((this->*p)(i, b, cur_level, method)) {
|
||||
#if INCLUDE_JVMCI
|
||||
if (EnableJVMCI && UseJVMCICompiler) {
|
||||
// Since JVMCI takes a while to warm up, its queue inevitably backs up during
|
||||
// early VM execution. As of 2014-06-13, JVMCI's inliner assumes that the root
|
||||
// compilation method and all potential inlinees have mature profiles (which
|
||||
// includes type profiling). If it sees immature profiles, JVMCI's inliner
|
||||
// can perform pathologically bad (e.g., causing OutOfMemoryErrors due to
|
||||
// exploring/inlining too many graphs). Since a rewrite of the inliner is
|
||||
// in progress, we simply disable the dialing back heuristic for now and will
|
||||
// revisit this decision once the new inliner is completed.
|
||||
next_level = CompLevel_full_profile;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
// C1-generated fully profiled code is about 30% slower than the limited profile
|
||||
// code that has only invocation and backedge counters. The observation is that
|
||||
// if C2 queue is large enough we can spend too much time in the fully profiled code
|
||||
// while waiting for C2 to pick the method from the queue. To alleviate this problem
|
||||
// we introduce a feedback on the C2 queue size. If the C2 queue is sufficiently long
|
||||
// we choose to compile a limited profiled version and then recompile with full profiling
|
||||
// when the load on C2 goes down.
|
||||
if (!disable_feedback && CompileBroker::queue_size(CompLevel_full_optimization) >
|
||||
Tier3DelayOn * compiler_count(CompLevel_full_optimization)) {
|
||||
next_level = CompLevel_limited_profile;
|
||||
} else {
|
||||
next_level = CompLevel_full_profile;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CompLevel_limited_profile:
|
||||
if (is_method_profiled(method)) {
|
||||
// Special case: we got here because this method was fully profiled in the interpreter.
|
||||
next_level = CompLevel_full_optimization;
|
||||
} else {
|
||||
MethodData* mdo = method->method_data();
|
||||
if (mdo != NULL) {
|
||||
if (mdo->would_profile()) {
|
||||
if (disable_feedback || (CompileBroker::queue_size(CompLevel_full_optimization) <=
|
||||
Tier3DelayOff * compiler_count(CompLevel_full_optimization) &&
|
||||
(this->*p)(i, b, cur_level, method))) {
|
||||
next_level = CompLevel_full_profile;
|
||||
}
|
||||
} else {
|
||||
next_level = CompLevel_full_optimization;
|
||||
}
|
||||
} else {
|
||||
// If there is no MDO we need to profile
|
||||
if (disable_feedback || (CompileBroker::queue_size(CompLevel_full_optimization) <=
|
||||
Tier3DelayOff * compiler_count(CompLevel_full_optimization) &&
|
||||
(this->*p)(i, b, cur_level, method))) {
|
||||
next_level = CompLevel_full_profile;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CompLevel_full_profile:
|
||||
{
|
||||
MethodData* mdo = method->method_data();
|
||||
if (mdo != NULL) {
|
||||
if (mdo->would_profile()) {
|
||||
int mdo_i = mdo->invocation_count_delta();
|
||||
int mdo_b = mdo->backedge_count_delta();
|
||||
if ((this->*p)(mdo_i, mdo_b, cur_level, method)) {
|
||||
next_level = CompLevel_full_optimization;
|
||||
}
|
||||
} else {
|
||||
next_level = CompLevel_full_optimization;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return MIN2(next_level, (CompLevel)TieredStopAtLevel);
|
||||
return MIN2(next_level, CompilationModeFlag::quick_only() ? CompLevel_simple : (CompLevel)TieredStopAtLevel);
|
||||
}
|
||||
|
||||
// Determine if a method should be compiled with a normal entry point at a different level.
|
||||
CompLevel TieredThresholdPolicy::call_event(Method* method, CompLevel cur_level, JavaThread * thread) {
|
||||
CompLevel TieredThresholdPolicy::call_event(Method* method, CompLevel cur_level, JavaThread* thread) {
|
||||
CompLevel osr_level = MIN2((CompLevel) method->highest_osr_comp_level(),
|
||||
common(&TieredThresholdPolicy::loop_predicate, method, cur_level, true));
|
||||
CompLevel next_level = common(&TieredThresholdPolicy::call_predicate, method, cur_level);
|
||||
@ -950,7 +1025,8 @@ void TieredThresholdPolicy::method_back_branch_event(const methodHandle& mh, con
|
||||
if (level == CompLevel_aot) {
|
||||
// Recompile the enclosing method to prevent infinite OSRs. Stay at AOT level while it's compiling.
|
||||
if (max_osr_level != CompLevel_none && !CompileBroker::compilation_is_in_queue(mh)) {
|
||||
compile(mh, InvocationEntryBci, MIN2((CompLevel)TieredStopAtLevel, CompLevel_full_profile), thread);
|
||||
CompLevel enclosing_level = MIN2(CompilationModeFlag::quick_only() ? CompLevel_simple : (CompLevel)TieredStopAtLevel, CompLevel_full_profile);
|
||||
compile(mh, InvocationEntryBci, enclosing_level, thread);
|
||||
}
|
||||
} else {
|
||||
// Current loop event level is not AOT
|
||||
|
@ -222,22 +222,18 @@ class TieredThresholdPolicy : public CompilationPolicy {
|
||||
|
||||
enum EventType { CALL, LOOP, COMPILE, REMOVE_FROM_QUEUE, UPDATE_IN_QUEUE, REPROFILE, MAKE_NOT_ENTRANT };
|
||||
void print_event(EventType type, const methodHandle& mh, const methodHandle& imh, int bci, CompLevel level);
|
||||
// Print policy-specific information if necessary
|
||||
void print_specific(EventType type, const methodHandle& mh, const methodHandle& imh, int bci, CompLevel level);
|
||||
// Check if the method can be compiled, change level if necessary
|
||||
void compile(const methodHandle& mh, int bci, CompLevel level, JavaThread* thread);
|
||||
// Submit a given method for compilation
|
||||
void submit_compile(const methodHandle& mh, int bci, CompLevel level, JavaThread* thread);
|
||||
// Simple methods are as good being compiled with C1 as C2.
|
||||
// This function tells if it's such a function.
|
||||
inline static bool is_trivial(Method* method);
|
||||
// Force method to be compiled at CompLevel_simple?
|
||||
inline static bool should_compile_at_level_simple(Method* method);
|
||||
inline bool force_comp_at_level_simple(Method* method);
|
||||
|
||||
// Predicate helpers are used by .*_predicate() methods as well as others.
|
||||
// They check the given counter values, multiplied by the scale against the thresholds.
|
||||
template<CompLevel level> static inline bool call_predicate_helper(int i, int b, double scale, Method* method);
|
||||
template<CompLevel level> static inline bool loop_predicate_helper(int i, int b, double scale, Method* method);
|
||||
inline bool call_predicate_helper(Method* method, CompLevel cur_level, int i, int b, double scale);
|
||||
inline bool loop_predicate_helper(Method* method, CompLevel cur_level, int i, int b, double scale);
|
||||
|
||||
// Get a compilation level for a given method.
|
||||
static CompLevel comp_level(Method* method);
|
||||
|
@ -3147,7 +3147,13 @@ jint Arguments::finalize_vm_init_args(bool patch_mod_javabase) {
|
||||
NOT_PRODUCT(UNSUPPORTED_OPTION(TraceProfileInterpreter));
|
||||
#endif
|
||||
|
||||
#ifndef TIERED
|
||||
|
||||
#ifdef TIERED
|
||||
// Parse the CompilationMode flag
|
||||
if (!CompilationModeFlag::initialize()) {
|
||||
return JNI_ERR;
|
||||
}
|
||||
#else
|
||||
// Tiered compilation is undefined.
|
||||
UNSUPPORTED_OPTION(TieredCompilation);
|
||||
#endif
|
||||
|
@ -60,16 +60,29 @@ JVMFlag::Error AliasLevelConstraintFunc(intx value, bool verbose) {
|
||||
* 4) The JVM is build using the compilers and tiered compilation is enabled. The option
|
||||
* 'TieredStopAtLevel = CompLevel_full_optimization' (the default value). As a result,
|
||||
* the minimum number of compiler threads is 2.
|
||||
* 5) Non-tiered emulation mode is on. CompilationModeFlag::disable_intermediate() == true.
|
||||
* The mininum number of threads is 2. But if CompilationModeFlag::quick_internal() == false, then it's 1.
|
||||
*/
|
||||
JVMFlag::Error CICompilerCountConstraintFunc(intx value, bool verbose) {
|
||||
int min_number_of_compiler_threads = 0;
|
||||
#if !defined(COMPILER1) && !defined(COMPILER2) && !INCLUDE_JVMCI
|
||||
// case 1
|
||||
#else
|
||||
if (!TieredCompilation || (TieredStopAtLevel < CompLevel_full_optimization)) {
|
||||
min_number_of_compiler_threads = 1; // case 2 or case 3
|
||||
if (TieredCompilation) {
|
||||
if (TieredStopAtLevel < CompLevel_full_optimization || CompilationModeFlag::quick_only()) {
|
||||
min_number_of_compiler_threads = 1; // case 3
|
||||
} else if (CompilationModeFlag::disable_intermediate()) {
|
||||
// case 5
|
||||
if (CompilationModeFlag::quick_internal()) {
|
||||
min_number_of_compiler_threads = 2;
|
||||
} else {
|
||||
min_number_of_compiler_threads = 1;
|
||||
}
|
||||
} else {
|
||||
min_number_of_compiler_threads = 2; // case 4 (tiered)
|
||||
}
|
||||
} else {
|
||||
min_number_of_compiler_threads = 2; // case 4 (tiered)
|
||||
min_number_of_compiler_threads = 1; // case 2
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -2059,6 +2059,35 @@ const size_t minimumSymbolTableSize = 1024;
|
||||
"if coming from AOT") \
|
||||
range(0, max_jint) \
|
||||
\
|
||||
diagnostic(intx, Tier0AOTInvocationThreshold, 200, \
|
||||
"Switch to interpreter to profile if the number of method " \
|
||||
"invocations crosses this threshold if coming from AOT " \
|
||||
"(applicable only with " \
|
||||
"CompilationMode=high-only|high-only-quick-internal)") \
|
||||
range(0, max_jint) \
|
||||
\
|
||||
diagnostic(intx, Tier0AOTMinInvocationThreshold, 100, \
|
||||
"Minimum number of invocations to switch to interpreter " \
|
||||
"to profile if coming from AOT " \
|
||||
"(applicable only with " \
|
||||
"CompilationMode=high-only|high-only-quick-internal)") \
|
||||
range(0, max_jint) \
|
||||
\
|
||||
diagnostic(intx, Tier0AOTCompileThreshold, 2000, \
|
||||
"Threshold at which to switch to interpreter to profile " \
|
||||
"if coming from AOT " \
|
||||
"(invocation minimum must be satisfied, " \
|
||||
"applicable only with " \
|
||||
"CompilationMode=high-only|high-only-quick-internal)") \
|
||||
range(0, max_jint) \
|
||||
\
|
||||
diagnostic(intx, Tier0AOTBackEdgeThreshold, 60000, \
|
||||
"Back edge threshold at which to switch to interpreter " \
|
||||
"to profile if coming from AOT " \
|
||||
"(applicable only with " \
|
||||
"CompilationMode=high-only|high-only-quick-internal)") \
|
||||
range(0, max_jint) \
|
||||
\
|
||||
product(intx, Tier4InvocationThreshold, 5000, \
|
||||
"Compile if number of method invocations crosses this " \
|
||||
"threshold") \
|
||||
@ -2070,13 +2099,44 @@ const size_t minimumSymbolTableSize = 1024;
|
||||
\
|
||||
product(intx, Tier4CompileThreshold, 15000, \
|
||||
"Threshold at which tier 4 compilation is invoked (invocation " \
|
||||
"minimum must be satisfied") \
|
||||
"minimum must be satisfied)") \
|
||||
range(0, max_jint) \
|
||||
\
|
||||
product(intx, Tier4BackEdgeThreshold, 40000, \
|
||||
"Back edge threshold at which tier 4 OSR compilation is invoked") \
|
||||
range(0, max_jint) \
|
||||
\
|
||||
diagnostic(intx, Tier40InvocationThreshold, 5000, \
|
||||
"Compile if number of method invocations crosses this " \
|
||||
"threshold (applicable only with " \
|
||||
"CompilationMode=high-only|high-only-quick-internal)") \
|
||||
range(0, max_jint) \
|
||||
\
|
||||
diagnostic(intx, Tier40MinInvocationThreshold, 600, \
|
||||
"Minimum number of invocations to compile at tier 4 " \
|
||||
"(applicable only with " \
|
||||
"CompilationMode=high-only|high-only-quick-internal)") \
|
||||
range(0, max_jint) \
|
||||
\
|
||||
diagnostic(intx, Tier40CompileThreshold, 10000, \
|
||||
"Threshold at which tier 4 compilation is invoked (invocation " \
|
||||
"minimum must be satisfied, applicable only with " \
|
||||
"CompilationMode=high-only|high-only-quick-internal)") \
|
||||
range(0, max_jint) \
|
||||
\
|
||||
diagnostic(intx, Tier40BackEdgeThreshold, 15000, \
|
||||
"Back edge threshold at which tier 4 OSR compilation is invoked " \
|
||||
"(applicable only with " \
|
||||
"CompilationMode=high-only|high-only-quick-internal)") \
|
||||
range(0, max_jint) \
|
||||
\
|
||||
diagnostic(intx, Tier0Delay, 5, \
|
||||
"If C2 queue size grows over this amount per compiler thread " \
|
||||
"do not start profiling in the interpreter " \
|
||||
"(applicable only with " \
|
||||
"CompilationMode=high-only|high-only-quick-internal)") \
|
||||
range(0, max_jint) \
|
||||
\
|
||||
product(intx, Tier3DelayOn, 5, \
|
||||
"If C2 queue size grows over this amount per compiler thread " \
|
||||
"stop compiling at tier 3 and start compiling at tier 2") \
|
||||
@ -2108,7 +2168,9 @@ const size_t minimumSymbolTableSize = 1024;
|
||||
\
|
||||
product(intx, Tier0ProfilingStartPercentage, 200, \
|
||||
"Start profiling in interpreter if the counters exceed tier 3 " \
|
||||
"thresholds by the specified percentage") \
|
||||
"thresholds (tier 4 thresholds with " \
|
||||
"CompilationMode=high-only|high-only-quick-internal)" \
|
||||
"by the specified percentage") \
|
||||
range(0, max_jint) \
|
||||
\
|
||||
product(uintx, IncreaseFirstTierCompileThresholdAt, 50, \
|
||||
@ -2124,6 +2186,14 @@ const size_t minimumSymbolTableSize = 1024;
|
||||
"Maximum rate sampling interval (in milliseconds)") \
|
||||
range(0, max_intx) \
|
||||
\
|
||||
product(ccstr, CompilationMode, "default", \
|
||||
"Compilation modes: " \
|
||||
"default: normal tiered compilation; " \
|
||||
"quick-only: C1-only mode; " \
|
||||
"high-only: C2/JVMCI-only mode; " \
|
||||
"high-only-quick-internal: C2/JVMCI-only mode, " \
|
||||
"with JVMCI compiler compiled with C1.") \
|
||||
\
|
||||
product_pd(bool, TieredCompilation, \
|
||||
"Enable tiered compilation") \
|
||||
\
|
||||
|
@ -31,8 +31,7 @@
|
||||
* @build compiler.profiling.spectrapredefineclass.Agent
|
||||
* @run driver ClassFileInstaller compiler.profiling.spectrapredefineclass.Agent
|
||||
* @run driver compiler.profiling.spectrapredefineclass.Launcher
|
||||
* @run main/othervm -XX:-TieredCompilation -XX:-BackgroundCompilation
|
||||
* -XX:CompileThreshold=10000
|
||||
* @run main/othervm -XX:CompilationMode=high-only -XX:-BackgroundCompilation -XX:CompileThreshold=10000
|
||||
* -XX:-UseOnStackReplacement -XX:TypeProfileLevel=222
|
||||
* -XX:ReservedCodeCacheSize=3M -Djdk.attach.allowAttachSelf
|
||||
* compiler.profiling.spectrapredefineclass.Agent
|
||||
|
@ -34,8 +34,7 @@
|
||||
* compiler.profiling.spectrapredefineclass_classloaders.B
|
||||
* @run driver ClassFileInstaller compiler.profiling.spectrapredefineclass_classloaders.Agent
|
||||
* @run driver compiler.profiling.spectrapredefineclass_classloaders.Launcher
|
||||
* @run main/othervm -XX:-TieredCompilation -XX:-BackgroundCompilation
|
||||
* -XX:CompileThreshold=10000
|
||||
* @run main/othervm -XX:CompilationMode=high-only -XX:-BackgroundCompilation -XX:CompileThreshold=10000
|
||||
* -XX:-UseOnStackReplacement -XX:TypeProfileLevel=222
|
||||
* -XX:ReservedCodeCacheSize=3M -Djdk.attach.allowAttachSelf
|
||||
* compiler.profiling.spectrapredefineclass_classloaders.Agent
|
||||
|
@ -34,7 +34,7 @@ import org.testng.annotations.Test;
|
||||
* java.compiler
|
||||
* java.management
|
||||
* jdk.internal.jvmstat/sun.jvmstat.monitor
|
||||
* @run testng/othervm -Xmx129m -XX:+UnlockDiagnosticVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+ThereShouldNotBeAnyVMOptionNamedLikeThis_Right -XX:-TieredCompilation FlagsTest
|
||||
* @run testng/othervm -Xmx129m -XX:+UnlockDiagnosticVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+ThereShouldNotBeAnyVMOptionNamedLikeThis_Right FlagsTest
|
||||
*/
|
||||
public class FlagsTest {
|
||||
public void run(CommandExecutor executor) {
|
||||
@ -43,7 +43,6 @@ public class FlagsTest {
|
||||
/* The following are interpreted by the JVM as actual "flags" */
|
||||
output.shouldContain("-XX:+UnlockDiagnosticVMOptions");
|
||||
output.shouldContain("-XX:+IgnoreUnrecognizedVMOptions");
|
||||
output.shouldContain("-XX:-TieredCompilation");
|
||||
|
||||
/* The following are not */
|
||||
output.shouldNotContain("-Xmx129m");
|
||||
|
Loading…
Reference in New Issue
Block a user