提交 30ace565 编写于 作者: I iignatyev

8007439: C2: adding successful message of inlining

Reviewed-by: kvn, vlivanov
上级 b2d65fa7
...@@ -47,7 +47,8 @@ InlineTree::InlineTree(Compile* c, ...@@ -47,7 +47,8 @@ InlineTree::InlineTree(Compile* c,
_site_invoke_ratio(site_invoke_ratio), _site_invoke_ratio(site_invoke_ratio),
_max_inline_level(max_inline_level), _max_inline_level(max_inline_level),
_count_inline_bcs(method()->code_size_for_inlining()), _count_inline_bcs(method()->code_size_for_inlining()),
_subtrees(c->comp_arena(), 2, 0, NULL) _subtrees(c->comp_arena(), 2, 0, NULL),
_msg(NULL)
{ {
NOT_PRODUCT(_count_inlines = 0;) NOT_PRODUCT(_count_inlines = 0;)
if (_caller_jvms != NULL) { if (_caller_jvms != NULL) {
...@@ -77,7 +78,8 @@ InlineTree::InlineTree(Compile* c, ciMethod* callee_method, JVMState* caller_jvm ...@@ -77,7 +78,8 @@ InlineTree::InlineTree(Compile* c, ciMethod* callee_method, JVMState* caller_jvm
_method(callee_method), _method(callee_method),
_site_invoke_ratio(site_invoke_ratio), _site_invoke_ratio(site_invoke_ratio),
_max_inline_level(max_inline_level), _max_inline_level(max_inline_level),
_count_inline_bcs(method()->code_size()) _count_inline_bcs(method()->code_size()),
_msg(NULL)
{ {
NOT_PRODUCT(_count_inlines = 0;) NOT_PRODUCT(_count_inlines = 0;)
assert(!UseOldInlining, "do not use for old stuff"); assert(!UseOldInlining, "do not use for old stuff");
...@@ -95,8 +97,10 @@ static bool is_init_with_ea(ciMethod* callee_method, ...@@ -95,8 +97,10 @@ static bool is_init_with_ea(ciMethod* callee_method,
); );
} }
// positive filter: should callee be inlined? returns NULL, if yes, or rejection msg // positive filter: should callee be inlined?
const char* InlineTree::should_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) const { bool InlineTree::should_inline(ciMethod* callee_method, ciMethod* caller_method,
int caller_bci, ciCallProfile& profile,
WarmCallInfo* wci_result) {
// Allows targeted inlining // Allows targeted inlining
if(callee_method->should_inline()) { if(callee_method->should_inline()) {
*wci_result = *(WarmCallInfo::always_hot()); *wci_result = *(WarmCallInfo::always_hot());
...@@ -104,11 +108,10 @@ const char* InlineTree::should_inline(ciMethod* callee_method, ciMethod* caller_ ...@@ -104,11 +108,10 @@ const char* InlineTree::should_inline(ciMethod* callee_method, ciMethod* caller_
CompileTask::print_inline_indent(inline_level()); CompileTask::print_inline_indent(inline_level());
tty->print_cr("Inlined method is hot: "); tty->print_cr("Inlined method is hot: ");
} }
return NULL; set_msg("force inline by CompilerOracle");
return true;
} }
// positive filter: should send be inlined? returns NULL (--> yes)
// or rejection msg
int size = callee_method->code_size_for_inlining(); int size = callee_method->code_size_for_inlining();
// Check for too many throws (and not too huge) // Check for too many throws (and not too huge)
...@@ -119,11 +122,13 @@ const char* InlineTree::should_inline(ciMethod* callee_method, ciMethod* caller_ ...@@ -119,11 +122,13 @@ const char* InlineTree::should_inline(ciMethod* callee_method, ciMethod* caller_
CompileTask::print_inline_indent(inline_level()); CompileTask::print_inline_indent(inline_level());
tty->print_cr("Inlined method with many throws (throws=%d):", callee_method->interpreter_throwout_count()); tty->print_cr("Inlined method with many throws (throws=%d):", callee_method->interpreter_throwout_count());
} }
return NULL; set_msg("many throws");
return true;
} }
if (!UseOldInlining) { if (!UseOldInlining) {
return NULL; // size and frequency are represented in a new way set_msg("!UseOldInlining");
return true; // size and frequency are represented in a new way
} }
int default_max_inline_size = C->max_inline_size(); int default_max_inline_size = C->max_inline_size();
...@@ -153,31 +158,44 @@ const char* InlineTree::should_inline(ciMethod* callee_method, ciMethod* caller_ ...@@ -153,31 +158,44 @@ const char* InlineTree::should_inline(ciMethod* callee_method, ciMethod* caller_
// Not hot. Check for medium-sized pre-existing nmethod at cold sites. // Not hot. Check for medium-sized pre-existing nmethod at cold sites.
if (callee_method->has_compiled_code() && if (callee_method->has_compiled_code() &&
callee_method->instructions_size() > inline_small_code_size) callee_method->instructions_size() > inline_small_code_size)
return "already compiled into a medium method"; set_msg("already compiled into a medium method");
return false;
} }
if (size > max_inline_size) { if (size > max_inline_size) {
if (max_inline_size > default_max_inline_size) if (max_inline_size > default_max_inline_size) {
return "hot method too big"; set_msg("hot method too big");
return "too big"; } else {
set_msg("too big");
} }
return NULL; return false;
}
return true;
} }
// negative filter: should callee NOT be inlined? returns NULL, ok to inline, or rejection msg // negative filter: should callee NOT be inlined?
const char* InlineTree::should_not_inline(ciMethod *callee_method, ciMethod* caller_method, WarmCallInfo* wci_result) const { bool InlineTree::should_not_inline(ciMethod *callee_method,
// negative filter: should send NOT be inlined? returns NULL (--> inline) or rejection msg ciMethod* caller_method,
WarmCallInfo* wci_result) {
const char* fail_msg = NULL;
// First check all inlining restrictions which are required for correctness
if ( callee_method->is_abstract()) {
fail_msg = "abstract method"; // // note: we allow ik->is_abstract()
} else if (!callee_method->holder()->is_initialized()) {
fail_msg = "method holder not initialized";
} else if ( callee_method->is_native()) {
fail_msg = "native method";
} else if ( callee_method->dont_inline()) {
fail_msg = "don't inline by annotation";
}
if (!UseOldInlining) { if (!UseOldInlining) {
const char* fail = NULL; if (fail_msg != NULL) {
if ( callee_method->is_abstract()) fail = "abstract method";
// note: we allow ik->is_abstract()
if (!callee_method->holder()->is_initialized()) fail = "method holder not initialized";
if ( callee_method->is_native()) fail = "native method";
if ( callee_method->dont_inline()) fail = "don't inline by annotation";
if (fail) {
*wci_result = *(WarmCallInfo::always_cold()); *wci_result = *(WarmCallInfo::always_cold());
return fail; set_msg(fail_msg);
return true;
} }
if (callee_method->has_unloaded_classes_in_signature()) { if (callee_method->has_unloaded_classes_in_signature()) {
...@@ -199,20 +217,23 @@ const char* InlineTree::should_not_inline(ciMethod *callee_method, ciMethod* cal ...@@ -199,20 +217,23 @@ const char* InlineTree::should_not_inline(ciMethod *callee_method, ciMethod* cal
// %%% adjust wci_result->size()? // %%% adjust wci_result->size()?
} }
return NULL; return false;
} }
// First check all inlining restrictions which are required for correctness // one more inlining restriction
if ( callee_method->is_abstract()) return "abstract method"; if (fail_msg == NULL && callee_method->has_unloaded_classes_in_signature()) {
// note: we allow ik->is_abstract() fail_msg = "unloaded signature classes";
if (!callee_method->holder()->is_initialized()) return "method holder not initialized"; }
if ( callee_method->is_native()) return "native method";
if ( callee_method->dont_inline()) return "don't inline by annotation"; if (fail_msg != NULL) {
if ( callee_method->has_unloaded_classes_in_signature()) return "unloaded signature classes"; set_msg(fail_msg);
return true;
}
if (callee_method->should_inline()) {
// ignore heuristic controls on inlining // ignore heuristic controls on inlining
return NULL; if (callee_method->should_inline()) {
set_msg("force inline by CompilerOracle");
return false;
} }
// Now perform checks which are heuristic // Now perform checks which are heuristic
...@@ -220,7 +241,8 @@ const char* InlineTree::should_not_inline(ciMethod *callee_method, ciMethod* cal ...@@ -220,7 +241,8 @@ const char* InlineTree::should_not_inline(ciMethod *callee_method, ciMethod* cal
if (!callee_method->force_inline()) { if (!callee_method->force_inline()) {
if (callee_method->has_compiled_code() && if (callee_method->has_compiled_code() &&
callee_method->instructions_size() > InlineSmallCode) { callee_method->instructions_size() > InlineSmallCode) {
return "already compiled into a big method"; set_msg("already compiled into a big method");
return true;
} }
} }
...@@ -231,17 +253,21 @@ const char* InlineTree::should_not_inline(ciMethod *callee_method, ciMethod* cal ...@@ -231,17 +253,21 @@ const char* InlineTree::should_not_inline(ciMethod *callee_method, ciMethod* cal
const InlineTree *top = this; const InlineTree *top = this;
while (top->caller_tree() != NULL) top = top->caller_tree(); while (top->caller_tree() != NULL) top = top->caller_tree();
ciInstanceKlass* k = top->method()->holder(); ciInstanceKlass* k = top->method()->holder();
if (!k->is_subclass_of(C->env()->Throwable_klass())) if (!k->is_subclass_of(C->env()->Throwable_klass())) {
return "exception method"; set_msg("exception method");
return true;
}
} }
if (callee_method->should_not_inline()) { if (callee_method->should_not_inline()) {
return "disallowed by CompilerOracle"; set_msg("disallowed by CompilerOracle");
return true;
} }
#ifndef PRODUCT #ifndef PRODUCT
if (ciReplay::should_not_inline(callee_method)) { if (ciReplay::should_not_inline(callee_method)) {
return "disallowed by ciReplay"; set_msg("disallowed by ciReplay");
return true;
} }
#endif #endif
...@@ -249,19 +275,23 @@ const char* InlineTree::should_not_inline(ciMethod *callee_method, ciMethod* cal ...@@ -249,19 +275,23 @@ const char* InlineTree::should_not_inline(ciMethod *callee_method, ciMethod* cal
// Do not inline StringCache::profile() method used only at the beginning. // Do not inline StringCache::profile() method used only at the beginning.
if (callee_method->name() == ciSymbol::profile_name() && if (callee_method->name() == ciSymbol::profile_name() &&
callee_method->holder()->name() == ciSymbol::java_lang_StringCache()) { callee_method->holder()->name() == ciSymbol::java_lang_StringCache()) {
return "profiling method"; set_msg("profiling method");
return true;
} }
} }
// use frequency-based objections only for non-trivial methods // use frequency-based objections only for non-trivial methods
if (callee_method->code_size() <= MaxTrivialSize) return NULL; if (callee_method->code_size() <= MaxTrivialSize) {
return false;
}
// don't use counts with -Xcomp or CTW // don't use counts with -Xcomp or CTW
if (UseInterpreter && !CompileTheWorld) { if (UseInterpreter && !CompileTheWorld) {
if (!callee_method->has_compiled_code() && if (!callee_method->has_compiled_code() &&
!callee_method->was_executed_more_than(0)) { !callee_method->was_executed_more_than(0)) {
return "never executed"; set_msg("never executed");
return true;
} }
if (is_init_with_ea(callee_method, caller_method, C)) { if (is_init_with_ea(callee_method, caller_method, C)) {
...@@ -270,39 +300,44 @@ const char* InlineTree::should_not_inline(ciMethod *callee_method, ciMethod* cal ...@@ -270,39 +300,44 @@ const char* InlineTree::should_not_inline(ciMethod *callee_method, ciMethod* cal
} else if (!callee_method->was_executed_more_than(MIN2(MinInliningThreshold, } else if (!callee_method->was_executed_more_than(MIN2(MinInliningThreshold,
CompileThreshold >> 1))) { CompileThreshold >> 1))) {
return "executed < MinInliningThreshold times"; set_msg("executed < MinInliningThreshold times");
return true;
} }
} }
return NULL; return false;
} }
//-----------------------------try_to_inline----------------------------------- //-----------------------------try_to_inline-----------------------------------
// return NULL if ok, reason for not inlining otherwise // return true if ok
// Relocated from "InliningClosure::try_to_inline" // Relocated from "InliningClosure::try_to_inline"
const char* InlineTree::try_to_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result, bool& should_delay) { bool InlineTree::try_to_inline(ciMethod* callee_method, ciMethod* caller_method,
int caller_bci, ciCallProfile& profile,
WarmCallInfo* wci_result, bool& should_delay) {
// Old algorithm had funny accumulating BC-size counters // Old algorithm had funny accumulating BC-size counters
if (UseOldInlining && ClipInlining if (UseOldInlining && ClipInlining
&& (int)count_inline_bcs() >= DesiredMethodLimit) { && (int)count_inline_bcs() >= DesiredMethodLimit) {
if (!callee_method->force_inline() || !IncrementalInline) { if (!callee_method->force_inline() || !IncrementalInline) {
return "size > DesiredMethodLimit"; set_msg("size > DesiredMethodLimit");
return false;
} else if (!C->inlining_incrementally()) { } else if (!C->inlining_incrementally()) {
should_delay = true; should_delay = true;
} }
} }
const char *msg = NULL; if (!should_inline(callee_method, caller_method, caller_bci, profile,
msg = should_inline(callee_method, caller_method, caller_bci, profile, wci_result); wci_result)) {
if (msg != NULL) return false;
return msg; }
if (should_not_inline(callee_method, caller_method, wci_result)) {
msg = should_not_inline(callee_method, caller_method, wci_result); return false;
if (msg != NULL) }
return msg;
if (InlineAccessors && callee_method->is_accessor()) { if (InlineAccessors && callee_method->is_accessor()) {
// accessor methods are not subject to any of the following limits. // accessor methods are not subject to any of the following limits.
return NULL; set_msg("accessor");
return true;
} }
// suppress a few checks for accessors and trivial methods // suppress a few checks for accessors and trivial methods
...@@ -312,7 +347,8 @@ const char* InlineTree::try_to_inline(ciMethod* callee_method, ciMethod* caller_ ...@@ -312,7 +347,8 @@ const char* InlineTree::try_to_inline(ciMethod* callee_method, ciMethod* caller_
if (C->over_inlining_cutoff()) { if (C->over_inlining_cutoff()) {
if ((!callee_method->force_inline() && !caller_method->is_compiled_lambda_form()) if ((!callee_method->force_inline() && !caller_method->is_compiled_lambda_form())
|| !IncrementalInline) { || !IncrementalInline) {
return "NodeCountInliningCutoff"; set_msg("NodeCountInliningCutoff");
return false;
} else { } else {
should_delay = true; should_delay = true;
} }
...@@ -326,16 +362,19 @@ const char* InlineTree::try_to_inline(ciMethod* callee_method, ciMethod* caller_ ...@@ -326,16 +362,19 @@ const char* InlineTree::try_to_inline(ciMethod* callee_method, ciMethod* caller_
} else if (profile.count() == 0) { } else if (profile.count() == 0) {
// don't inline unreached call sites // don't inline unreached call sites
return "call site not reached"; set_msg("call site not reached");
return false;
} }
} }
if (!C->do_inlining() && InlineAccessors) { if (!C->do_inlining() && InlineAccessors) {
return "not an accessor"; set_msg("not an accessor");
return false;
} }
if (inline_level() > _max_inline_level) { if (inline_level() > _max_inline_level) {
if (!callee_method->force_inline() || !IncrementalInline) { if (!callee_method->force_inline() || !IncrementalInline) {
return "inlining too deep"; set_msg("inlining too deep");
return false;
} else if (!C->inlining_incrementally()) { } else if (!C->inlining_incrementally()) {
should_delay = true; should_delay = true;
} }
...@@ -345,15 +384,19 @@ const char* InlineTree::try_to_inline(ciMethod* callee_method, ciMethod* caller_ ...@@ -345,15 +384,19 @@ const char* InlineTree::try_to_inline(ciMethod* callee_method, ciMethod* caller_
if (!callee_method->is_compiled_lambda_form()) { if (!callee_method->is_compiled_lambda_form()) {
// count the current method and the callee // count the current method and the callee
int inline_level = (method() == callee_method) ? 1 : 0; int inline_level = (method() == callee_method) ? 1 : 0;
if (inline_level > MaxRecursiveInlineLevel) if (inline_level > MaxRecursiveInlineLevel) {
return "recursively inlining too deep"; set_msg("recursively inlining too deep");
return false;
}
// count callers of current method and callee // count callers of current method and callee
JVMState* jvms = caller_jvms(); JVMState* jvms = caller_jvms();
while (jvms != NULL && jvms->has_method()) { while (jvms != NULL && jvms->has_method()) {
if (jvms->method() == callee_method) { if (jvms->method() == callee_method) {
inline_level++; inline_level++;
if (inline_level > MaxRecursiveInlineLevel) if (inline_level > MaxRecursiveInlineLevel) {
return "recursively inlining too deep"; set_msg("recursively inlining too deep");
return false;
}
} }
jvms = jvms->caller(); jvms = jvms->caller();
} }
...@@ -364,14 +407,15 @@ const char* InlineTree::try_to_inline(ciMethod* callee_method, ciMethod* caller_ ...@@ -364,14 +407,15 @@ const char* InlineTree::try_to_inline(ciMethod* callee_method, ciMethod* caller_
if (UseOldInlining && ClipInlining if (UseOldInlining && ClipInlining
&& (int)count_inline_bcs() + size >= DesiredMethodLimit) { && (int)count_inline_bcs() + size >= DesiredMethodLimit) {
if (!callee_method->force_inline() || !IncrementalInline) { if (!callee_method->force_inline() || !IncrementalInline) {
return "size > DesiredMethodLimit"; set_msg("size > DesiredMethodLimit");
return false;
} else if (!C->inlining_incrementally()) { } else if (!C->inlining_incrementally()) {
should_delay = true; should_delay = true;
} }
} }
// ok, inline this method // ok, inline this method
return NULL; return true;
} }
//------------------------------pass_initial_checks---------------------------- //------------------------------pass_initial_checks----------------------------
...@@ -421,17 +465,18 @@ const char* InlineTree::check_can_parse(ciMethod* callee) { ...@@ -421,17 +465,18 @@ const char* InlineTree::check_can_parse(ciMethod* callee) {
//------------------------------print_inlining--------------------------------- //------------------------------print_inlining---------------------------------
void InlineTree::print_inlining(ciMethod* callee_method, int caller_bci, void InlineTree::print_inlining(ciMethod* callee_method, int caller_bci,
const char* msg, bool success) const { bool success) const {
assert(msg != NULL, "just checking"); const char* inline_msg = msg();
assert(inline_msg != NULL, "just checking");
if (C->log() != NULL) { if (C->log() != NULL) {
if (success) { if (success) {
C->log()->inline_success(msg); C->log()->inline_success(inline_msg);
} else { } else {
C->log()->inline_fail(msg); C->log()->inline_fail(inline_msg);
} }
} }
if (PrintInlining) { if (PrintInlining) {
C->print_inlining(callee_method, inline_level(), caller_bci, msg); C->print_inlining(callee_method, inline_level(), caller_bci, inline_msg);
if (callee_method == NULL) tty->print(" callee not monotonic or profiled"); if (callee_method == NULL) tty->print(" callee not monotonic or profiled");
if (Verbose && callee_method) { if (Verbose && callee_method) {
const InlineTree *top = this; const InlineTree *top = this;
...@@ -455,49 +500,51 @@ WarmCallInfo* InlineTree::ok_to_inline(ciMethod* callee_method, JVMState* jvms, ...@@ -455,49 +500,51 @@ WarmCallInfo* InlineTree::ok_to_inline(ciMethod* callee_method, JVMState* jvms,
} }
assert(_method == jvms->method(), "redundant instance state"); assert(_method == jvms->method(), "redundant instance state");
#endif #endif
const char *failure_msg = NULL;
int caller_bci = jvms->bci(); int caller_bci = jvms->bci();
ciMethod *caller_method = jvms->method(); ciMethod* caller_method = jvms->method();
// Do some initial checks. // Do some initial checks.
if (!pass_initial_checks(caller_method, caller_bci, callee_method)) { if (!pass_initial_checks(caller_method, caller_bci, callee_method)) {
print_inlining(callee_method, caller_bci, "failed initial checks", set_msg("failed initial checks");
false /* !success */); print_inlining(callee_method, caller_bci, false /* !success */);
return NULL; return NULL;
} }
// Do some parse checks. // Do some parse checks.
failure_msg = check_can_parse(callee_method); set_msg(check_can_parse(callee_method));
if (failure_msg != NULL) { if (msg() != NULL) {
print_inlining(callee_method, caller_bci, failure_msg, print_inlining(callee_method, caller_bci, false /* !success */);
false /* !success */);
return NULL; return NULL;
} }
// Check if inlining policy says no. // Check if inlining policy says no.
WarmCallInfo wci = *(initial_wci); WarmCallInfo wci = *(initial_wci);
failure_msg = try_to_inline(callee_method, caller_method, caller_bci, profile, bool success = try_to_inline(callee_method, caller_method, caller_bci,
&wci, should_delay); profile, &wci, should_delay);
#ifndef PRODUCT #ifndef PRODUCT
if (UseOldInlining && InlineWarmCalls if (UseOldInlining && InlineWarmCalls
&& (PrintOpto || PrintOptoInlining || PrintInlining)) { && (PrintOpto || PrintOptoInlining || PrintInlining)) {
bool cold = wci.is_cold(); bool cold = wci.is_cold();
bool hot = !cold && wci.is_hot(); bool hot = !cold && wci.is_hot();
bool old_cold = (failure_msg != NULL); bool old_cold = !success;
if (old_cold != cold || (Verbose || WizardMode)) { if (old_cold != cold || (Verbose || WizardMode)) {
if (msg() == NULL) {
set_msg("OK");
}
tty->print(" OldInlining= %4s : %s\n WCI=", tty->print(" OldInlining= %4s : %s\n WCI=",
old_cold ? "cold" : "hot", failure_msg ? failure_msg : "OK"); old_cold ? "cold" : "hot", msg());
wci.print(); wci.print();
} }
} }
#endif #endif
if (UseOldInlining) { if (UseOldInlining) {
if (failure_msg == NULL) if (success) {
wci = *(WarmCallInfo::always_hot()); wci = *(WarmCallInfo::always_hot());
else } else {
wci = *(WarmCallInfo::always_cold()); wci = *(WarmCallInfo::always_cold());
} }
}
if (!InlineWarmCalls) { if (!InlineWarmCalls) {
if (!wci.is_cold() && !wci.is_hot()) { if (!wci.is_cold() && !wci.is_hot()) {
// Do not inline the warm calls. // Do not inline the warm calls.
...@@ -507,9 +554,10 @@ WarmCallInfo* InlineTree::ok_to_inline(ciMethod* callee_method, JVMState* jvms, ...@@ -507,9 +554,10 @@ WarmCallInfo* InlineTree::ok_to_inline(ciMethod* callee_method, JVMState* jvms,
if (!wci.is_cold()) { if (!wci.is_cold()) {
// Inline! // Inline!
print_inlining(callee_method, caller_bci, if (msg() == NULL) {
failure_msg ? failure_msg : "inline (hot)", set_msg("inline (hot)");
true /* success */); }
print_inlining(callee_method, caller_bci, true /* success */);
if (UseOldInlining) if (UseOldInlining)
build_inline_tree_for_callee(callee_method, jvms, caller_bci); build_inline_tree_for_callee(callee_method, jvms, caller_bci);
if (InlineWarmCalls && !wci.is_hot()) if (InlineWarmCalls && !wci.is_hot())
...@@ -518,9 +566,10 @@ WarmCallInfo* InlineTree::ok_to_inline(ciMethod* callee_method, JVMState* jvms, ...@@ -518,9 +566,10 @@ WarmCallInfo* InlineTree::ok_to_inline(ciMethod* callee_method, JVMState* jvms,
} }
// Do not inline // Do not inline
print_inlining(callee_method, caller_bci, if (msg() == NULL) {
failure_msg ? failure_msg : "too cold to inline", set_msg("too cold to inline");
false /* !success */ ); }
print_inlining(callee_method, caller_bci, false /* !success */ );
return NULL; return NULL;
} }
......
...@@ -58,7 +58,7 @@ class InlineTree : public ResourceObj { ...@@ -58,7 +58,7 @@ class InlineTree : public ResourceObj {
GrowableArray<InlineTree*> _subtrees; GrowableArray<InlineTree*> _subtrees;
void print_impl(outputStream* stj, int indent) const PRODUCT_RETURN; void print_impl(outputStream* stj, int indent) const PRODUCT_RETURN;
const char* _msg;
protected: protected:
InlineTree(Compile* C, InlineTree(Compile* C,
const InlineTree* caller_tree, const InlineTree* caller_tree,
...@@ -70,17 +70,29 @@ protected: ...@@ -70,17 +70,29 @@ protected:
InlineTree *build_inline_tree_for_callee(ciMethod* callee_method, InlineTree *build_inline_tree_for_callee(ciMethod* callee_method,
JVMState* caller_jvms, JVMState* caller_jvms,
int caller_bci); int caller_bci);
const char* try_to_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result, bool& should_delay); bool try_to_inline(ciMethod* callee_method,
const char* should_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) const; ciMethod* caller_method,
const char* should_not_inline(ciMethod* callee_method, ciMethod* caller_method, WarmCallInfo* wci_result) const; int caller_bci,
ciCallProfile& profile,
WarmCallInfo* wci_result,
bool& should_delay);
bool should_inline(ciMethod* callee_method,
ciMethod* caller_method,
int caller_bci,
ciCallProfile& profile,
WarmCallInfo* wci_result);
bool should_not_inline(ciMethod* callee_method,
ciMethod* caller_method,
WarmCallInfo* wci_result);
void print_inlining(ciMethod* callee_method, int caller_bci, void print_inlining(ciMethod* callee_method, int caller_bci,
const char* msg, bool success) const; bool success) const;
InlineTree *caller_tree() const { return _caller_tree; } InlineTree* caller_tree() const { return _caller_tree; }
InlineTree* callee_at(int bci, ciMethod* m) const; InlineTree* callee_at(int bci, ciMethod* m) const;
int inline_level() const { return stack_depth(); } int inline_level() const { return stack_depth(); }
int stack_depth() const { return _caller_jvms ? _caller_jvms->depth() : 0; } int stack_depth() const { return _caller_jvms ? _caller_jvms->depth() : 0; }
const char* msg() const { return _msg; }
void set_msg(const char* msg) { _msg = msg; }
public: public:
static const char* check_can_parse(ciMethod* callee); static const char* check_can_parse(ciMethod* callee);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册