mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8173338: C2: continuous CallSite relinkage eventually disables compilation for a method
Reviewed-by: jrose, dlong, kvn
This commit is contained in:
parent
81e25c58fb
commit
95ff3ccdb4
4 changed files with 19 additions and 3 deletions
|
@ -101,6 +101,7 @@ ciEnv::ciEnv(CompileTask* task, int system_dictionary_modification_counter)
|
||||||
_debug_info = NULL;
|
_debug_info = NULL;
|
||||||
_dependencies = NULL;
|
_dependencies = NULL;
|
||||||
_failure_reason = NULL;
|
_failure_reason = NULL;
|
||||||
|
_inc_decompile_count_on_failure = true;
|
||||||
_compilable = MethodCompilable;
|
_compilable = MethodCompilable;
|
||||||
_break_at_compile = false;
|
_break_at_compile = false;
|
||||||
_compiler_data = NULL;
|
_compiler_data = NULL;
|
||||||
|
@ -161,6 +162,7 @@ ciEnv::ciEnv(Arena* arena) : _ciEnv_arena(mtCompiler) {
|
||||||
_debug_info = NULL;
|
_debug_info = NULL;
|
||||||
_dependencies = NULL;
|
_dependencies = NULL;
|
||||||
_failure_reason = NULL;
|
_failure_reason = NULL;
|
||||||
|
_inc_decompile_count_on_failure = true;
|
||||||
_compilable = MethodCompilable_never;
|
_compilable = MethodCompilable_never;
|
||||||
_break_at_compile = false;
|
_break_at_compile = false;
|
||||||
_compiler_data = NULL;
|
_compiler_data = NULL;
|
||||||
|
@ -902,7 +904,12 @@ void ciEnv::validate_compile_task_dependencies(ciMethod* target) {
|
||||||
if (deps.is_klass_type()) continue; // skip klass dependencies
|
if (deps.is_klass_type()) continue; // skip klass dependencies
|
||||||
Klass* witness = deps.check_dependency();
|
Klass* witness = deps.check_dependency();
|
||||||
if (witness != NULL) {
|
if (witness != NULL) {
|
||||||
record_failure("invalid non-klass dependency");
|
if (deps.type() == Dependencies::call_site_target_value) {
|
||||||
|
_inc_decompile_count_on_failure = false;
|
||||||
|
record_failure("call site target change");
|
||||||
|
} else {
|
||||||
|
record_failure("invalid non-klass dependency");
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1017,7 +1024,7 @@ void ciEnv::register_method(ciMethod* target,
|
||||||
if (failing()) {
|
if (failing()) {
|
||||||
// While not a true deoptimization, it is a preemptive decompile.
|
// While not a true deoptimization, it is a preemptive decompile.
|
||||||
MethodData* mdo = method()->method_data();
|
MethodData* mdo = method()->method_data();
|
||||||
if (mdo != NULL) {
|
if (mdo != NULL && _inc_decompile_count_on_failure) {
|
||||||
mdo->inc_decompile_count();
|
mdo->inc_decompile_count();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,7 @@ private:
|
||||||
DebugInformationRecorder* _debug_info;
|
DebugInformationRecorder* _debug_info;
|
||||||
Dependencies* _dependencies;
|
Dependencies* _dependencies;
|
||||||
const char* _failure_reason;
|
const char* _failure_reason;
|
||||||
|
bool _inc_decompile_count_on_failure;
|
||||||
int _compilable;
|
int _compilable;
|
||||||
bool _break_at_compile;
|
bool _break_at_compile;
|
||||||
int _num_inlined_bytecodes;
|
int _num_inlined_bytecodes;
|
||||||
|
|
|
@ -1211,7 +1211,7 @@ void CodeCache::make_marked_nmethods_not_entrant() {
|
||||||
CompiledMethodIterator iter;
|
CompiledMethodIterator iter;
|
||||||
while(iter.next_alive()) {
|
while(iter.next_alive()) {
|
||||||
CompiledMethod* nm = iter.method();
|
CompiledMethod* nm = iter.method();
|
||||||
if (nm->is_marked_for_deoptimization()) {
|
if (nm->is_marked_for_deoptimization() && !nm->is_not_entrant()) {
|
||||||
nm->make_not_entrant();
|
nm->make_not_entrant();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1146,6 +1146,14 @@ bool nmethod::make_not_entrant_or_zombie(unsigned int state) {
|
||||||
assert(state == zombie || state == not_entrant, "must be zombie or not_entrant");
|
assert(state == zombie || state == not_entrant, "must be zombie or not_entrant");
|
||||||
assert(!is_zombie(), "should not already be a zombie");
|
assert(!is_zombie(), "should not already be a zombie");
|
||||||
|
|
||||||
|
if (_state == state) {
|
||||||
|
// Avoid taking the lock if already in required state.
|
||||||
|
// This is safe from races because the state is an end-state,
|
||||||
|
// which the nmethod cannot back out of once entered.
|
||||||
|
// No need for fencing either.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Make sure neither the nmethod nor the method is flushed in case of a safepoint in code below.
|
// Make sure neither the nmethod nor the method is flushed in case of a safepoint in code below.
|
||||||
nmethodLocker nml(this);
|
nmethodLocker nml(this);
|
||||||
methodHandle the_method(method());
|
methodHandle the_method(method());
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue