提交 33d0b626 编写于 作者: T twisti

7196277: JSR 292: Two jck/runtime tests crash on java.lang.invoke.MethodHandle.invokeExact

Reviewed-by: jrose, kvn
上级 f3338732
......@@ -832,7 +832,9 @@ void Method::link_method(methodHandle h_method, TRAPS) {
assert(entry != NULL, "interpreter entry must be non-null");
// Sets both _i2i_entry and _from_interpreted_entry
set_interpreter_entry(entry);
if (is_native() && !is_method_handle_intrinsic()) {
// Don't overwrite already registered native entries.
if (is_native() && !has_native_function()) {
set_native_function(
SharedRuntime::native_method_throw_unsatisfied_link_error_entry(),
!native_bind_event_is_interesting);
......
......@@ -1298,6 +1298,28 @@ JVM_ENTRY(void, MHN_setCallSiteTargetVolatile(JNIEnv* env, jobject igcls, jobjec
}
JVM_END
/**
* Throws a java/lang/UnsupportedOperationException unconditionally.
* This is required by the specification of MethodHandle.invoke if
* invoked directly.
*/
JVM_ENTRY(jobject, MH_invoke_UOE(JNIEnv* env, jobject mh, jobjectArray args)) {
THROW_MSG_NULL(vmSymbols::java_lang_UnsupportedOperationException(), "MethodHandle.invoke cannot be invoked reflectively");
return NULL;
}
JVM_END
/**
* Throws a java/lang/UnsupportedOperationException unconditionally.
* This is required by the specification of MethodHandle.invokeExact if
* invoked directly.
*/
JVM_ENTRY(jobject, MH_invokeExact_UOE(JNIEnv* env, jobject mh, jobjectArray args)) {
THROW_MSG_NULL(vmSymbols::java_lang_UnsupportedOperationException(), "MethodHandle.invokeExact cannot be invoked reflectively");
return NULL;
}
JVM_END
/// JVM_RegisterMethodHandleMethods
#undef CS // Solaris builds complain
......@@ -1317,7 +1339,7 @@ JVM_END
#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
// These are the native methods on java.lang.invoke.MethodHandleNatives.
static JNINativeMethod required_methods_JDK8[] = {
static JNINativeMethod MHN_methods[] = {
{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")"MEM, FN_PTR(MHN_resolve_Mem)},
......@@ -1335,8 +1357,28 @@ static JNINativeMethod required_methods_JDK8[] = {
{CC"getMemberVMInfo", CC"("MEM")"OBJ, FN_PTR(MHN_getMemberVMInfo)}
};
// This one function is exported, used by NativeLookup.
static JNINativeMethod MH_methods[] = {
// UnsupportedOperationException throwers
{CC"invoke", CC"(["OBJ")"OBJ, FN_PTR(MH_invoke_UOE)},
{CC"invokeExact", CC"(["OBJ")"OBJ, FN_PTR(MH_invokeExact_UOE)}
};
/**
* Helper method to register native methods.
*/
static bool register_natives(JNIEnv* env, jclass clazz, const JNINativeMethod* methods, jint nMethods) {
int status = env->RegisterNatives(clazz, methods, nMethods);
if (status != JNI_OK || env->ExceptionOccurred()) {
warning("JSR 292 method handle code is mismatched to this JVM. Disabling support.");
env->ExceptionClear();
return false;
}
return true;
}
/**
* This one function is exported, used by NativeLookup.
*/
JVM_ENTRY(void, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class)) {
if (!EnableInvokeDynamic) {
warning("JSR 292 is disabled in this JVM. Use -XX:+UnlockDiagnosticVMOptions -XX:+EnableInvokeDynamic to enable.");
......@@ -1354,16 +1396,14 @@ JVM_ENTRY(void, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class))
MH_class = (jclass) JNIHandles::make_local(env, mirror);
}
int status;
if (enable_MH) {
ThreadToNativeFromVM ttnfv(thread);
status = env->RegisterNatives(MHN_class, required_methods_JDK8, sizeof(required_methods_JDK8)/sizeof(JNINativeMethod));
if (status != JNI_OK || env->ExceptionOccurred()) {
warning("JSR 292 method handle code is mismatched to this JVM. Disabling support.");
enable_MH = false;
env->ExceptionClear();
if (enable_MH) {
enable_MH = register_natives(env, MHN_class, MHN_methods, sizeof(MHN_methods)/sizeof(JNINativeMethod));
}
if (enable_MH) {
enable_MH = register_natives(env, MH_class, MH_methods, sizeof(MH_methods)/sizeof(JNINativeMethod));
}
}
......
......@@ -383,10 +383,7 @@ address NativeLookup::lookup_base(methodHandle method, bool& in_base_library, TR
address NativeLookup::lookup(methodHandle method, bool& in_base_library, TRAPS) {
if (!method->has_native_function()) {
address entry =
method->intrinsic_id() == vmIntrinsics::_invokeGeneric ?
SharedRuntime::native_method_throw_unsupported_operation_exception_entry() :
lookup_base(method, in_base_library, CHECK_NULL);
address entry = lookup_base(method, in_base_library, CHECK_NULL);
method->set_native_function(entry,
Method::native_bind_event_is_interesting);
// -verbose:jni printing
......
......@@ -883,15 +883,23 @@ address SharedRuntime::continuation_for_implicit_exception(JavaThread* thread,
}
JNI_ENTRY(void, throw_unsatisfied_link_error(JNIEnv* env, ...))
{
THROW(vmSymbols::java_lang_UnsatisfiedLinkError());
}
JNI_END
JNI_ENTRY(void, throw_unsupported_operation_exception(JNIEnv* env, ...))
/**
* Throws an java/lang/UnsatisfiedLinkError. The address of this method is
* installed in the native function entry of all native Java methods before
* they get linked to their actual native methods.
*
* \note
* This method actually never gets called! The reason is because
* the interpreter's native entries call NativeLookup::lookup() which
* throws the exception when the lookup fails. The exception is then
* caught and forwarded on the return from NativeLookup::lookup() call
* before the call to the native function. This might change in the future.
*/
JNI_ENTRY(void*, throw_unsatisfied_link_error(JNIEnv* env, ...))
{
THROW(vmSymbols::java_lang_UnsupportedOperationException());
// We return a bad value here to make sure that the exception is
// forwarded before we look at the return value.
THROW_(vmSymbols::java_lang_UnsatisfiedLinkError(), (void*)badJNIHandle);
}
JNI_END
......@@ -899,10 +907,6 @@ address SharedRuntime::native_method_throw_unsatisfied_link_error_entry() {
return CAST_FROM_FN_PTR(address, &throw_unsatisfied_link_error);
}
address SharedRuntime::native_method_throw_unsupported_operation_exception_entry() {
return CAST_FROM_FN_PTR(address, &throw_unsupported_operation_exception);
}
#ifndef PRODUCT
JRT_ENTRY(intptr_t, SharedRuntime::trace_bytecode(JavaThread* thread, intptr_t preserve_this_value, intptr_t tos, intptr_t tos2))
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册