提交 d275f121 编写于 作者: I iveresov

7057120: Tiered: Allow C1 to inline methods with loops

Summary: Recompile the enclosing methods without inlining of the method that has OSRed to level 4 or recompile the enclosing method at level 4.
Reviewed-by: kvn, never
上级 6b840423
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "compiler/compileBroker.hpp" #include "compiler/compileBroker.hpp"
#include "interpreter/bytecode.hpp" #include "interpreter/bytecode.hpp"
#include "runtime/sharedRuntime.hpp" #include "runtime/sharedRuntime.hpp"
#include "runtime/compilationPolicy.hpp"
#include "utilities/bitMap.inline.hpp" #include "utilities/bitMap.inline.hpp"
class BlockListBuilder VALUE_OBJ_CLASS_SPEC { class BlockListBuilder VALUE_OBJ_CLASS_SPEC {
...@@ -3395,8 +3396,8 @@ void GraphBuilder::fill_sync_handler(Value lock, BlockBegin* sync_handler, bool ...@@ -3395,8 +3396,8 @@ void GraphBuilder::fill_sync_handler(Value lock, BlockBegin* sync_handler, bool
bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known) { bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known) {
assert(!callee->is_native(), "callee must not be native"); assert(!callee->is_native(), "callee must not be native");
if (count_backedges() && callee->has_loops()) { if (CompilationPolicy::policy()->should_not_inline(compilation()->env(), callee)) {
INLINE_BAILOUT("too complex for tiered"); INLINE_BAILOUT("inlining prohibited by policy");
} }
// first perform tests of things it's not possible to inline // first perform tests of things it's not possible to inline
if (callee->has_exception_handlers() && if (callee->has_exception_handlers() &&
......
...@@ -383,8 +383,10 @@ JRT_ENTRY(void, Runtime1::post_jvmti_exception_throw(JavaThread* thread)) ...@@ -383,8 +383,10 @@ JRT_ENTRY(void, Runtime1::post_jvmti_exception_throw(JavaThread* thread))
} }
JRT_END JRT_END
// This is a helper to allow us to safepoint but allow the outer entry // counter_overflow() is called from within C1-compiled methods. The enclosing method is the method
// to be safepoint free if we need to do an osr // associated with the top activation record. The inlinee (that is possibly included in the enclosing
// method) method oop is passed as an argument. In order to do that it is embedded in the code as
// a constant.
static nmethod* counter_overflow_helper(JavaThread* THREAD, int branch_bci, methodOopDesc* m) { static nmethod* counter_overflow_helper(JavaThread* THREAD, int branch_bci, methodOopDesc* m) {
nmethod* osr_nm = NULL; nmethod* osr_nm = NULL;
methodHandle method(THREAD, m); methodHandle method(THREAD, m);
...@@ -420,7 +422,7 @@ static nmethod* counter_overflow_helper(JavaThread* THREAD, int branch_bci, meth ...@@ -420,7 +422,7 @@ static nmethod* counter_overflow_helper(JavaThread* THREAD, int branch_bci, meth
bci = branch_bci + offset; bci = branch_bci + offset;
} }
osr_nm = CompilationPolicy::policy()->event(enclosing_method, method, branch_bci, bci, level, THREAD); osr_nm = CompilationPolicy::policy()->event(enclosing_method, method, branch_bci, bci, level, nm, THREAD);
return osr_nm; return osr_nm;
} }
......
...@@ -1010,6 +1010,12 @@ int ciMethod::comp_level() { ...@@ -1010,6 +1010,12 @@ int ciMethod::comp_level() {
return 0; return 0;
} }
int ciMethod::highest_osr_comp_level() {
check_is_loaded();
VM_ENTRY_MARK;
return get_methodOop()->highest_osr_comp_level();
}
// ------------------------------------------------------------------ // ------------------------------------------------------------------
// ciMethod::instructions_size // ciMethod::instructions_size
// //
......
...@@ -158,6 +158,7 @@ class ciMethod : public ciObject { ...@@ -158,6 +158,7 @@ class ciMethod : public ciObject {
int interpreter_throwout_count() const { check_is_loaded(); return _interpreter_throwout_count; } int interpreter_throwout_count() const { check_is_loaded(); return _interpreter_throwout_count; }
int comp_level(); int comp_level();
int highest_osr_comp_level();
Bytecodes::Code java_code_at_bci(int bci) { Bytecodes::Code java_code_at_bci(int bci) {
address bcp = code() + bci; address bcp = code() + bci;
......
...@@ -844,7 +844,7 @@ IRT_ENTRY(nmethod*, ...@@ -844,7 +844,7 @@ IRT_ENTRY(nmethod*,
const int branch_bci = branch_bcp != NULL ? method->bci_from(branch_bcp) : InvocationEntryBci; const int branch_bci = branch_bcp != NULL ? method->bci_from(branch_bcp) : InvocationEntryBci;
const int bci = branch_bcp != NULL ? method->bci_from(fr.interpreter_frame_bcp()) : InvocationEntryBci; const int bci = branch_bcp != NULL ? method->bci_from(fr.interpreter_frame_bcp()) : InvocationEntryBci;
nmethod* osr_nm = CompilationPolicy::policy()->event(method, method, branch_bci, bci, CompLevel_none, thread); nmethod* osr_nm = CompilationPolicy::policy()->event(method, method, branch_bci, bci, CompLevel_none, NULL, thread);
if (osr_nm != NULL) { if (osr_nm != NULL) {
// We may need to do on-stack replacement which requires that no // We may need to do on-stack replacement which requires that no
......
...@@ -171,7 +171,7 @@ CompileTask* AdvancedThresholdPolicy::select_task(CompileQueue* compile_queue) { ...@@ -171,7 +171,7 @@ CompileTask* AdvancedThresholdPolicy::select_task(CompileQueue* compile_queue) {
// If a method has been stale for some time, remove it from the queue. // If a method has been stale for some time, remove it from the queue.
if (is_stale(t, TieredCompileTaskTimeout, method) && !is_old(method)) { if (is_stale(t, TieredCompileTaskTimeout, method) && !is_old(method)) {
if (PrintTieredEvents) { if (PrintTieredEvents) {
print_event(KILL, method, method, task->osr_bci(), (CompLevel)task->comp_level()); print_event(REMOVE_FROM_QUEUE, method, method, task->osr_bci(), (CompLevel)task->comp_level());
} }
CompileTaskWrapper ctw(task); // Frees the task CompileTaskWrapper ctw(task); // Frees the task
compile_queue->remove(task); compile_queue->remove(task);
...@@ -192,7 +192,7 @@ CompileTask* AdvancedThresholdPolicy::select_task(CompileQueue* compile_queue) { ...@@ -192,7 +192,7 @@ CompileTask* AdvancedThresholdPolicy::select_task(CompileQueue* compile_queue) {
if (max_task->comp_level() == CompLevel_full_profile && is_method_profiled(max_method)) { if (max_task->comp_level() == CompLevel_full_profile && is_method_profiled(max_method)) {
max_task->set_comp_level(CompLevel_limited_profile); max_task->set_comp_level(CompLevel_limited_profile);
if (PrintTieredEvents) { if (PrintTieredEvents) {
print_event(UPDATE, max_method, max_method, max_task->osr_bci(), (CompLevel)max_task->comp_level()); print_event(UPDATE_IN_QUEUE, max_method, max_method, max_task->osr_bci(), (CompLevel)max_task->comp_level());
} }
} }
...@@ -259,6 +259,17 @@ bool AdvancedThresholdPolicy::should_create_mdo(methodOop method, CompLevel cur_ ...@@ -259,6 +259,17 @@ bool AdvancedThresholdPolicy::should_create_mdo(methodOop method, CompLevel cur_
return false; return false;
} }
// Inlining control: if we're compiling a profiled method with C1 and the callee
// is known to have OSRed in a C2 version, don't inline it.
bool AdvancedThresholdPolicy::should_not_inline(ciEnv* env, ciMethod* callee) {
CompLevel comp_level = (CompLevel)env->comp_level();
if (comp_level == CompLevel_full_profile ||
comp_level == CompLevel_limited_profile) {
return callee->highest_osr_comp_level() == CompLevel_full_optimization;
}
return false;
}
// Create MDO if necessary. // Create MDO if necessary.
void AdvancedThresholdPolicy::create_mdo(methodHandle mh, TRAPS) { void AdvancedThresholdPolicy::create_mdo(methodHandle mh, TRAPS) {
if (mh->is_native() || mh->is_abstract() || mh->is_accessor()) return; if (mh->is_native() || mh->is_abstract() || mh->is_accessor()) return;
...@@ -420,10 +431,9 @@ void AdvancedThresholdPolicy::submit_compile(methodHandle mh, int bci, CompLevel ...@@ -420,10 +431,9 @@ void AdvancedThresholdPolicy::submit_compile(methodHandle mh, int bci, CompLevel
CompileBroker::compile_method(mh, bci, level, mh, hot_count, "tiered", THREAD); CompileBroker::compile_method(mh, bci, level, mh, hot_count, "tiered", THREAD);
} }
// Handle the invocation event. // Handle the invocation event.
void AdvancedThresholdPolicy::method_invocation_event(methodHandle mh, methodHandle imh, void AdvancedThresholdPolicy::method_invocation_event(methodHandle mh, methodHandle imh,
CompLevel level, TRAPS) { CompLevel level, nmethod* nm, TRAPS) {
if (should_create_mdo(mh(), level)) { if (should_create_mdo(mh(), level)) {
create_mdo(mh, THREAD); create_mdo(mh, THREAD);
} }
...@@ -438,32 +448,81 @@ void AdvancedThresholdPolicy::method_invocation_event(methodHandle mh, methodHan ...@@ -438,32 +448,81 @@ void AdvancedThresholdPolicy::method_invocation_event(methodHandle mh, methodHan
// Handle the back branch event. Notice that we can compile the method // Handle the back branch event. Notice that we can compile the method
// with a regular entry from here. // with a regular entry from here.
void AdvancedThresholdPolicy::method_back_branch_event(methodHandle mh, methodHandle imh, void AdvancedThresholdPolicy::method_back_branch_event(methodHandle mh, methodHandle imh,
int bci, CompLevel level, TRAPS) { int bci, CompLevel level, nmethod* nm, TRAPS) {
if (should_create_mdo(mh(), level)) { if (should_create_mdo(mh(), level)) {
create_mdo(mh, THREAD); create_mdo(mh, THREAD);
} }
// Check if MDO should be created for the inlined method
if (should_create_mdo(imh(), level)) {
create_mdo(imh, THREAD);
}
// If the method is already compiling, quickly bail out. if (is_compilation_enabled()) {
if (is_compilation_enabled() && !CompileBroker::compilation_is_in_queue(mh, bci)) { CompLevel next_osr_level = loop_event(imh(), level);
// Use loop event as an opportinity to also check there's been CompLevel max_osr_level = (CompLevel)imh->highest_osr_comp_level();
// enough calls.
CompLevel cur_level = comp_level(mh());
CompLevel next_level = call_event(mh(), cur_level);
CompLevel next_osr_level = loop_event(mh(), level);
if (next_osr_level == CompLevel_limited_profile) { if (next_osr_level == CompLevel_limited_profile) {
next_osr_level = CompLevel_full_profile; // OSRs are supposed to be for very hot methods. next_osr_level = CompLevel_full_profile; // OSRs are supposed to be for very hot methods.
} }
next_level = MAX2(next_level,
next_osr_level < CompLevel_full_optimization ? next_osr_level : cur_level); // At the very least compile the OSR version
bool is_compiling = false; if (!CompileBroker::compilation_is_in_queue(imh, bci)) {
if (next_level != cur_level) { // Check if there's a method like that already
compile(mh, InvocationEntryBci, next_level, THREAD); nmethod* osr_nm = NULL;
is_compiling = true; if (max_osr_level >= next_osr_level) {
// There is an osr method already with the same
// or greater level, check if it has the bci we need
osr_nm = imh->lookup_osr_nmethod_for(bci, next_osr_level, false);
}
if (osr_nm == NULL) {
compile(imh, bci, next_osr_level, THREAD);
}
} }
// Do the OSR version // Use loop event as an opportunity to also check if there's been
if (!is_compiling && next_osr_level != level) { // enough calls.
compile(mh, bci, next_osr_level, THREAD); CompLevel cur_level, next_level;
if (mh() != imh()) { // If there is an enclosing method
guarantee(nm != NULL, "Should have nmethod here");
cur_level = comp_level(mh());
next_level = call_event(mh(), cur_level);
if (max_osr_level == CompLevel_full_optimization) {
// The inlinee OSRed to full opt, we need to modify the enclosing method to avoid deopts
bool make_not_entrant = false;
if (nm->is_osr_method()) {
// This is an osr method, just make it not entrant and recompile later if needed
make_not_entrant = true;
} else {
if (next_level != CompLevel_full_optimization) {
// next_level is not full opt, so we need to recompile the
// enclosing method without the inlinee
cur_level = CompLevel_none;
make_not_entrant = true;
}
}
if (make_not_entrant) {
if (PrintTieredEvents) {
int osr_bci = nm->is_osr_method() ? nm->osr_entry_bci() : InvocationEntryBci;
print_event(MAKE_NOT_ENTRANT, mh(), mh(), osr_bci, level);
}
nm->make_not_entrant();
}
}
if (!CompileBroker::compilation_is_in_queue(mh, InvocationEntryBci)) {
// Fix up next_level if necessary to avoid deopts
if (next_level == CompLevel_limited_profile && max_osr_level == CompLevel_full_profile) {
next_level = CompLevel_full_profile;
}
if (cur_level != next_level) {
compile(mh, InvocationEntryBci, next_level, THREAD);
}
}
} else {
cur_level = comp_level(imh());
next_level = call_event(imh(), cur_level);
if (!CompileBroker::compilation_is_in_queue(imh, bci) && next_level != cur_level) {
compile(imh, InvocationEntryBci, next_level, THREAD);
}
} }
} }
} }
......
...@@ -211,14 +211,16 @@ protected: ...@@ -211,14 +211,16 @@ protected:
virtual void submit_compile(methodHandle mh, int bci, CompLevel level, TRAPS); virtual void submit_compile(methodHandle mh, int bci, CompLevel level, TRAPS);
// event() from SimpleThresholdPolicy would call these. // event() from SimpleThresholdPolicy would call these.
virtual void method_invocation_event(methodHandle method, methodHandle inlinee, virtual void method_invocation_event(methodHandle method, methodHandle inlinee,
CompLevel level, TRAPS); CompLevel level, nmethod* nm, TRAPS);
virtual void method_back_branch_event(methodHandle method, methodHandle inlinee, virtual void method_back_branch_event(methodHandle method, methodHandle inlinee,
int bci, CompLevel level, TRAPS); int bci, CompLevel level, nmethod* nm, TRAPS);
public: public:
AdvancedThresholdPolicy() : _start_time(0) { } AdvancedThresholdPolicy() : _start_time(0) { }
// Select task is called by CompileBroker. We should return a task or NULL. // Select task is called by CompileBroker. We should return a task or NULL.
virtual CompileTask* select_task(CompileQueue* compile_queue); virtual CompileTask* select_task(CompileQueue* compile_queue);
virtual void initialize(); virtual void initialize();
virtual bool should_not_inline(ciEnv* env, ciMethod* callee);
}; };
#endif // TIERED #endif // TIERED
......
...@@ -306,7 +306,7 @@ bool NonTieredCompPolicy::is_mature(methodOop method) { ...@@ -306,7 +306,7 @@ bool NonTieredCompPolicy::is_mature(methodOop method) {
return (current >= initial + target); return (current >= initial + target);
} }
nmethod* NonTieredCompPolicy::event(methodHandle method, methodHandle inlinee, int branch_bci, int bci, CompLevel comp_level, TRAPS) { nmethod* NonTieredCompPolicy::event(methodHandle method, methodHandle inlinee, int branch_bci, int bci, CompLevel comp_level, nmethod* nm, TRAPS) {
assert(comp_level == CompLevel_none, "This should be only called from the interpreter"); assert(comp_level == CompLevel_none, "This should be only called from the interpreter");
NOT_PRODUCT(trace_frequency_counter_overflow(method, branch_bci, bci)); NOT_PRODUCT(trace_frequency_counter_overflow(method, branch_bci, bci));
if (JvmtiExport::can_post_interpreter_events()) { if (JvmtiExport::can_post_interpreter_events()) {
......
...@@ -62,7 +62,7 @@ public: ...@@ -62,7 +62,7 @@ public:
virtual int compiler_count(CompLevel comp_level) = 0; virtual int compiler_count(CompLevel comp_level) = 0;
// main notification entry, return a pointer to an nmethod if the OSR is required, // main notification entry, return a pointer to an nmethod if the OSR is required,
// returns NULL otherwise. // returns NULL otherwise.
virtual nmethod* event(methodHandle method, methodHandle inlinee, int branch_bci, int bci, CompLevel comp_level, TRAPS) = 0; virtual nmethod* event(methodHandle method, methodHandle inlinee, int branch_bci, int bci, CompLevel comp_level, nmethod* nm, TRAPS) = 0;
// safepoint() is called at the end of the safepoint // safepoint() is called at the end of the safepoint
virtual void do_safepoint_work() = 0; virtual void do_safepoint_work() = 0;
// reprofile request // reprofile request
...@@ -80,6 +80,7 @@ public: ...@@ -80,6 +80,7 @@ public:
virtual bool is_mature(methodOop method) = 0; virtual bool is_mature(methodOop method) = 0;
// Do policy initialization // Do policy initialization
virtual void initialize() = 0; virtual void initialize() = 0;
virtual bool should_not_inline(ciEnv* env, ciMethod* method) { return false; }
}; };
// A base class for baseline policies. // A base class for baseline policies.
...@@ -101,7 +102,7 @@ public: ...@@ -101,7 +102,7 @@ public:
virtual bool is_mature(methodOop method); virtual bool is_mature(methodOop method);
virtual void initialize(); virtual void initialize();
virtual CompileTask* select_task(CompileQueue* compile_queue); virtual CompileTask* select_task(CompileQueue* compile_queue);
virtual nmethod* event(methodHandle method, methodHandle inlinee, int branch_bci, int bci, CompLevel comp_level, TRAPS); virtual nmethod* event(methodHandle method, methodHandle inlinee, int branch_bci, int bci, CompLevel comp_level, nmethod* nm, TRAPS);
virtual void method_invocation_event(methodHandle m, TRAPS) = 0; virtual void method_invocation_event(methodHandle m, TRAPS) = 0;
virtual void method_back_branch_event(methodHandle m, int bci, TRAPS) = 0; virtual void method_back_branch_event(methodHandle m, int bci, TRAPS) = 0;
}; };
......
...@@ -50,15 +50,18 @@ void SimpleThresholdPolicy::print_event(EventType type, methodHandle mh, methodH ...@@ -50,15 +50,18 @@ void SimpleThresholdPolicy::print_event(EventType type, methodHandle mh, methodH
case COMPILE: case COMPILE:
tty->print("compile"); tty->print("compile");
break; break;
case KILL: case REMOVE_FROM_QUEUE:
tty->print("kill"); tty->print("remove-from-queue");
break; break;
case UPDATE: case UPDATE_IN_QUEUE:
tty->print("update"); tty->print("update-in-queue");
break; break;
case REPROFILE: case REPROFILE:
tty->print("reprofile"); tty->print("reprofile");
break; break;
case MAKE_NOT_ENTRANT:
tty->print("make-not-entrant");
break;
default: default:
tty->print("unknown"); tty->print("unknown");
} }
...@@ -68,7 +71,6 @@ void SimpleThresholdPolicy::print_event(EventType type, methodHandle mh, methodH ...@@ -68,7 +71,6 @@ void SimpleThresholdPolicy::print_event(EventType type, methodHandle mh, methodH
ResourceMark rm; ResourceMark rm;
char *method_name = mh->name_and_sig_as_C_string(); char *method_name = mh->name_and_sig_as_C_string();
tty->print("[%s", method_name); tty->print("[%s", method_name);
// We can have an inlinee, although currently we don't generate any notifications for the inlined methods.
if (inlinee_event) { if (inlinee_event) {
char *inlinee_name = imh->name_and_sig_as_C_string(); char *inlinee_name = imh->name_and_sig_as_C_string();
tty->print(" [%s]] ", inlinee_name); tty->print(" [%s]] ", inlinee_name);
...@@ -170,7 +172,7 @@ void SimpleThresholdPolicy::reprofile(ScopeDesc* trap_scope, bool is_osr) { ...@@ -170,7 +172,7 @@ void SimpleThresholdPolicy::reprofile(ScopeDesc* trap_scope, bool is_osr) {
} }
nmethod* SimpleThresholdPolicy::event(methodHandle method, methodHandle inlinee, nmethod* SimpleThresholdPolicy::event(methodHandle method, methodHandle inlinee,
int branch_bci, int bci, CompLevel comp_level, TRAPS) { int branch_bci, int bci, CompLevel comp_level, nmethod* nm, TRAPS) {
if (comp_level == CompLevel_none && if (comp_level == CompLevel_none &&
JvmtiExport::can_post_interpreter_events()) { JvmtiExport::can_post_interpreter_events()) {
assert(THREAD->is_Java_thread(), "Should be java thread"); assert(THREAD->is_Java_thread(), "Should be java thread");
...@@ -190,12 +192,13 @@ nmethod* SimpleThresholdPolicy::event(methodHandle method, methodHandle inlinee, ...@@ -190,12 +192,13 @@ nmethod* SimpleThresholdPolicy::event(methodHandle method, methodHandle inlinee,
} }
if (bci == InvocationEntryBci) { if (bci == InvocationEntryBci) {
method_invocation_event(method, inlinee, comp_level, THREAD); method_invocation_event(method, inlinee, comp_level, nm, THREAD);
} else { } else {
method_back_branch_event(method, inlinee, bci, comp_level, THREAD); method_back_branch_event(method, inlinee, bci, comp_level, nm, THREAD);
int highest_level = method->highest_osr_comp_level(); // method == inlinee if the event originated in the main method
int highest_level = inlinee->highest_osr_comp_level();
if (highest_level > comp_level) { if (highest_level > comp_level) {
osr_nm = method->lookup_osr_nmethod_for(bci, highest_level, false); osr_nm = inlinee->lookup_osr_nmethod_for(bci, highest_level, false);
} }
} }
return osr_nm; return osr_nm;
...@@ -360,7 +363,7 @@ CompLevel SimpleThresholdPolicy::loop_event(methodOop method, CompLevel cur_leve ...@@ -360,7 +363,7 @@ CompLevel SimpleThresholdPolicy::loop_event(methodOop method, CompLevel cur_leve
// Handle the invocation event. // Handle the invocation event.
void SimpleThresholdPolicy::method_invocation_event(methodHandle mh, methodHandle imh, void SimpleThresholdPolicy::method_invocation_event(methodHandle mh, methodHandle imh,
CompLevel level, TRAPS) { CompLevel level, nmethod* nm, TRAPS) {
if (is_compilation_enabled() && !CompileBroker::compilation_is_in_queue(mh, InvocationEntryBci)) { if (is_compilation_enabled() && !CompileBroker::compilation_is_in_queue(mh, InvocationEntryBci)) {
CompLevel next_level = call_event(mh(), level); CompLevel next_level = call_event(mh(), level);
if (next_level != level) { if (next_level != level) {
...@@ -372,7 +375,7 @@ void SimpleThresholdPolicy::method_invocation_event(methodHandle mh, methodHandl ...@@ -372,7 +375,7 @@ void SimpleThresholdPolicy::method_invocation_event(methodHandle mh, methodHandl
// Handle the back branch event. Notice that we can compile the method // Handle the back branch event. Notice that we can compile the method
// with a regular entry from here. // with a regular entry from here.
void SimpleThresholdPolicy::method_back_branch_event(methodHandle mh, methodHandle imh, void SimpleThresholdPolicy::method_back_branch_event(methodHandle mh, methodHandle imh,
int bci, CompLevel level, TRAPS) { int bci, CompLevel level, nmethod* nm, TRAPS) {
// If the method is already compiling, quickly bail out. // If the method is already compiling, quickly bail out.
if (is_compilation_enabled() && !CompileBroker::compilation_is_in_queue(mh, bci)) { if (is_compilation_enabled() && !CompileBroker::compilation_is_in_queue(mh, bci)) {
// Use loop event as an opportinity to also check there's been // Use loop event as an opportinity to also check there's been
......
...@@ -62,7 +62,7 @@ protected: ...@@ -62,7 +62,7 @@ protected:
void set_c1_count(int x) { _c1_count = x; } void set_c1_count(int x) { _c1_count = x; }
void set_c2_count(int x) { _c2_count = x; } void set_c2_count(int x) { _c2_count = x; }
enum EventType { CALL, LOOP, COMPILE, KILL, UPDATE, REPROFILE }; enum EventType { CALL, LOOP, COMPILE, REMOVE_FROM_QUEUE, UPDATE_IN_QUEUE, REPROFILE, MAKE_NOT_ENTRANT };
void print_event(EventType type, methodHandle mh, methodHandle imh, int bci, CompLevel level); void print_event(EventType type, methodHandle mh, methodHandle imh, int bci, CompLevel level);
// Print policy-specific information if necessary // Print policy-specific information if necessary
virtual void print_specific(EventType type, methodHandle mh, methodHandle imh, int bci, CompLevel level) { } virtual void print_specific(EventType type, methodHandle mh, methodHandle imh, int bci, CompLevel level) { }
...@@ -88,9 +88,9 @@ protected: ...@@ -88,9 +88,9 @@ protected:
return CompLevel_none; return CompLevel_none;
} }
virtual void method_invocation_event(methodHandle method, methodHandle inlinee, virtual void method_invocation_event(methodHandle method, methodHandle inlinee,
CompLevel level, TRAPS); CompLevel level, nmethod* nm, TRAPS);
virtual void method_back_branch_event(methodHandle method, methodHandle inlinee, virtual void method_back_branch_event(methodHandle method, methodHandle inlinee,
int bci, CompLevel level, TRAPS); int bci, CompLevel level, nmethod* nm, TRAPS);
public: public:
SimpleThresholdPolicy() : _c1_count(0), _c2_count(0) { } SimpleThresholdPolicy() : _c1_count(0), _c2_count(0) { }
virtual int compiler_count(CompLevel comp_level) { virtual int compiler_count(CompLevel comp_level) {
...@@ -101,17 +101,20 @@ public: ...@@ -101,17 +101,20 @@ public:
virtual void do_safepoint_work() { } virtual void do_safepoint_work() { }
virtual void delay_compilation(methodOop method) { } virtual void delay_compilation(methodOop method) { }
virtual void disable_compilation(methodOop method) { } virtual void disable_compilation(methodOop method) { }
// TODO: we should honour reprofiling requests in the future. Currently reprofiling
// would happen but not to the extent we would ideally like.
virtual void reprofile(ScopeDesc* trap_scope, bool is_osr); virtual void reprofile(ScopeDesc* trap_scope, bool is_osr);
virtual nmethod* event(methodHandle method, methodHandle inlinee, virtual nmethod* event(methodHandle method, methodHandle inlinee,
int branch_bci, int bci, CompLevel comp_level, TRAPS); int branch_bci, int bci, CompLevel comp_level, nmethod* nm, TRAPS);
// Select task is called by CompileBroker. We should return a task or NULL. // Select task is called by CompileBroker. We should return a task or NULL.
virtual CompileTask* select_task(CompileQueue* compile_queue); virtual CompileTask* select_task(CompileQueue* compile_queue);
// Tell the runtime if we think a given method is adequately profiled. // Tell the runtime if we think a given method is adequately profiled.
virtual bool is_mature(methodOop method); virtual bool is_mature(methodOop method);
// Initialize: set compiler thread count // Initialize: set compiler thread count
virtual void initialize(); virtual void initialize();
virtual bool should_not_inline(ciEnv* env, ciMethod* callee) {
return (env->comp_level() == CompLevel_limited_profile ||
env->comp_level() == CompLevel_full_profile) &&
callee->has_loops();
}
}; };
#endif // SHARE_VM_RUNTIME_SIMPLETHRESHOLDPOLICY_HPP #endif // SHARE_VM_RUNTIME_SIMPLETHRESHOLDPOLICY_HPP
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册