# HG changeset patch # User thartmann # Date 1444289843 -7200 # Node ID 682119c4c32e176f3009c6d721fe0552112bb87e # Parent aa97f9321b9cb40b67a4607aa448d0c3491ef401 8058737: CodeCache::find_blob fails with 'unsafe access to zombie method' Summary: Remove active ICStubs from zombie nmethods Reviewed-by: kvn, iveresov diff -r aa97f9321b9c -r 682119c4c32e src/share/vm/code/compiledIC.cpp --- a/src/share/vm/code/compiledIC.cpp Tue Oct 06 12:18:17 2015 +0200 +++ b/src/share/vm/code/compiledIC.cpp Thu Oct 08 09:37:23 2015 +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 aa97f9321b9c -r 682119c4c32e src/share/vm/code/compiledIC.hpp --- a/src/share/vm/code/compiledIC.hpp Tue Oct 06 12:18:17 2015 +0200 +++ b/src/share/vm/code/compiledIC.hpp Thu Oct 08 09:37:23 2015 +0200 @@ -230,6 +230,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 aa97f9321b9c -r 682119c4c32e src/share/vm/code/nmethod.cpp --- a/src/share/vm/code/nmethod.cpp Tue Oct 06 12:18:17 2015 +0200 +++ b/src/share/vm/code/nmethod.cpp Thu Oct 08 09:37:23 2015 +0200 @@ -1148,6 +1148,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 aa97f9321b9c -r 682119c4c32e src/share/vm/code/nmethod.hpp --- a/src/share/vm/code/nmethod.hpp Tue Oct 06 12:18:17 2015 +0200 +++ b/src/share/vm/code/nmethod.hpp Thu Oct 08 09:37:23 2015 +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 aa97f9321b9c -r 682119c4c32e src/share/vm/runtime/sweeper.cpp --- a/src/share/vm/runtime/sweeper.cpp Tue Oct 06 12:18:17 2015 +0200 +++ b/src/share/vm/runtime/sweeper.cpp Thu Oct 08 09:37:23 2015 +0200 @@ -542,6 +542,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++;