提交 e32f7c80 编写于 作者: T thartmann

8075805: Crash while trying to release CompiledICHolder

Summary: Removed nmethod transition to zombie outside of sweeper. Added cleaning of ICs of unloaded nmethods.
Reviewed-by: kvn, iveresov
上级 c5d6f330
......@@ -524,12 +524,15 @@ void CodeCache::gc_epilogue() {
FOR_ALL_ALIVE_BLOBS(cb) {
if (cb->is_nmethod()) {
nmethod *nm = (nmethod*)cb;
assert(!nm->is_unloaded(), "Tautology");
if (needs_cache_clean()) {
nm->cleanup_inline_caches();
if (!nm->is_zombie()) {
if (needs_cache_clean()) {
// Clean ICs of unloaded nmethods as well because they may reference other
// unloaded nmethods that may be flushed earlier in the sweeper cycle.
nm->cleanup_inline_caches();
}
DEBUG_ONLY(nm->verify());
DEBUG_ONLY(nm->verify_oop_relocations());
}
DEBUG_ONLY(nm->verify());
DEBUG_ONLY(nm->verify_oop_relocations());
}
}
set_needs_cache_clean(false);
......@@ -734,27 +737,6 @@ int CodeCache::mark_for_deoptimization(Method* dependee) {
return number_of_marked_CodeBlobs;
}
void CodeCache::make_marked_nmethods_zombies() {
assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint");
FOR_ALL_ALIVE_NMETHODS(nm) {
if (nm->is_marked_for_deoptimization()) {
// If the nmethod has already been made non-entrant and it can be converted
// then zombie it now. Otherwise make it non-entrant and it will eventually
// be zombied when it is no longer seen on the stack. Note that the nmethod
// might be "entrant" and not on the stack and so could be zombied immediately
// but we can't tell because we don't track it on stack until it becomes
// non-entrant.
if (nm->is_not_entrant() && nm->can_not_entrant_be_converted()) {
nm->make_zombie();
} else {
nm->make_not_entrant();
}
}
}
}
void CodeCache::make_marked_nmethods_not_entrant() {
assert_locked_or_safepoint(CodeCache_lock);
FOR_ALL_ALIVE_NMETHODS(nm) {
......
......@@ -179,7 +179,6 @@ class CodeCache : AllStatic {
static void mark_all_nmethods_for_deoptimization();
static int mark_for_deoptimization(Method* dependee);
static void make_marked_nmethods_zombies();
static void make_marked_nmethods_not_entrant();
// tells how many nmethods have dependencies
......
......@@ -343,8 +343,8 @@ void CompiledIC::set_to_clean() {
// Kill any leftover stub we might have too
clear_ic_stub();
if (is_optimized()) {
set_ic_destination(entry);
} else {
set_ic_destination(entry);
} else {
set_ic_destination_and_value(entry, (void*)NULL);
}
} else {
......
......@@ -228,7 +228,7 @@ class CompiledIC: public ResourceObj {
//
// They all takes a TRAP argument, since they can cause a GC if the inline-cache buffer is full.
//
void set_to_clean(); // Can only be called during a safepoint operation
void set_to_clean();
void set_to_monomorphic(CompiledICInfo& info);
void clear_ic_stub();
......
......@@ -1162,7 +1162,6 @@ void nmethod::clear_ic_stubs() {
void nmethod::cleanup_inline_caches() {
assert_locked_or_safepoint(CompiledIC_lock);
// If the method is not entrant or zombie then a JMP is plastered over the
......@@ -1178,7 +1177,8 @@ void nmethod::cleanup_inline_caches() {
// In fact, why are we bothering to look at oops in a non-entrant method??
}
// Find all calls in an nmethod, and clear the ones that points to zombie methods
// Find all calls in an nmethod and clear the ones that point to non-entrant,
// zombie and unloaded nmethods.
ResourceMark rm;
RelocIterator iter(this, low_boundary);
while(iter.next()) {
......@@ -1190,7 +1190,7 @@ void nmethod::cleanup_inline_caches() {
CodeBlob *cb = CodeCache::find_blob_unsafe(ic->ic_destination());
if( cb != NULL && cb->is_nmethod() ) {
nmethod* nm = (nmethod*)cb;
// Clean inline caches pointing to both zombie and not_entrant methods
// Clean inline caches pointing to zombie, non-entrant and unloaded methods
if (!nm->is_in_use() || (nm->method()->code() != nm)) ic->set_to_clean();
}
break;
......@@ -1200,7 +1200,7 @@ void nmethod::cleanup_inline_caches() {
CodeBlob *cb = CodeCache::find_blob_unsafe(csc->destination());
if( cb != NULL && cb->is_nmethod() ) {
nmethod* nm = (nmethod*)cb;
// Clean inline caches pointing to both zombie and not_entrant methods
// Clean inline caches pointing to zombie, non-entrant and unloaded methods
if (!nm->is_in_use() || (nm->method()->code() != nm)) csc->set_to_clean();
}
break;
......@@ -2707,7 +2707,7 @@ void nmethod::verify() {
// Hmm. OSR methods can be deopted but not marked as zombie or not_entrant
// seems odd.
if( is_zombie() || is_not_entrant() )
if (is_zombie() || is_not_entrant() || is_unloaded())
return;
// Make sure all the entry points are correctly aligned for patching.
......
......@@ -3751,7 +3751,7 @@ void VM_RedefineClasses::flush_dependent_code(instanceKlassHandle k_h, TRAPS) {
// Deoptimize all activations depending on marked nmethods
Deoptimization::deoptimize_dependents();
// Make the dependent methods not entrant (in VM_Deoptimize they are made zombies)
// Make the dependent methods not entrant
CodeCache::make_marked_nmethods_not_entrant();
// From now on we know that the dependency information is complete
......
......@@ -106,8 +106,8 @@ void VM_Deoptimize::doit() {
// Deoptimize all activations depending on marked nmethods
Deoptimization::deoptimize_dependents();
// Make the dependent methods zombies
CodeCache::make_marked_nmethods_zombies();
// Make the dependent methods not entrant
CodeCache::make_marked_nmethods_not_entrant();
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册