< prev index next >

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

Print this page

        

*** 63,72 **** --- 63,73 ---- private static final String OBJ = "java/lang/Object"; private static final String CLASS_PREFIX = "java/lang/invoke/LambdaForm$Value$"; private static final String DEFAULT_CLASS = "MH"; 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 MH = "java/lang/invoke/MethodHandle"; private static final String MHARY2 = "[[L" + MH + ";"; static MemberName generateCustomizedCode(LambdaForm form, MethodType invokerType) {
*** 92,102 **** --- 93,121 ---- LambdaFormBuilder(LambdaFormCodeBuilder builder, LambdaForm lambdaForm) { this.builder = builder; this.lambdaForm = lambdaForm; } + /** 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 + builder.dup().load(0).invokestatic(MethodHandleImpl.class, "assertSame", LLV_SIG, false); + return true; + } + void generateLambdaFormBody() { + if (lambdaForm.customized != null && MethodHandleBuilder.ENABLE_POOL_PATCHES) { + // 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. + builder.ldc(lambdaForm.customized) + .checkcast(MethodHandle.class); + assert(checkActualReceiver()); // generates runtime check + builder.store(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];
< prev index next >