# HG changeset patch # User thartmann # Date 1411972851 -7200 # Node ID 19021f626ad24d1f4e1d62c6481981a06aadd030 # Parent 8f2c7a83220fde6cb67d1d69eaf03a3f51769176 8058737: CodeCache::find_blob fails with 'unsafe access to zombie method' Summary: Remove active ICStubs from zombie nmethods Reviewed-by: kvn, iveresov diff -r 8f2c7a83220f -r 19021f626ad2 hotspot/src/share/vm/code/compiledIC.cpp --- a/hotspot/src/share/vm/code/compiledIC.cpp Fri Sep 26 20:09:02 2014 -0700 +++ b/hotspot/src/share/vm/code/compiledIC.cpp Mon Sep 29 08:40:51 2014 +0200 @@ -155,6 +155,14 @@ return _ic_call->destination(); } +// Clears the IC stub if the compiled IC is in transition state +void CompiledIC::clear_ic_stub() { + if (is_in_transition_state()) { + ICStub* stub = ICStub_from_destination_address(stub_address()); + stub->clear(); + } +} + //----------------------------------------------------------------------------- // High-level access to an inline cache. Guaranteed to be MT-safe. @@ -333,10 +341,7 @@ if (safe_transition) { // Kill any leftover stub we might have too - if (is_in_transition_state()) { - ICStub* old_stub = ICStub_from_destination_address(stub_address()); - old_stub->clear(); - } + clear_ic_stub(); if (is_optimized()) { set_ic_destination(entry); } else { diff -r 8f2c7a83220f -r 19021f626ad2 hotspot/src/share/vm/code/compiledIC.hpp --- a/hotspot/src/share/vm/code/compiledIC.hpp Fri Sep 26 20:09:02 2014 -0700 +++ b/hotspot/src/share/vm/code/compiledIC.hpp Mon Sep 29 08:40:51 2014 +0200 @@ -216,6 +216,7 @@ // void set_to_clean(); // Can only be called during a safepoint operation void set_to_monomorphic(CompiledICInfo& info); + void clear_ic_stub(); // Returns true if successful and false otherwise. The call can fail if memory // allocation in the code cache fails. diff -r 8f2c7a83220f -r 19021f626ad2 hotspot/src/share/vm/code/nmethod.cpp --- a/hotspot/src/share/vm/code/nmethod.cpp Fri Sep 26 20:09:02 2014 -0700 +++ b/hotspot/src/share/vm/code/nmethod.cpp Mon Sep 29 08:40:51 2014 +0200 @@ -1130,6 +1130,18 @@ } } +// Clear ICStubs of all compiled ICs +void nmethod::clear_ic_stubs() { + assert_locked_or_safepoint(CompiledIC_lock); + RelocIterator iter(this); + while(iter.next()) { + if (iter.type() == relocInfo::virtual_call_type) { + CompiledIC* ic = CompiledIC_at(&iter); + ic->clear_ic_stub(); + } + } +} + void nmethod::cleanup_inline_caches() { diff -r 8f2c7a83220f -r 19021f626ad2 hotspot/src/share/vm/code/nmethod.hpp --- a/hotspot/src/share/vm/code/nmethod.hpp Fri Sep 26 20:09:02 2014 -0700 +++ b/hotspot/src/share/vm/code/nmethod.hpp Mon Sep 29 08:40:51 2014 +0200 @@ -577,6 +577,7 @@ // Inline cache support void clear_inline_caches(); + void clear_ic_stubs(); void cleanup_inline_caches(); bool inlinecache_check_contains(address addr) const { return (addr >= code_begin() && addr < verified_entry_point()); diff -r 8f2c7a83220f -r 19021f626ad2 hotspot/src/share/vm/runtime/sweeper.cpp --- a/hotspot/src/share/vm/runtime/sweeper.cpp Fri Sep 26 20:09:02 2014 -0700 +++ b/hotspot/src/share/vm/runtime/sweeper.cpp Mon Sep 29 08:40:51 2014 +0200 @@ -543,6 +543,10 @@ if (PrintMethodFlushing && Verbose) { tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (not entrant) being made zombie", nm->compile_id(), nm); } + // Clear ICStubs to prevent back patching stubs of zombie or unloaded + // nmethods during the next safepoint (see ICStub::finalize). + MutexLocker cl(CompiledIC_lock); + nm->clear_ic_stubs(); // Code cache state change is tracked in make_zombie() nm->make_zombie(); _zombified_count++;