7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
Reviewed-by: jrose, never
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp Thu Sep 08 10:12:25 2011 +0200
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp Thu Sep 08 05:11:31 2011 -0700
@@ -2707,14 +2707,6 @@
}
}
-oop java_lang_invoke_CallSite::target(oop site) {
- return site->obj_field(_target_offset);
-}
-
-void java_lang_invoke_CallSite::set_target(oop site, oop target) {
- site->obj_field_put(_target_offset, target);
-}
-
// Support for java_security_AccessControlContext
--- a/hotspot/src/share/vm/classfile/javaClasses.hpp Thu Sep 08 10:12:25 2011 +0200
+++ b/hotspot/src/share/vm/classfile/javaClasses.hpp Thu Sep 08 05:11:31 2011 -0700
@@ -771,7 +771,7 @@
ref->obj_field_put(referent_offset, value);
}
static void set_referent_raw(oop ref, oop value) {
- ref->obj_field_raw_put(referent_offset, value);
+ ref->obj_field_put_raw(referent_offset, value);
}
static HeapWord* referent_addr(oop ref) {
return ref->obj_field_addr<HeapWord>(referent_offset);
@@ -783,7 +783,7 @@
ref->obj_field_put(next_offset, value);
}
static void set_next_raw(oop ref, oop value) {
- ref->obj_field_raw_put(next_offset, value);
+ ref->obj_field_put_raw(next_offset, value);
}
static HeapWord* next_addr(oop ref) {
return ref->obj_field_addr<HeapWord>(next_offset);
@@ -795,7 +795,7 @@
ref->obj_field_put(discovered_offset, value);
}
static void set_discovered_raw(oop ref, oop value) {
- ref->obj_field_raw_put(discovered_offset, value);
+ ref->obj_field_put_raw(discovered_offset, value);
}
static HeapWord* discovered_addr(oop ref) {
return ref->obj_field_addr<HeapWord>(discovered_offset);
@@ -1163,14 +1163,17 @@
public:
// Accessors
- static oop target(oop site);
- static void set_target(oop site, oop target);
+ static oop target( oop site) { return site->obj_field( _target_offset); }
+ static void set_target( oop site, oop target) { site->obj_field_put( _target_offset, target); }
+
+ static volatile oop target_volatile(oop site) { return site->obj_field_volatile( _target_offset); }
+ static void set_target_volatile(oop site, oop target) { site->obj_field_put_volatile(_target_offset, target); }
- static oop caller_method(oop site);
- static void set_caller_method(oop site, oop ref);
+ static oop caller_method(oop site);
+ static void set_caller_method(oop site, oop ref);
- static jint caller_bci(oop site);
- static void set_caller_bci(oop site, jint bci);
+ static jint caller_bci(oop site);
+ static void set_caller_bci(oop site, jint bci);
// Testers
static bool is_subclass(klassOop klass) {
--- a/hotspot/src/share/vm/oops/klassOop.hpp Thu Sep 08 10:12:25 2011 +0200
+++ b/hotspot/src/share/vm/oops/klassOop.hpp Thu Sep 08 05:11:31 2011 -0700
@@ -53,8 +53,10 @@
private:
// These have no implementation since klassOop should never be accessed in this fashion
oop obj_field(int offset) const;
+ volatile oop obj_field_volatile(int offset) const;
void obj_field_put(int offset, oop value);
- void obj_field_raw_put(int offset, oop value);
+ void obj_field_put_raw(int offset, oop value);
+ void obj_field_put_volatile(int offset, oop value);
jbyte byte_field(int offset) const;
void byte_field_put(int offset, jbyte contents);
--- a/hotspot/src/share/vm/oops/oop.hpp Thu Sep 08 10:12:25 2011 +0200
+++ b/hotspot/src/share/vm/oops/oop.hpp Thu Sep 08 05:11:31 2011 -0700
@@ -214,8 +214,10 @@
// Access to fields in a instanceOop through these methods.
oop obj_field(int offset) const;
+ volatile oop obj_field_volatile(int offset) const;
void obj_field_put(int offset, oop value);
- void obj_field_raw_put(int offset, oop value);
+ void obj_field_put_raw(int offset, oop value);
+ void obj_field_put_volatile(int offset, oop value);
jbyte byte_field(int offset) const;
void byte_field_put(int offset, jbyte contents);
--- a/hotspot/src/share/vm/oops/oop.inline.hpp Thu Sep 08 10:12:25 2011 +0200
+++ b/hotspot/src/share/vm/oops/oop.inline.hpp Thu Sep 08 05:11:31 2011 -0700
@@ -321,15 +321,25 @@
load_decode_heap_oop(obj_field_addr<narrowOop>(offset)) :
load_decode_heap_oop(obj_field_addr<oop>(offset));
}
+inline volatile oop oopDesc::obj_field_volatile(int offset) const {
+ volatile oop value = obj_field(offset);
+ OrderAccess::acquire();
+ return value;
+}
inline void oopDesc::obj_field_put(int offset, oop value) {
UseCompressedOops ? oop_store(obj_field_addr<narrowOop>(offset), value) :
oop_store(obj_field_addr<oop>(offset), value);
}
-inline void oopDesc::obj_field_raw_put(int offset, oop value) {
+inline void oopDesc::obj_field_put_raw(int offset, oop value) {
UseCompressedOops ?
encode_store_heap_oop(obj_field_addr<narrowOop>(offset), value) :
encode_store_heap_oop(obj_field_addr<oop>(offset), value);
}
+inline void oopDesc::obj_field_put_volatile(int offset, oop value) {
+ OrderAccess::release();
+ obj_field_put(offset, value);
+ OrderAccess::fence();
+}
inline jbyte oopDesc::byte_field(int offset) const { return (jbyte) *byte_field_addr(offset); }
inline void oopDesc::byte_field_put(int offset, jbyte contents) { *byte_field_addr(offset) = (jint) contents; }
--- a/hotspot/src/share/vm/prims/methodHandles.cpp Thu Sep 08 10:12:25 2011 +0200
+++ b/hotspot/src/share/vm/prims/methodHandles.cpp Thu Sep 08 05:11:31 2011 -0700
@@ -3081,6 +3081,30 @@
}
JVM_END
+JVM_ENTRY(void, MHN_setCallSiteTargetNormal(JNIEnv* env, jobject igcls, jobject call_site_jh, jobject target_jh)) {
+ oop call_site = JNIHandles::resolve_non_null(call_site_jh);
+ oop target = JNIHandles::resolve(target_jh);
+ {
+ // Walk all nmethods depending on this call site.
+ MutexLocker mu(Compile_lock, thread);
+ Universe::flush_dependents_on(call_site, target);
+ }
+ java_lang_invoke_CallSite::set_target(call_site, target);
+}
+JVM_END
+
+JVM_ENTRY(void, MHN_setCallSiteTargetVolatile(JNIEnv* env, jobject igcls, jobject call_site_jh, jobject target_jh)) {
+ oop call_site = JNIHandles::resolve_non_null(call_site_jh);
+ oop target = JNIHandles::resolve(target_jh);
+ {
+ // Walk all nmethods depending on this call site.
+ MutexLocker mu(Compile_lock, thread);
+ Universe::flush_dependents_on(call_site, target);
+ }
+ java_lang_invoke_CallSite::set_target_volatile(call_site, target);
+}
+JVM_END
+
methodOop MethodHandles::resolve_raise_exception_method(TRAPS) {
if (_raise_exception_method != NULL) {
// no need to do it twice
@@ -3137,12 +3161,15 @@
/// JVM_RegisterMethodHandleMethods
+#undef CS // Solaris builds complain
+
#define LANG "Ljava/lang/"
#define JLINV "Ljava/lang/invoke/"
#define OBJ LANG"Object;"
#define CLS LANG"Class;"
#define STRG LANG"String;"
+#define CS JLINV"CallSite;"
#define MT JLINV"MethodType;"
#define MH JLINV"MethodHandle;"
#define MEM JLINV"MemberName;"
@@ -3153,29 +3180,34 @@
#define CC (char*) /*cast a literal from (const char*)*/
#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
-// These are the native methods on sun.invoke.MethodHandleNatives.
+// These are the native methods on java.lang.invoke.MethodHandleNatives.
static JNINativeMethod methods[] = {
// void init(MemberName self, AccessibleObject ref)
- {CC"init", CC"("AMH""MH"I)V", FN_PTR(MHN_init_AMH)},
- {CC"init", CC"("BMH""OBJ"I)V", FN_PTR(MHN_init_BMH)},
- {CC"init", CC"("DMH""OBJ"Z"CLS")V", FN_PTR(MHN_init_DMH)},
- {CC"init", CC"("MT")V", FN_PTR(MHN_init_MT)},
- {CC"init", CC"("MEM""OBJ")V", FN_PTR(MHN_init_Mem)},
- {CC"expand", CC"("MEM")V", FN_PTR(MHN_expand_Mem)},
- {CC"resolve", CC"("MEM""CLS")V", FN_PTR(MHN_resolve_Mem)},
- {CC"getTarget", CC"("MH"I)"OBJ, FN_PTR(MHN_getTarget)},
- {CC"getConstant", CC"(I)I", FN_PTR(MHN_getConstant)},
+ {CC"init", CC"("AMH""MH"I)V", FN_PTR(MHN_init_AMH)},
+ {CC"init", CC"("BMH""OBJ"I)V", FN_PTR(MHN_init_BMH)},
+ {CC"init", CC"("DMH""OBJ"Z"CLS")V", FN_PTR(MHN_init_DMH)},
+ {CC"init", CC"("MT")V", FN_PTR(MHN_init_MT)},
+ {CC"init", CC"("MEM""OBJ")V", FN_PTR(MHN_init_Mem)},
+ {CC"expand", CC"("MEM")V", FN_PTR(MHN_expand_Mem)},
+ {CC"resolve", CC"("MEM""CLS")V", FN_PTR(MHN_resolve_Mem)},
+ {CC"getTarget", CC"("MH"I)"OBJ, FN_PTR(MHN_getTarget)},
+ {CC"getConstant", CC"(I)I", FN_PTR(MHN_getConstant)},
// static native int getNamedCon(int which, Object[] name)
- {CC"getNamedCon", CC"(I["OBJ")I", FN_PTR(MHN_getNamedCon)},
+ {CC"getNamedCon", CC"(I["OBJ")I", FN_PTR(MHN_getNamedCon)},
// static native int getMembers(Class<?> defc, String matchName, String matchSig,
// int matchFlags, Class<?> caller, int skip, MemberName[] results);
- {CC"getMembers", CC"("CLS""STRG""STRG"I"CLS"I["MEM")I", FN_PTR(MHN_getMembers)}
+ {CC"getMembers", CC"("CLS""STRG""STRG"I"CLS"I["MEM")I", FN_PTR(MHN_getMembers)}
+};
+
+static JNINativeMethod call_site_methods[] = {
+ {CC"setCallSiteTargetNormal", CC"("CS""MH")V", FN_PTR(MHN_setCallSiteTargetNormal)},
+ {CC"setCallSiteTargetVolatile", CC"("CS""MH")V", FN_PTR(MHN_setCallSiteTargetVolatile)}
};
static JNINativeMethod invoke_methods[] = {
// void init(MemberName self, AccessibleObject ref)
- {CC"invoke", CC"(["OBJ")"OBJ, FN_PTR(MH_invoke_UOE)},
- {CC"invokeExact", CC"(["OBJ")"OBJ, FN_PTR(MH_invokeExact_UOE)}
+ {CC"invoke", CC"(["OBJ")"OBJ, FN_PTR(MH_invoke_UOE)},
+ {CC"invokeExact", CC"(["OBJ")"OBJ, FN_PTR(MH_invokeExact_UOE)}
};
// This one function is exported, used by NativeLookup.
@@ -3188,11 +3220,11 @@
return; // bind nothing
}
+ assert(!MethodHandles::enabled(), "must not be enabled");
bool enable_MH = true;
{
ThreadToNativeFromVM ttnfv(thread);
-
int status = env->RegisterNatives(MHN_class, methods, sizeof(methods)/sizeof(JNINativeMethod));
if (!env->ExceptionOccurred()) {
const char* L_MH_name = (JLINV "MethodHandle");
@@ -3201,11 +3233,16 @@
status = env->RegisterNatives(MH_class, invoke_methods, sizeof(invoke_methods)/sizeof(JNINativeMethod));
}
if (env->ExceptionOccurred()) {
- MethodHandles::set_enabled(false);
warning("JSR 292 method handle code is mismatched to this JVM. Disabling support.");
enable_MH = false;
env->ExceptionClear();
}
+
+ status = env->RegisterNatives(MHN_class, call_site_methods, sizeof(call_site_methods)/sizeof(JNINativeMethod));
+ if (env->ExceptionOccurred()) {
+ // Exception is okay until 7087357
+ env->ExceptionClear();
+ }
}
if (enable_MH) {