# HG changeset patch # User redestad # Date 1522070920 -7200 # Mon Mar 26 15:28:40 2018 +0200 # Node ID 6bc773f42ee1d3aeb96859852fb0c74dc8a4c5e8 # Parent b39bc2eb8325eafc55b7c0d0f4dd5076b3d44561 8200238: Reduce number of exceptions created when calling MemberName$Factory::resolveOrNull Reviewed-by: lfoltan, acorn diff --git a/src/hotspot/share/prims/methodHandles.cpp b/src/hotspot/share/prims/methodHandles.cpp --- a/src/hotspot/share/prims/methodHandles.cpp +++ b/src/hotspot/share/prims/methodHandles.cpp @@ -304,7 +304,7 @@ Handle resolved_method = info.resolved_method_name(); assert(java_lang_invoke_ResolvedMethodName::vmtarget(resolved_method()) == m(), - "Should not change after link resolultion"); + "Should not change after link resolution"); oop mname_oop = mname(); java_lang_invoke_MemberName::set_flags (mname_oop, flags); @@ -1185,7 +1185,8 @@ JVM_END // void resolve(MemberName self, Class caller) -JVM_ENTRY(jobject, MHN_resolve_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jclass caller_jh)) { +JVM_ENTRY(jobject, MHN_resolve_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jclass caller_jh, + jboolean speculative_resolve)) { if (mname_jh == NULL) { THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "mname is null"); } Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh)); @@ -1221,6 +1222,9 @@ if (!MethodHandles::ref_kind_is_valid(ref_kind)) { THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "obsolete MemberName format"); } + if (speculative_resolve) { + return NULL; + } if ((flags & ALL_KINDS) == IS_FIELD) { THROW_MSG_NULL(vmSymbols::java_lang_NoSuchFieldError(), "field resolution failed"); } else if ((flags & ALL_KINDS) == IS_METHOD || @@ -1512,7 +1516,7 @@ 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)}, + {CC "resolve", CC "(" MEM "" CLS "Z)" MEM, FN_PTR(MHN_resolve_Mem)}, // static native int getNamedCon(int which, Object[] name) {CC "getNamedCon", CC "(I[" OBJ ")I", FN_PTR(MHN_getNamedCon)}, // static native int getMembers(Class defc, String matchName, String matchSig, diff --git a/src/java.base/share/classes/java/lang/invoke/MemberName.java b/src/java.base/share/classes/java/lang/invoke/MemberName.java --- a/src/java.base/share/classes/java/lang/invoke/MemberName.java +++ b/src/java.base/share/classes/java/lang/invoke/MemberName.java @@ -1047,7 +1047,8 @@ * If lookup fails or access is not permitted, null is returned. * Otherwise a fresh copy of the given member is returned, with modifier bits filled in. */ - private MemberName resolve(byte refKind, MemberName ref, Class lookupClass) { + private MemberName resolve(byte refKind, MemberName ref, Class lookupClass, + boolean speculativeResolve) { MemberName m = ref.clone(); // JVM will side-effect the ref assert(refKind == m.getReferenceKind()); try { @@ -1066,7 +1067,10 @@ // // REFC view on PTYPES doesn't matter, since it is used only as a starting point for resolution and doesn't // participate in method selection. - m = MethodHandleNatives.resolve(m, lookupClass); + m = MethodHandleNatives.resolve(m, lookupClass, speculativeResolve); + if (m == null && speculativeResolve) { + return null; + } m.checkForTypeAlias(m.getDeclaringClass()); m.resolution = null; } catch (ClassNotFoundException | LinkageError ex) { @@ -1091,7 +1095,7 @@ MemberName resolveOrFail(byte refKind, MemberName m, Class lookupClass, Class nsmClass) throws IllegalAccessException, NoSuchMemberException { - MemberName result = resolve(refKind, m, lookupClass); + MemberName result = resolve(refKind, m, lookupClass, false); if (result.isResolved()) return result; ReflectiveOperationException ex = result.makeAccessException(); @@ -1106,8 +1110,8 @@ */ public MemberName resolveOrNull(byte refKind, MemberName m, Class lookupClass) { - MemberName result = resolve(refKind, m, lookupClass); - if (result.isResolved()) + MemberName result = resolve(refKind, m, lookupClass, true); + if (result != null && result.isResolved()) return result; return null; } diff --git a/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java b/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java --- a/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java +++ b/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java @@ -49,7 +49,8 @@ static native void init(MemberName self, Object ref); static native void expand(MemberName self); - static native MemberName resolve(MemberName self, Class caller) throws LinkageError, ClassNotFoundException; + static native MemberName resolve(MemberName self, Class caller, + boolean speculativeResolve) throws LinkageError, ClassNotFoundException; static native int getMembers(Class defc, String matchName, String matchSig, int matchFlags, Class caller, int skip, MemberName[] results);