7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods
Reviewed-by: jrose, never
This commit is contained in:
parent
6141a568aa
commit
439b75eb12
@ -2707,14 +2707,6 @@ void java_lang_invoke_CallSite::compute_offsets() {
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
|
@ -771,7 +771,7 @@ class java_lang_ref_Reference: AllStatic {
|
||||
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 @@ class java_lang_ref_Reference: AllStatic {
|
||||
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 @@ class java_lang_ref_Reference: AllStatic {
|
||||
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 @@ private:
|
||||
|
||||
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 oop caller_method(oop site);
|
||||
static void set_caller_method(oop site, oop ref);
|
||||
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 jint caller_bci(oop site);
|
||||
static void set_caller_bci(oop site, jint bci);
|
||||
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);
|
||||
|
||||
// Testers
|
||||
static bool is_subclass(klassOop klass) {
|
||||
|
@ -53,8 +53,10 @@ class klassOopDesc : public oopDesc {
|
||||
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);
|
||||
|
@ -214,8 +214,10 @@ class oopDesc {
|
||||
|
||||
// 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);
|
||||
|
@ -321,15 +321,25 @@ inline oop oopDesc::obj_field(int offset) const {
|
||||
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; }
|
||||
|
@ -3081,6 +3081,30 @@ JVM_ENTRY(jint, MHN_getMembers(JNIEnv *env, jobject igcls,
|
||||
}
|
||||
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_END
|
||||
|
||||
/// 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 @@ JVM_END
|
||||
#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 @@ JVM_ENTRY(void, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class))
|
||||
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 @@ JVM_ENTRY(void, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class))
|
||||
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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user