71 private static final String LF_SIG = "L" + LF + ";"; |
71 private static final String LF_SIG = "L" + LF + ";"; |
72 private static final String LFN_SIG = "L" + LFN + ";"; |
72 private static final String LFN_SIG = "L" + LFN + ";"; |
73 private static final String LL_SIG = "(L" + OBJ + ";)L" + OBJ + ";"; |
73 private static final String LL_SIG = "(L" + OBJ + ";)L" + OBJ + ";"; |
74 private static final String LLV_SIG = "(L" + OBJ + ";L" + OBJ + ";)V"; |
74 private static final String LLV_SIG = "(L" + OBJ + ";L" + OBJ + ";)V"; |
75 private static final String CLASS_PREFIX = LF + "$"; |
75 private static final String CLASS_PREFIX = LF + "$"; |
|
76 private static final String SOURCE_PREFIX = "LambdaForm$"; |
76 |
77 |
77 /** Name of its super class*/ |
78 /** Name of its super class*/ |
78 static final String INVOKER_SUPER_NAME = OBJ; |
79 static final String INVOKER_SUPER_NAME = OBJ; |
79 |
80 |
80 /** Name of new class */ |
81 /** Name of new class */ |
81 private final String className; |
82 private final String className; |
82 |
|
83 /** Name of the source file (for stack trace printing). */ |
|
84 private final String sourceFile; |
|
85 |
83 |
86 private final LambdaForm lambdaForm; |
84 private final LambdaForm lambdaForm; |
87 private final String invokerName; |
85 private final String invokerName; |
88 private final MethodType invokerType; |
86 private final MethodType invokerType; |
89 |
87 |
107 invokerName = invokerName.substring(p + 1); |
105 invokerName = invokerName.substring(p + 1); |
108 } |
106 } |
109 if (DUMP_CLASS_FILES) { |
107 if (DUMP_CLASS_FILES) { |
110 className = makeDumpableClassName(className); |
108 className = makeDumpableClassName(className); |
111 } |
109 } |
112 this.className = CLASS_PREFIX + className; |
110 this.className = className; |
113 this.sourceFile = "LambdaForm$" + className; |
|
114 this.lambdaForm = lambdaForm; |
111 this.lambdaForm = lambdaForm; |
115 this.invokerName = invokerName; |
112 this.invokerName = invokerName; |
116 this.invokerType = invokerType; |
113 this.invokerType = invokerType; |
117 this.localsMap = new int[localsMapSize+1]; // last entry of localsMap is count of allocated local slots |
114 this.localsMap = new int[localsMapSize+1]; // last entry of localsMap is count of allocated local slots |
118 this.localClasses = new Class<?>[localsMapSize+1]; |
115 this.localClasses = new Class<?>[localsMapSize+1]; |
128 } |
125 } |
129 } |
126 } |
130 |
127 |
131 /** For generating customized code for a single LambdaForm. */ |
128 /** For generating customized code for a single LambdaForm. */ |
132 private InvokerBytecodeGenerator(String className, LambdaForm form, MethodType invokerType) { |
129 private InvokerBytecodeGenerator(String className, LambdaForm form, MethodType invokerType) { |
133 this(className, form.debugName, form, invokerType); |
130 this(className, form.lambdaName(), form, invokerType); |
134 } |
131 } |
135 |
132 |
136 /** For generating customized code for a single LambdaForm. */ |
133 /** For generating customized code for a single LambdaForm. */ |
137 InvokerBytecodeGenerator(String className, String invokerName, |
134 InvokerBytecodeGenerator(String className, String invokerName, |
138 LambdaForm form, MethodType invokerType) { |
135 LambdaForm form, MethodType invokerType) { |
171 DUMP_CLASS_FILES_COUNTERS = null; |
168 DUMP_CLASS_FILES_COUNTERS = null; |
172 DUMP_CLASS_FILES_DIR = null; |
169 DUMP_CLASS_FILES_DIR = null; |
173 } |
170 } |
174 } |
171 } |
175 |
172 |
|
173 private void maybeDump(final byte[] classFile) { |
|
174 if (DUMP_CLASS_FILES) { |
|
175 maybeDump(CLASS_PREFIX + className, classFile); |
|
176 } |
|
177 } |
|
178 |
|
179 // Also used from BoundMethodHandle |
176 static void maybeDump(final String className, final byte[] classFile) { |
180 static void maybeDump(final String className, final byte[] classFile) { |
177 if (DUMP_CLASS_FILES) { |
181 if (DUMP_CLASS_FILES) { |
178 java.security.AccessController.doPrivileged( |
182 java.security.AccessController.doPrivileged( |
179 new java.security.PrivilegedAction<>() { |
183 new java.security.PrivilegedAction<>() { |
180 public Void run() { |
184 public Void run() { |
304 * Set up class file generation. |
308 * Set up class file generation. |
305 */ |
309 */ |
306 private ClassWriter classFilePrologue() { |
310 private ClassWriter classFilePrologue() { |
307 final int NOT_ACC_PUBLIC = 0; // not ACC_PUBLIC |
311 final int NOT_ACC_PUBLIC = 0; // not ACC_PUBLIC |
308 cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES); |
312 cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES); |
309 cw.visit(Opcodes.V1_8, NOT_ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_SUPER, className, null, INVOKER_SUPER_NAME, null); |
313 cw.visit(Opcodes.V1_8, NOT_ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_SUPER, |
310 cw.visitSource(sourceFile, null); |
314 CLASS_PREFIX + className, null, INVOKER_SUPER_NAME, null); |
|
315 cw.visitSource(SOURCE_PREFIX + className, null); |
311 return cw; |
316 return cw; |
312 } |
317 } |
313 |
318 |
314 private void methodPrologue() { |
319 private void methodPrologue() { |
315 String invokerDesc = invokerType.toMethodDescriptorString(); |
320 String invokerDesc = invokerType.toMethodDescriptorString(); |
615 shortenSignature(basicTypeSignature(type)) + (resolvedMember != null ? " (success)" : " (fail)") ); |
620 shortenSignature(basicTypeSignature(type)) + (resolvedMember != null ? " (success)" : " (fail)") ); |
616 } |
621 } |
617 return resolvedMember; |
622 return resolvedMember; |
618 } |
623 } |
619 |
624 |
620 private static MemberName lookupPregenerated(LambdaForm form) { |
625 private static MemberName lookupPregenerated(LambdaForm form, MethodType invokerType) { |
621 if (form.customized != null) { |
626 if (form.customized != null) { |
622 // No pre-generated version for customized LF |
627 // No pre-generated version for customized LF |
623 return null; |
628 return null; |
624 } |
629 } |
625 MethodType invokerType = form.methodType(); |
|
626 String name = form.kind.methodName; |
630 String name = form.kind.methodName; |
627 switch (form.kind) { |
631 switch (form.kind) { |
628 case BOUND_REINVOKER: { |
632 case BOUND_REINVOKER: { |
629 name = name + "_" + BoundMethodHandle.speciesData(form).fieldSignature(); |
633 name = name + "_" + BoundMethodHandle.speciesData(form).fieldSignature(); |
630 return resolveFrom(name, invokerType, DelegatingMethodHandle.Holder.class); |
634 return resolveFrom(name, invokerType, DelegatingMethodHandle.Holder.class); |
668 |
672 |
669 /** |
673 /** |
670 * Generate customized bytecode for a given LambdaForm. |
674 * Generate customized bytecode for a given LambdaForm. |
671 */ |
675 */ |
672 static MemberName generateCustomizedCode(LambdaForm form, MethodType invokerType) { |
676 static MemberName generateCustomizedCode(LambdaForm form, MethodType invokerType) { |
673 MemberName pregenerated = lookupPregenerated(form); |
677 MemberName pregenerated = lookupPregenerated(form, invokerType); |
674 if (pregenerated != null) return pregenerated; // pre-generated bytecode |
678 if (pregenerated != null) return pregenerated; // pre-generated bytecode |
675 |
679 |
676 InvokerBytecodeGenerator g = new InvokerBytecodeGenerator("MH", form, invokerType); |
680 InvokerBytecodeGenerator g = new InvokerBytecodeGenerator("MH", form, invokerType); |
677 return g.loadMethod(g.generateCustomizedCodeBytes()); |
681 return g.loadMethod(g.generateCustomizedCodeBytes()); |
678 } |
682 } |
906 java.util.Arrays.class, |
910 java.util.Arrays.class, |
907 jdk.internal.misc.Unsafe.class |
911 jdk.internal.misc.Unsafe.class |
908 //MethodHandle.class already covered |
912 //MethodHandle.class already covered |
909 }; |
913 }; |
910 |
914 |
911 static boolean isStaticallyInvocable(NamedFunction[] functions) { |
915 static boolean isStaticallyInvocable(NamedFunction ... functions) { |
912 for (NamedFunction nf : functions) { |
916 for (NamedFunction nf : functions) { |
913 if (!isStaticallyInvocable(nf.member())) { |
917 if (!isStaticallyInvocable(nf.member())) { |
914 return false; |
918 return false; |
915 } |
919 } |
916 } |
920 } |