src/share/vm/code/nmethod.cpp

changeset 6462
e2722a66aba7
parent 6461
bdd155477289
parent 5548
5888334c9c24
child 6472
2b8e28fdf503
     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

mercurial