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