8058737: CodeCache::find_blob fails with 'unsafe access to zombie method'
Summary: Remove active ICStubs from zombie nmethods
Reviewed-by: kvn, iveresov
--- 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 {
--- 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.
--- 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() {
--- 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());
--- 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++;