提交 1c8eb83f 编写于 作者: T twisti

7085860: JSR 292: implement CallSite.setTargetNormal and setTargetVolatile as native methods

Reviewed-by: jrose, never
上级 15bdbb1e
......@@ -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) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册