diff -r 36d1d483d5d6 -r da91efe96a93 src/share/vm/runtime/sweeper.cpp --- a/src/share/vm/runtime/sweeper.cpp Fri Aug 31 16:39:35 2012 -0700 +++ b/src/share/vm/runtime/sweeper.cpp Sat Sep 01 13:25:18 2012 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,10 +24,12 @@ #include "precompiled.hpp" #include "code/codeCache.hpp" +#include "code/compiledIC.hpp" +#include "code/icBuffer.hpp" #include "code/nmethod.hpp" #include "compiler/compileBroker.hpp" #include "memory/resourceArea.hpp" -#include "oops/methodOop.hpp" +#include "oops/method.hpp" #include "runtime/atomic.hpp" #include "runtime/compilationPolicy.hpp" #include "runtime/mutexLocker.hpp" @@ -324,13 +326,32 @@ public: NMethodMarker(nmethod* nm) { _thread = CompilerThread::current(); + if (!nm->is_zombie() && !nm->is_unloaded()) { + // Only expose live nmethods for scanning _thread->set_scanned_nmethod(nm); } + } ~NMethodMarker() { _thread->set_scanned_nmethod(NULL); } }; +void NMethodSweeper::release_nmethod(nmethod *nm) { + // Clean up any CompiledICHolders + { + ResourceMark rm; + MutexLocker ml_patch(CompiledIC_lock); + RelocIterator iter(nm); + while (iter.next()) { + if (iter.type() == relocInfo::virtual_call_type) { + CompiledIC::cleanup_call_site(iter.virtual_call_reloc()); + } + } + } + + MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); + nm->flush(); +} void NMethodSweeper::process_nmethod(nmethod *nm) { assert(!CodeCache_lock->owned_by_self(), "just checking"); @@ -365,8 +386,7 @@ if (PrintMethodFlushing && Verbose) { tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (marked for reclamation) being flushed", nm->compile_id(), nm); } - MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); - nm->flush(); + release_nmethod(nm); } else { if (PrintMethodFlushing && Verbose) { tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (zombie) being marked for reclamation", nm->compile_id(), nm); @@ -400,10 +420,9 @@ if (PrintMethodFlushing && Verbose) tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (unloaded) being made zombie", nm->compile_id(), nm); if (nm->is_osr_method()) { + SWEEP(nm); // No inline caches will ever point to osr methods, so we can just remove it - MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); - SWEEP(nm); - nm->flush(); + release_nmethod(nm); } else { nm->make_zombie(); _rescan = true; @@ -434,8 +453,8 @@ // saving the old code in a list in the CodeCache. Then // execution resumes. If a method so marked is not called by the second sweeper // stack traversal after the current one, the nmethod will be marked non-entrant and -// got rid of by normal sweeping. If the method is called, the methodOop's -// _code field is restored and the methodOop/nmethod +// got rid of by normal sweeping. If the method is called, the Method*'s +// _code field is restored and the Method*/nmethod // go back to their normal state. void NMethodSweeper::handle_full_code_cache(bool is_full) { // Only the first one to notice can advise us to start early cleaning