Mercurial > hg > graal-jvmci-8
changeset 23426:682119c4c32e
8058737: CodeCache::find_blob fails with 'unsafe access to zombie method'
Summary: Remove active ICStubs from zombie nmethods
Reviewed-by: kvn, iveresov
author | thartmann |
---|---|
date | Thu, 08 Oct 2015 09:37:23 +0200 |
parents | aa97f9321b9c |
children | c1950f51ed60 |
files | src/share/vm/code/compiledIC.cpp src/share/vm/code/compiledIC.hpp src/share/vm/code/nmethod.cpp src/share/vm/code/nmethod.hpp src/share/vm/runtime/sweeper.cpp |
diffstat | 5 files changed, 27 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- 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 {
--- 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.
--- 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() {
--- 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());
--- 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++;