< prev index next >

src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java

Print this page
rev 50604 : imported patch jep181-rev1

*** 56,65 **** --- 56,66 ---- private DirectMethodHandle(MethodType mtype, LambdaForm form, MemberName member) { super(mtype, form); if (!member.isResolved()) throw new InternalError(); if (member.getDeclaringClass().isInterface() && + member.getReferenceKind() == REF_invokeInterface && member.isMethod() && !member.isAbstract()) { // Check for corner case: invokeinterface of Object method MemberName m = new MemberName(Object.class, member.getName(), member.getMethodType(), member.getReferenceKind()); m = MemberName.getFactory().resolveOrNull(m.getReferenceKind(), m, null); if (m != null && m.isPublic()) {
*** 78,103 **** if (!member.getDeclaringClass().isAssignableFrom(refc) || member.isConstructor()) throw new InternalError(member.toString()); mtype = mtype.insertParameterTypes(0, refc); } if (!member.isField()) { switch (refKind) { case REF_invokeSpecial: { member = member.asSpecial(); ! LambdaForm lform = preparedLambdaForm(member, callerClass); ! Class<?> checkClass = refc; // Class to use for receiver type check ! if (callerClass != null) { ! checkClass = callerClass; // potentially strengthen to caller class } ! return new Special(mtype, lform, member, checkClass); } case REF_invokeInterface: { ! LambdaForm lform = preparedLambdaForm(member, callerClass); return new Interface(mtype, lform, member, refc); } default: { ! LambdaForm lform = preparedLambdaForm(member, callerClass); return new DirectMethodHandle(mtype, lform, member); } } } else { LambdaForm lform = preparedFieldLambdaForm(member); --- 79,110 ---- if (!member.getDeclaringClass().isAssignableFrom(refc) || member.isConstructor()) throw new InternalError(member.toString()); mtype = mtype.insertParameterTypes(0, refc); } if (!member.isField()) { + // refKind reflects the original type of lookup via findSpecial or + // findVirtual etc. switch (refKind) { case REF_invokeSpecial: { member = member.asSpecial(); ! // if caller is an interface we need to adapt to get the ! // receiver check inserted ! if (callerClass == null) { ! throw new InternalError("callerClass must not be null for REF_invokeSpecial"); } ! LambdaForm lform = preparedLambdaForm(member, callerClass.isInterface()); ! return new Special(mtype, lform, member, callerClass); } case REF_invokeInterface: { ! // for interfaces we always need the receiver typecheck, ! // so we always pass 'true' to ensure we adapt if needed ! // to include the REF_invokeSpecial case ! LambdaForm lform = preparedLambdaForm(member, true); return new Interface(mtype, lform, member, refc); } default: { ! LambdaForm lform = preparedLambdaForm(member); return new DirectMethodHandle(mtype, lform, member); } } } else { LambdaForm lform = preparedFieldLambdaForm(member);
*** 163,177 **** /** * Create a LF which can invoke the given method. * Cache and share this structure among all methods with * the same basicType and refKind. */ ! private static LambdaForm preparedLambdaForm(MemberName m, Class<?> callerClass) { assert(m.isInvocable()) : m; // call preparedFieldLambdaForm instead MethodType mtype = m.getInvocationType().basicType(); assert(!m.isMethodHandleInvoke()) : m; int which; switch (m.getReferenceKind()) { case REF_invokeVirtual: which = LF_INVVIRTUAL; break; case REF_invokeStatic: which = LF_INVSTATIC; break; case REF_invokeSpecial: which = LF_INVSPECIAL; break; case REF_invokeInterface: which = LF_INVINTERFACE; break; --- 170,189 ---- /** * Create a LF which can invoke the given method. * Cache and share this structure among all methods with * the same basicType and refKind. */ ! private static LambdaForm preparedLambdaForm(MemberName m, boolean adaptToSpecialIfc) { assert(m.isInvocable()) : m; // call preparedFieldLambdaForm instead MethodType mtype = m.getInvocationType().basicType(); assert(!m.isMethodHandleInvoke()) : m; int which; + // MemberName.getReferenceKind represents the JVM optimized form of the call + // as distinct from the "kind" passed to DMH.make which represents the original + // bytecode-equivalent request. Specifically private/final methods that use a direct + // call have getReferenceKind adapted to REF_invokeSpecial, even though the actual + // invocation mode may be invokevirtual or invokeinterface. switch (m.getReferenceKind()) { case REF_invokeVirtual: which = LF_INVVIRTUAL; break; case REF_invokeStatic: which = LF_INVSTATIC; break; case REF_invokeSpecial: which = LF_INVSPECIAL; break; case REF_invokeInterface: which = LF_INVINTERFACE; break;
*** 181,191 **** if (which == LF_INVSTATIC && shouldBeInitialized(m)) { // precompute the barrier-free version: preparedLambdaForm(mtype, which); which = LF_INVSTATIC_INIT; } ! if (which == LF_INVSPECIAL && callerClass != null && callerClass.isInterface()) { which = LF_INVSPECIAL_IFC; } LambdaForm lform = preparedLambdaForm(mtype, which); maybeCompile(lform, m); assert(lform.methodType().dropParameterTypes(0, 1) --- 193,203 ---- if (which == LF_INVSTATIC && shouldBeInitialized(m)) { // precompute the barrier-free version: preparedLambdaForm(mtype, which); which = LF_INVSTATIC_INIT; } ! if (which == LF_INVSPECIAL && adaptToSpecialIfc) { which = LF_INVSPECIAL_IFC; } LambdaForm lform = preparedLambdaForm(mtype, which); maybeCompile(lform, m); assert(lform.methodType().dropParameterTypes(0, 1)
*** 193,203 **** : Arrays.asList(m, m.getInvocationType().basicType(), lform, lform.methodType()); return lform; } private static LambdaForm preparedLambdaForm(MemberName m) { ! return preparedLambdaForm(m, null); } private static LambdaForm preparedLambdaForm(MethodType mtype, int which) { LambdaForm lform = mtype.form().cachedLambdaForm(which); if (lform != null) return lform; --- 205,215 ---- : Arrays.asList(m, m.getInvocationType().basicType(), lform, lform.methodType()); return lform; } private static LambdaForm preparedLambdaForm(MemberName m) { ! return preparedLambdaForm(m, false); } private static LambdaForm preparedLambdaForm(MethodType mtype, int which) { LambdaForm lform = mtype.form().cachedLambdaForm(which); if (lform != null) return lform;
< prev index next >