8212996: Use AS_NO_KEEPALIVE when accessing dead java.lang.invoke.CallSites during nmethod unloading
Reviewed-by: coleenp, pliden
--- a/src/hotspot/share/classfile/javaClasses.cpp Mon Nov 05 12:36:23 2018 +0100
+++ b/src/hotspot/share/classfile/javaClasses.cpp Mon Nov 05 12:36:23 2018 +0100
@@ -3732,10 +3732,10 @@
}
#endif
-oop java_lang_invoke_CallSite::context(oop call_site) {
+oop java_lang_invoke_CallSite::context_no_keepalive(oop call_site) {
assert(java_lang_invoke_CallSite::is_instance(call_site), "");
- oop dep_oop = call_site->obj_field(_context_offset);
+ oop dep_oop = call_site->obj_field_access<AS_NO_KEEPALIVE>(_context_offset);
return dep_oop;
}
--- a/src/hotspot/share/classfile/javaClasses.hpp Mon Nov 05 12:36:23 2018 +0100
+++ b/src/hotspot/share/classfile/javaClasses.hpp Mon Nov 05 12:36:23 2018 +0100
@@ -1186,7 +1186,7 @@
static void set_target( oop site, oop target);
static void set_target_volatile( oop site, oop target);
- static oop context(oop site);
+ static oop context_no_keepalive(oop site);
// Testers
static bool is_subclass(Klass* klass) {
--- a/src/hotspot/share/code/nmethod.cpp Mon Nov 05 12:36:23 2018 +0100
+++ b/src/hotspot/share/code/nmethod.cpp Mon Nov 05 12:36:23 2018 +0100
@@ -42,6 +42,7 @@
#include "logging/logStream.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/resourceArea.hpp"
+#include "oops/access.inline.hpp"
#include "oops/method.inline.hpp"
#include "oops/methodData.hpp"
#include "oops/oop.inline.hpp"
@@ -1334,6 +1335,13 @@
CodeCache::free(this);
}
+oop nmethod::oop_at(int index) const {
+ if (index == 0) {
+ return NULL;
+ }
+ return NativeAccess<AS_NO_KEEPALIVE>::oop_load(oop_addr_at(index));
+}
+
//
// Notify all classes this nmethod is dependent on that it is no
// longer dependent. This should only be called in two situations.
--- a/src/hotspot/share/code/nmethod.hpp Mon Nov 05 12:36:23 2018 +0100
+++ b/src/hotspot/share/code/nmethod.hpp Mon Nov 05 12:36:23 2018 +0100
@@ -365,7 +365,7 @@
// Support for oops in scopes and relocs:
// Note: index 0 is reserved for null.
- oop oop_at(int index) const { return index == 0 ? (oop) NULL: *oop_addr_at(index); }
+ oop oop_at(int index) const;
oop* oop_addr_at(int index) const { // for GC
// relocation indexes are biased by 1 (because 0 is reserved)
assert(index > 0 && index <= oops_count(), "must be a valid non-zero index");
--- a/src/hotspot/share/prims/methodHandles.cpp Mon Nov 05 12:36:23 2018 +0100
+++ b/src/hotspot/share/prims/methodHandles.cpp Mon Nov 05 12:36:23 2018 +0100
@@ -1075,7 +1075,7 @@
void MethodHandles::add_dependent_nmethod(oop call_site, nmethod* nm) {
assert_locked_or_safepoint(CodeCache_lock);
- oop context = java_lang_invoke_CallSite::context(call_site);
+ oop context = java_lang_invoke_CallSite::context_no_keepalive(call_site);
DependencyContext deps = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context);
// Try to purge stale entries on updates.
// Since GC doesn't clean dependency contexts rooted at CallSiteContext objects,
@@ -1088,7 +1088,7 @@
void MethodHandles::remove_dependent_nmethod(oop call_site, nmethod* nm) {
assert_locked_or_safepoint(CodeCache_lock);
- oop context = java_lang_invoke_CallSite::context(call_site);
+ oop context = java_lang_invoke_CallSite::context_no_keepalive(call_site);
DependencyContext deps = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context);
deps.remove_dependent_nmethod(nm, /*expunge_stale_entries=*/safe_to_expunge());
}
@@ -1102,7 +1102,7 @@
NoSafepointVerifier nsv;
MutexLockerEx mu2(CodeCache_lock, Mutex::_no_safepoint_check_flag);
- oop context = java_lang_invoke_CallSite::context(call_site());
+ oop context = java_lang_invoke_CallSite::context_no_keepalive(call_site());
DependencyContext deps = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context);
marked = deps.mark_dependent_nmethods(changes);
}