# HG changeset patch # User never # Date 1281656303 25200 # Node ID 9e96dde307e93c00d7ec39f3916f16d6a257d217 # Parent 95ea4d66089a35a0ad835fe06ead108a8b15d148 6974176: ShouldNotReachHere, instanceKlass.cpp:1426 Reviewed-by: kvn, twisti diff -r 95ea4d66089a -r 9e96dde307e9 hotspot/src/share/vm/code/nmethod.cpp --- a/hotspot/src/share/vm/code/nmethod.cpp Wed Aug 11 10:48:20 2010 -0700 +++ b/hotspot/src/share/vm/code/nmethod.cpp Thu Aug 12 16:38:23 2010 -0700 @@ -433,6 +433,10 @@ _unload_reported = false; // jvmti state NOT_PRODUCT(_has_debug_info = false); +#ifdef ASSERT + _oops_are_stale = false; +#endif + _oops_do_mark_link = NULL; _jmethod_id = NULL; _osr_link = NULL; @@ -1230,11 +1234,10 @@ bool nmethod::make_not_entrant_or_zombie(unsigned int state) { assert(state == zombie || state == not_entrant, "must be zombie or not_entrant"); - bool was_alive = false; - // Make sure neither the nmethod nor the method is flushed in case of a safepoint in code below. nmethodLocker nml(this); methodHandle the_method(method()); + No_Safepoint_Verifier nsv; { // If the method is already zombie there is nothing to do @@ -1303,13 +1306,27 @@ // state will be flushed later when the transition to zombie // happens or they get unloaded. if (state == zombie) { - // zombie only - if a JVMTI agent has enabled the CompiledMethodUnload event - // and it hasn't already been reported for this nmethod then report it now. - // (the event may have been reported earilier if the GC marked it for unloading). - post_compiled_method_unload(); + { + // Flushing dependecies must be done before any possible + // safepoint can sneak in, otherwise the oops used by the + // dependency logic could have become stale. + MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); + flush_dependencies(NULL); + } - MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); - flush_dependencies(NULL); + { + // zombie only - if a JVMTI agent has enabled the CompiledMethodUnload event + // and it hasn't already been reported for this nmethod then report it now. + // (the event may have been reported earilier if the GC marked it for unloading). + Pause_No_Safepoint_Verifier pnsv(&nsv); + post_compiled_method_unload(); + } + +#ifdef ASSERT + // It's no longer safe to access the oops section since zombie + // nmethods aren't scanned for GC. + _oops_are_stale = true; +#endif } else { assert(state == not_entrant, "other cases may need to be handled differently"); } diff -r 95ea4d66089a -r 9e96dde307e9 hotspot/src/share/vm/code/nmethod.hpp --- a/hotspot/src/share/vm/code/nmethod.hpp Wed Aug 11 10:48:20 2010 -0700 +++ b/hotspot/src/share/vm/code/nmethod.hpp Thu Aug 12 16:38:23 2010 -0700 @@ -177,6 +177,10 @@ // Protected by Patching_lock unsigned char _state; // {alive, not_entrant, zombie, unloaded) +#ifdef ASSERT + bool _oops_are_stale; // indicates that it's no longer safe to access oops section +#endif + enum { alive = 0, not_entrant = 1, // uncommon trap has happened but activations may still exist zombie = 2, @@ -434,6 +438,7 @@ oop* oop_addr_at(int index) const { // for GC // relocation indexes are biased by 1 (because 0 is reserved) assert(index > 0 && index <= oops_size(), "must be a valid non-zero index"); + assert(!_oops_are_stale, "oops are stale"); return &oops_begin()[index - 1]; }