1.1 --- a/src/share/vm/code/nmethod.cpp Thu Aug 22 09:39:54 2013 -0700 1.2 +++ b/src/share/vm/code/nmethod.cpp Thu Sep 05 11:04:39 2013 -0700 1.3 @@ -687,6 +687,7 @@ 1.4 code_buffer->copy_values_to(this); 1.5 if (ScavengeRootsInCode && detect_scavenge_root_oops()) { 1.6 CodeCache::add_scavenge_root_nmethod(this); 1.7 + Universe::heap()->register_nmethod(this); 1.8 } 1.9 debug_only(verify_scavenge_root_oops()); 1.10 CodeCache::commit(this); 1.11 @@ -881,6 +882,7 @@ 1.12 dependencies->copy_to(this); 1.13 if (ScavengeRootsInCode && detect_scavenge_root_oops()) { 1.14 CodeCache::add_scavenge_root_nmethod(this); 1.15 + Universe::heap()->register_nmethod(this); 1.16 } 1.17 debug_only(verify_scavenge_root_oops()); 1.18 1.19 @@ -1300,6 +1302,13 @@ 1.20 methodHandle the_method(method()); 1.21 No_Safepoint_Verifier nsv; 1.22 1.23 + // during patching, depending on the nmethod state we must notify the GC that 1.24 + // code has been unloaded, unregistering it. We cannot do this right while 1.25 + // holding the Patching_lock because we need to use the CodeCache_lock. This 1.26 + // would be prone to deadlocks. 1.27 + // This flag is used to remember whether we need to later lock and unregister. 1.28 + bool nmethod_needs_unregister = false; 1.29 + 1.30 { 1.31 // invalidate osr nmethod before acquiring the patching lock since 1.32 // they both acquire leaf locks and we don't want a deadlock. 1.33 @@ -1332,6 +1341,13 @@ 1.34 inc_decompile_count(); 1.35 } 1.36 1.37 + // If the state is becoming a zombie, signal to unregister the nmethod with 1.38 + // the heap. 1.39 + // This nmethod may have already been unloaded during a full GC. 1.40 + if ((state == zombie) && !is_unloaded()) { 1.41 + nmethod_needs_unregister = true; 1.42 + } 1.43 + 1.44 // Change state 1.45 _state = state; 1.46 1.47 @@ -1367,6 +1383,9 @@ 1.48 // safepoint can sneak in, otherwise the oops used by the 1.49 // dependency logic could have become stale. 1.50 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); 1.51 + if (nmethod_needs_unregister) { 1.52 + Universe::heap()->unregister_nmethod(this); 1.53 + } 1.54 flush_dependencies(NULL); 1.55 } 1.56 1.57 @@ -1817,21 +1836,10 @@ 1.58 if (_method != NULL) f(_method); 1.59 } 1.60 1.61 - 1.62 -// This method is called twice during GC -- once while 1.63 -// tracing the "active" nmethods on thread stacks during 1.64 -// the (strong) marking phase, and then again when walking 1.65 -// the code cache contents during the weak roots processing 1.66 -// phase. The two uses are distinguished by means of the 1.67 -// 'do_strong_roots_only' flag, which is true in the first 1.68 -// case. We want to walk the weak roots in the nmethod 1.69 -// only in the second case. The weak roots in the nmethod 1.70 -// are the oops in the ExceptionCache and the InlineCache 1.71 -// oops. 1.72 -void nmethod::oops_do(OopClosure* f, bool do_strong_roots_only) { 1.73 +void nmethod::oops_do(OopClosure* f, bool allow_zombie) { 1.74 // make sure the oops ready to receive visitors 1.75 - assert(!is_zombie() && !is_unloaded(), 1.76 - "should not call follow on zombie or unloaded nmethod"); 1.77 + assert(allow_zombie || !is_zombie(), "should not call follow on zombie nmethod"); 1.78 + assert(!is_unloaded(), "should not call follow on unloaded nmethod"); 1.79 1.80 // If the method is not entrant or zombie then a JMP is plastered over the 1.81 // first few bytes. If an oop in the old code was there, that oop