mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-18 18:14:38 +02:00
8273712: C2: Add mechanism for rejecting inlining of low frequency call sites and deprecate MinInliningThreshold.
Reviewed-by: kvn, rbackman
This commit is contained in:
parent
3221a14f9e
commit
89671aa164
6 changed files with 34 additions and 22 deletions
|
@ -237,6 +237,7 @@ class CompilationPolicy : AllStatic {
|
|||
// m must be compiled before executing it
|
||||
static bool must_be_compiled(const methodHandle& m, int comp_level = CompLevel_any);
|
||||
public:
|
||||
static int min_invocations() { return Tier4MinInvocationThreshold; }
|
||||
static int c1_count() { return _c1_count; }
|
||||
static int c2_count() { return _c2_count; }
|
||||
static int compiler_count(CompLevel comp_level);
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "precompiled.hpp"
|
||||
#include "ci/ciReplay.hpp"
|
||||
#include "classfile/vmSymbols.hpp"
|
||||
#include "compiler/compilationPolicy.hpp"
|
||||
#include "compiler/compileBroker.hpp"
|
||||
#include "compiler/compilerEvent.hpp"
|
||||
#include "compiler/compileLog.hpp"
|
||||
|
@ -152,8 +153,8 @@ bool InlineTree::should_inline(ciMethod* callee_method, ciMethod* caller_method,
|
|||
int inline_small_code_size = InlineSmallCode / 4;
|
||||
int max_inline_size = default_max_inline_size;
|
||||
|
||||
int call_site_count = method()->scale_count(profile.count());
|
||||
int invoke_count = method()->interpreter_invocation_count();
|
||||
int call_site_count = caller_method->scale_count(profile.count());
|
||||
int invoke_count = caller_method->interpreter_invocation_count();
|
||||
|
||||
assert(invoke_count != 0, "require invocation count greater than zero");
|
||||
double freq = (double)call_site_count / (double)invoke_count;
|
||||
|
@ -192,10 +193,8 @@ bool InlineTree::should_inline(ciMethod* callee_method, ciMethod* caller_method,
|
|||
|
||||
|
||||
// negative filter: should callee NOT be inlined?
|
||||
bool InlineTree::should_not_inline(ciMethod *callee_method,
|
||||
ciMethod* caller_method,
|
||||
JVMState* jvms) {
|
||||
|
||||
bool InlineTree::should_not_inline(ciMethod* callee_method, ciMethod* caller_method,
|
||||
int caller_bci, ciCallProfile& profile) {
|
||||
const char* fail_msg = NULL;
|
||||
|
||||
// First check all inlining restrictions which are required for correctness
|
||||
|
@ -233,7 +232,6 @@ bool InlineTree::should_not_inline(ciMethod *callee_method,
|
|||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
int caller_bci = jvms->bci();
|
||||
int inline_depth = inline_level()+1;
|
||||
if (ciReplay::should_inline(C->replay_inline_data(), callee_method, caller_bci, inline_depth)) {
|
||||
set_msg("force inline by ciReplay");
|
||||
|
@ -289,7 +287,6 @@ bool InlineTree::should_not_inline(ciMethod *callee_method,
|
|||
|
||||
// don't use counts with -Xcomp
|
||||
if (UseInterpreter) {
|
||||
|
||||
if (!callee_method->has_compiled_code() &&
|
||||
!callee_method->was_executed_more_than(0)) {
|
||||
set_msg("never executed");
|
||||
|
@ -299,15 +296,23 @@ bool InlineTree::should_not_inline(ciMethod *callee_method,
|
|||
if (is_init_with_ea(callee_method, caller_method, C)) {
|
||||
// Escape Analysis: inline all executed constructors
|
||||
return false;
|
||||
} else {
|
||||
intx counter_high_value;
|
||||
// Tiered compilation uses a different "high value" than non-tiered compilation.
|
||||
// Determine the right value to use.
|
||||
if (TieredCompilation) {
|
||||
counter_high_value = InvocationCounter::count_limit / 2;
|
||||
} else {
|
||||
counter_high_value = CompileThreshold / 2;
|
||||
}
|
||||
|
||||
if (MinInlineFrequencyRatio > 0) {
|
||||
int call_site_count = caller_method->scale_count(profile.count());
|
||||
int invoke_count = caller_method->interpreter_invocation_count();
|
||||
assert(invoke_count != 0, "require invocation count greater than zero");
|
||||
double freq = (double)call_site_count / (double)invoke_count;
|
||||
double min_freq = MAX2(MinInlineFrequencyRatio, 1.0 / CompilationPolicy::min_invocations());
|
||||
|
||||
if (freq < min_freq) {
|
||||
set_msg("low call site frequency");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (MinInliningThreshold > 0) { // Deprecated heuristic
|
||||
intx counter_high_value = TieredCompilation ? InvocationCounter::count_limit / 2 : CompileThreshold / 2;
|
||||
if (!callee_method->was_executed_more_than(MIN2(MinInliningThreshold, counter_high_value))) {
|
||||
set_msg("executed < MinInliningThreshold times");
|
||||
return true;
|
||||
|
@ -367,7 +372,7 @@ bool InlineTree::try_to_inline(ciMethod* callee_method, ciMethod* caller_method,
|
|||
if (!should_inline(callee_method, caller_method, caller_bci, profile)) {
|
||||
return false;
|
||||
}
|
||||
if (should_not_inline(callee_method, caller_method, jvms)) {
|
||||
if (should_not_inline(callee_method, caller_method, caller_bci, profile)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -78,7 +78,8 @@ protected:
|
|||
ciCallProfile& profile);
|
||||
bool should_not_inline(ciMethod* callee_method,
|
||||
ciMethod* caller_method,
|
||||
JVMState* jvms);
|
||||
int caller_bci,
|
||||
ciCallProfile& profile);
|
||||
bool is_not_reached(ciMethod* callee_method,
|
||||
ciMethod* caller_method,
|
||||
int caller_bci,
|
||||
|
|
|
@ -527,6 +527,7 @@ static SpecialFlag const special_jvm_flags[] = {
|
|||
{ "AllowRedefinitionToAddDeleteMethods", JDK_Version::jdk(13), JDK_Version::undefined(), JDK_Version::undefined() },
|
||||
{ "FlightRecorder", JDK_Version::jdk(13), JDK_Version::undefined(), JDK_Version::undefined() },
|
||||
{ "FilterSpuriousWakeups", JDK_Version::jdk(18), JDK_Version::jdk(19), JDK_Version::jdk(20) },
|
||||
{ "MinInliningThreshold", JDK_Version::jdk(18), JDK_Version::jdk(19), JDK_Version::jdk(20) },
|
||||
|
||||
// --- Deprecated alias flags (see also aliased_jvm_flags) - sorted by obsolete_in then expired_in:
|
||||
{ "DefaultMaxRAMFraction", JDK_Version::jdk(8), JDK_Version::undefined(), JDK_Version::undefined() },
|
||||
|
|
|
@ -1348,9 +1348,9 @@ const intx ObjectAlignmentInBytes = 8;
|
|||
"(using CompileCommand or marked w/ @ForceInline)") \
|
||||
range(0, max_jint) \
|
||||
\
|
||||
product(intx, MinInliningThreshold, 250, \
|
||||
"The minimum invocation count a method needs to have to be " \
|
||||
"inlined") \
|
||||
product(intx, MinInliningThreshold, 0, \
|
||||
"(Deprecated) The minimum invocation count a method needs to" \
|
||||
"have to be inlined") \
|
||||
range(0, max_jint) \
|
||||
\
|
||||
develop(intx, MethodHistogramCutoff, 100, \
|
||||
|
@ -1404,6 +1404,10 @@ const intx ObjectAlignmentInBytes = 8;
|
|||
product(double, InlineFrequencyRatio, 0.25, DIAGNOSTIC, \
|
||||
"Ratio of call site execution to caller method invocation") \
|
||||
\
|
||||
product(double, MinInlineFrequencyRatio, 0.0085, DIAGNOSTIC, \
|
||||
"Minimum ratio of call site execution to caller method" \
|
||||
"invocation to be considered for inlining") \
|
||||
\
|
||||
develop(intx, InlineThrowCount, 50, \
|
||||
"Force inlining of interpreted methods that throw this often") \
|
||||
range(0, max_jint) \
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
* -XX:+WhiteBoxAPI
|
||||
* -XX:+IgnoreUnrecognizedVMOptions
|
||||
* -XX:MaxInlineSize=70
|
||||
* -XX:MinInliningThreshold=0
|
||||
* -XX:MinInlineFrequencyRatio=0
|
||||
* compiler.intrinsics.string.TestStringIntrinsics2
|
||||
*/
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue