src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File jdk Cdiff src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java

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

Print this page
rev 11254 : 8063137: Never-taken branches should be pruned when GWT LambdaForms are shared
Reviewed-by: ?
rev 11255 : [mq]: gwt.profile.1
rev 11258 : 8069591: Customize LambdaForms which are invoked using MH.invoke/invokeExact
Reviewed-by: ?

*** 54,66 **** --- 54,68 ---- private static final String LFN = "java/lang/invoke/LambdaForm$Name"; private static final String CLS = "java/lang/Class"; private static final String OBJ = "java/lang/Object"; private static final String OBJARY = "[Ljava/lang/Object;"; + private static final String MH_SIG = "L" + MH + ";"; private static final String LF_SIG = "L" + LF + ";"; private static final String LFN_SIG = "L" + LFN + ";"; private static final String LL_SIG = "(L" + OBJ + ";)L" + OBJ + ";"; + private static final String LLV_SIG = "(L" + OBJ + ";L" + OBJ + ";)V"; private static final String CLL_SIG = "(L" + CLS + ";L" + OBJ + ";)L" + OBJ + ";"; /** Name of its super class*/ private static final String superName = OBJ;
*** 625,634 **** --- 627,645 ---- } } return false; } + /** Generates code to check that actual receiver and LambdaForm matches */ + private boolean checkActualReceiver() { + // Expects MethodHandle on the stack and actual receiver MethodHandle in slot #0 + mv.visitInsn(Opcodes.DUP); + mv.visitVarInsn(Opcodes.ALOAD, localsMap[0]); + mv.visitMethodInsn(Opcodes.INVOKESTATIC, MHI, "assertSame", LLV_SIG, false); + return true; + } + /** * Generate an invoker method for the passed {@link LambdaForm}. */ private byte[] generateCustomizedCodeBytes() { classFilePrologue();
*** 650,659 **** --- 661,681 ---- mv.visitAnnotation("Ljava/lang/invoke/ForceInline;", true); } else { mv.visitAnnotation("Ljava/lang/invoke/DontInline;", true); } + if (lambdaForm.customized != null) { + // Since LambdaForm is customized for a particular MethodHandle, it's safe to substitute + // receiver MethodHandle (at slot #0) with an embedded constant and use it instead. + // It enables more efficient code generation in some situations, since embedded constants + // are compile-time constants for JIT compiler. + mv.visitLdcInsn(constantPlaceholder(lambdaForm.customized)); + mv.visitTypeInsn(Opcodes.CHECKCAST, MH); + assert(checkActualReceiver()); // expects MethodHandle on top of the stack + mv.visitVarInsn(Opcodes.ASTORE, localsMap[0]); + } + // iterate over the form's names, generating bytecode instructions for each // start iterating at the first name following the arguments Name onStack = null; for (int i = lambdaForm.arity; i < lambdaForm.names.length; i++) { Name name = lambdaForm.names[i];
src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File