< prev index next >

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

Print this page
rev 15353 : 8164044: Generate the corresponding BoundMethodHandle to all generated DirectMethodHandles
Reviewed-by: vlivanov, mhaupt

*** 44,53 **** --- 44,54 ---- import java.util.HashMap; import java.util.stream.Stream; import static java.lang.invoke.LambdaForm.*; import static java.lang.invoke.LambdaForm.BasicType.*; + import static java.lang.invoke.LambdaForm.Kind.*; import static java.lang.invoke.MethodHandleNatives.Constants.*; import static java.lang.invoke.MethodHandleStatics.*; /** * Code generation backend for LambdaForm.
*** 123,135 **** localsMap[i] = invokerType.parameterSlotCount() - invokerType.parameterSlotDepth(i); } } /** For generating customized code for a single LambdaForm. */ ! InvokerBytecodeGenerator(String className, LambdaForm form, MethodType invokerType) { this(form, form.names.length, ! className, form.debugName, invokerType); // Create an array to map name indexes to locals indexes. Name[] names = form.names; for (int i = 0, index = 0; i < localsMap.length; i++) { localsMap[i] = index; if (i < names.length) { --- 124,142 ---- localsMap[i] = invokerType.parameterSlotCount() - invokerType.parameterSlotDepth(i); } } /** For generating customized code for a single LambdaForm. */ ! private InvokerBytecodeGenerator(String className, LambdaForm form, MethodType invokerType) { ! this(className, form.debugName, form, invokerType); ! } ! ! /** For generating customized code for a single LambdaForm. */ ! InvokerBytecodeGenerator(String className, String invokerName, ! LambdaForm form, MethodType invokerType) { this(form, form.names.length, ! className, invokerName, invokerType); // Create an array to map name indexes to locals indexes. Name[] names = form.names; for (int i = 0, index = 0; i < localsMap.length; i++) { localsMap[i] = index; if (i < names.length) {
*** 595,608 **** --- 602,644 ---- else if (c == MethodHandle.class) return MH; assert(VerifyAccess.isTypeVisible(c, Object.class)) : c.getName(); return c.getName().replace('.', '/'); } + private static MemberName resolveFrom(String name, MethodType type, Class<?> holder) { + MemberName member = new MemberName(holder, name, type, REF_invokeStatic); + MemberName resolvedMember = MemberName.getFactory().resolveOrNull(REF_invokeStatic, member, holder); + + return resolvedMember; + } + + private static MemberName lookupPregenerated(LambdaForm form) { + if (form.customized != null) return null; // No pre-generated version for customized LF + MethodType invokerType = form.methodType(); + String name = form.kind.methodName; + switch (form.kind) { + case BOUND_REINVOKER: { + name = name + "_" + BoundMethodHandle.speciesData(form).fieldSignature(); + return resolveFrom(name, invokerType, DelegatingMethodHandle.Holder.class); + } + case DELEGATE: return resolveFrom(name, invokerType, DelegatingMethodHandle.Holder.class); + case DIRECT_INVOKE_INTERFACE: // fall-through + case DIRECT_INVOKE_SPECIAL: // fall-through + case DIRECT_INVOKE_STATIC: // fall-through + case DIRECT_INVOKE_STATIC_INIT: // fall-through + case DIRECT_INVOKE_VIRTUAL: return resolveFrom(name, invokerType, DirectMethodHandle.Holder.class); + } + return null; + } + /** * Generate customized bytecode for a given LambdaForm. */ static MemberName generateCustomizedCode(LambdaForm form, MethodType invokerType) { + MemberName pregenerated = lookupPregenerated(form); + if (pregenerated != null) return pregenerated; // pre-generated bytecode + InvokerBytecodeGenerator g = new InvokerBytecodeGenerator("MH", form, invokerType); return g.loadMethod(g.generateCustomizedCodeBytes()); } /** Generates code to check that actual receiver and LambdaForm matches */
< prev index next >