src/share/vm/runtime/sweeper.cpp

changeset 4037
da91efe96a93
parent 3900
d2a62e0f25eb
child 5038
0cfa93c2fcc4
     1.1 --- a/src/share/vm/runtime/sweeper.cpp	Fri Aug 31 16:39:35 2012 -0700
     1.2 +++ b/src/share/vm/runtime/sweeper.cpp	Sat Sep 01 13:25:18 2012 -0400
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
     1.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8   *
     1.9   * This code is free software; you can redistribute it and/or modify it
    1.10 @@ -24,10 +24,12 @@
    1.11  
    1.12  #include "precompiled.hpp"
    1.13  #include "code/codeCache.hpp"
    1.14 +#include "code/compiledIC.hpp"
    1.15 +#include "code/icBuffer.hpp"
    1.16  #include "code/nmethod.hpp"
    1.17  #include "compiler/compileBroker.hpp"
    1.18  #include "memory/resourceArea.hpp"
    1.19 -#include "oops/methodOop.hpp"
    1.20 +#include "oops/method.hpp"
    1.21  #include "runtime/atomic.hpp"
    1.22  #include "runtime/compilationPolicy.hpp"
    1.23  #include "runtime/mutexLocker.hpp"
    1.24 @@ -324,13 +326,32 @@
    1.25   public:
    1.26    NMethodMarker(nmethod* nm) {
    1.27      _thread = CompilerThread::current();
    1.28 +    if (!nm->is_zombie() && !nm->is_unloaded()) {
    1.29 +      // Only expose live nmethods for scanning
    1.30      _thread->set_scanned_nmethod(nm);
    1.31    }
    1.32 +  }
    1.33    ~NMethodMarker() {
    1.34      _thread->set_scanned_nmethod(NULL);
    1.35    }
    1.36  };
    1.37  
    1.38 +void NMethodSweeper::release_nmethod(nmethod *nm) {
    1.39 +  // Clean up any CompiledICHolders
    1.40 +  {
    1.41 +    ResourceMark rm;
    1.42 +    MutexLocker ml_patch(CompiledIC_lock);
    1.43 +    RelocIterator iter(nm);
    1.44 +    while (iter.next()) {
    1.45 +      if (iter.type() == relocInfo::virtual_call_type) {
    1.46 +        CompiledIC::cleanup_call_site(iter.virtual_call_reloc());
    1.47 +      }
    1.48 +    }
    1.49 +  }
    1.50 +
    1.51 +  MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
    1.52 +  nm->flush();
    1.53 +}
    1.54  
    1.55  void NMethodSweeper::process_nmethod(nmethod *nm) {
    1.56    assert(!CodeCache_lock->owned_by_self(), "just checking");
    1.57 @@ -365,8 +386,7 @@
    1.58        if (PrintMethodFlushing && Verbose) {
    1.59          tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (marked for reclamation) being flushed", nm->compile_id(), nm);
    1.60        }
    1.61 -      MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
    1.62 -      nm->flush();
    1.63 +      release_nmethod(nm);
    1.64      } else {
    1.65        if (PrintMethodFlushing && Verbose) {
    1.66          tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (zombie) being marked for reclamation", nm->compile_id(), nm);
    1.67 @@ -400,10 +420,9 @@
    1.68      if (PrintMethodFlushing && Verbose)
    1.69        tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (unloaded) being made zombie", nm->compile_id(), nm);
    1.70      if (nm->is_osr_method()) {
    1.71 +      SWEEP(nm);
    1.72        // No inline caches will ever point to osr methods, so we can just remove it
    1.73 -      MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
    1.74 -      SWEEP(nm);
    1.75 -      nm->flush();
    1.76 +      release_nmethod(nm);
    1.77      } else {
    1.78        nm->make_zombie();
    1.79        _rescan = true;
    1.80 @@ -434,8 +453,8 @@
    1.81  // saving the old code in a list in the CodeCache. Then
    1.82  // execution resumes. If a method so marked is not called by the second sweeper
    1.83  // stack traversal after the current one, the nmethod will be marked non-entrant and
    1.84 -// got rid of by normal sweeping. If the method is called, the methodOop's
    1.85 -// _code field is restored and the methodOop/nmethod
    1.86 +// got rid of by normal sweeping. If the method is called, the Method*'s
    1.87 +// _code field is restored and the Method*/nmethod
    1.88  // go back to their normal state.
    1.89  void NMethodSweeper::handle_full_code_cache(bool is_full) {
    1.90    // Only the first one to notice can advise us to start early cleaning

mercurial