8032463: VirtualDispatch test timeout with DeoptimizeALot

Introduce code aging for warm method detection

Reviewed-by: kvn, twisti
This commit is contained in:
Igor Veresov 2014-05-13 11:32:10 -07:00
parent 5938d3d5b9
commit 54db2c2d61
27 changed files with 283 additions and 69 deletions

View file

@ -744,6 +744,8 @@ int Deoptimization::deoptimize_dependents() {
return 0;
}
Deoptimization::DeoptAction Deoptimization::_unloaded_action
= Deoptimization::Action_reinterpret;
#ifdef COMPILER2
bool Deoptimization::realloc_objects(JavaThread* thread, frame* fr, GrowableArray<ScopeValue*>* objects, TRAPS) {
@ -1185,6 +1187,23 @@ JRT_LEAF(void, Deoptimization::popframe_preserve_args(JavaThread* thread, int by
}
JRT_END
MethodData*
Deoptimization::get_method_data(JavaThread* thread, methodHandle m,
bool create_if_missing) {
Thread* THREAD = thread;
MethodData* mdo = m()->method_data();
if (mdo == NULL && create_if_missing && !HAS_PENDING_EXCEPTION) {
// Build an MDO. Ignore errors like OutOfMemory;
// that simply means we won't have an MDO to update.
Method::build_interpreter_method_data(m, THREAD);
if (HAS_PENDING_EXCEPTION) {
assert((PENDING_EXCEPTION->is_a(SystemDictionary::OutOfMemoryError_klass())), "we expect only an OOM error here");
CLEAR_PENDING_EXCEPTION;
}
mdo = m()->method_data();
}
return mdo;
}
#if defined(COMPILER2) || defined(SHARK)
void Deoptimization::load_class_by_index(constantPoolHandle constant_pool, int index, TRAPS) {
@ -1285,7 +1304,7 @@ JRT_ENTRY(void, Deoptimization::uncommon_trap_inner(JavaThread* thread, jint tra
// Ensure that we can record deopt. history:
// Need MDO to record RTM code generation state.
bool create_if_missing = ProfileTraps RTM_OPT_ONLY( || UseRTMLocking );
bool create_if_missing = ProfileTraps || UseCodeAging RTM_OPT_ONLY( || UseRTMLocking );
MethodData* trap_mdo =
get_method_data(thread, trap_method, create_if_missing);
@ -1421,7 +1440,7 @@ JRT_ENTRY(void, Deoptimization::uncommon_trap_inner(JavaThread* thread, jint tra
//
// The other actions cause immediate removal of the present code.
bool update_trap_state = true;
bool update_trap_state = (reason != Reason_tenured);
bool make_not_entrant = false;
bool make_not_compilable = false;
bool reprofile = false;
@ -1548,7 +1567,6 @@ JRT_ENTRY(void, Deoptimization::uncommon_trap_inner(JavaThread* thread, jint tra
if (make_not_entrant && maybe_prior_recompile && maybe_prior_trap) {
reprofile = true;
}
}
// Take requested actions on the method:
@ -1577,6 +1595,11 @@ JRT_ENTRY(void, Deoptimization::uncommon_trap_inner(JavaThread* thread, jint tra
trap_mdo->atomic_set_rtm_state(ProfileRTM);
}
#endif
// For code aging we count traps separately here, using make_not_entrant()
// as a guard against simultaneous deopts in multiple threads.
if (reason == Reason_tenured && trap_mdo != NULL) {
trap_mdo->inc_tenure_traps();
}
}
if (inc_recompile_count) {
@ -1609,24 +1632,6 @@ JRT_ENTRY(void, Deoptimization::uncommon_trap_inner(JavaThread* thread, jint tra
}
JRT_END
MethodData*
Deoptimization::get_method_data(JavaThread* thread, methodHandle m,
bool create_if_missing) {
Thread* THREAD = thread;
MethodData* mdo = m()->method_data();
if (mdo == NULL && create_if_missing && !HAS_PENDING_EXCEPTION) {
// Build an MDO. Ignore errors like OutOfMemory;
// that simply means we won't have an MDO to update.
Method::build_interpreter_method_data(m, THREAD);
if (HAS_PENDING_EXCEPTION) {
assert((PENDING_EXCEPTION->is_a(SystemDictionary::OutOfMemoryError_klass())), "we expect only an OOM error here");
CLEAR_PENDING_EXCEPTION;
}
mdo = m()->method_data();
}
return mdo;
}
ProfileData*
Deoptimization::query_update_method_data(MethodData* trap_mdo,
int trap_bci,
@ -1813,8 +1818,6 @@ const char* Deoptimization::format_trap_state(char* buf, size_t buflen,
//--------------------------------statics--------------------------------------
Deoptimization::DeoptAction Deoptimization::_unloaded_action
= Deoptimization::Action_reinterpret;
const char* Deoptimization::_trap_reason_name[Reason_LIMIT] = {
// Note: Keep this in sync. with enum DeoptReason.
"none",