1 /*
2 * Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.lang.invoke;
27
28 import java.lang.classfile.TypeKind;
29 import jdk.internal.perf.PerfCounter;
30 import jdk.internal.vm.annotation.AOTSafeClassInitializer;
31 import jdk.internal.vm.annotation.DontInline;
32 import jdk.internal.vm.annotation.Hidden;
33 import jdk.internal.vm.annotation.Stable;
34 import sun.invoke.util.Wrapper;
35
36 import java.lang.annotation.ElementType;
37 import java.lang.annotation.Retention;
38 import java.lang.annotation.RetentionPolicy;
39 import java.lang.annotation.Target;
40 import java.lang.reflect.Method;
41 import java.util.Arrays;
42 import java.util.HashMap;
43
44 import static java.lang.invoke.LambdaForm.BasicType.*;
45 import static java.lang.invoke.MethodHandleNatives.Constants.*;
46 import static java.lang.invoke.MethodHandleStatics.*;
47
48 /**
49 * The symbolic, non-executable form of a method handle's invocation semantics.
50 * It consists of a series of names.
51 * The first N (N=arity) names are parameters,
52 * while any remaining names are temporary values.
53 * Each temporary specifies the application of a function to some arguments.
54 * The functions are method handles, while the arguments are mixes of
55 * constant values and local names.
56 * The result of the lambda is defined as one of the names, often the last one.
57 * <p>
58 * Here is an approximate grammar:
59 * <blockquote><pre>{@code
60 * LambdaForm = "(" ArgName* ")=>{" TempName* Result "}"
61 * ArgName = "a" N ":" T
62 * TempName = "t" N ":" T "=" Function "(" Argument* ");"
63 * Function = ConstantValue
64 * Argument = NameRef | ConstantValue
65 * Result = NameRef | "void"
66 * NameRef = "a" N | "t" N
67 * N = (any whole number)
68 * T = "L" | "I" | "J" | "F" | "D" | "V"
69 * }</pre></blockquote>
70 * Names are numbered consecutively from left to right starting at zero.
71 * (The letters are merely a taste of syntax sugar.)
72 * Thus, the first temporary (if any) is always numbered N (where N=arity).
73 * Every occurrence of a name reference in an argument list must refer to
74 * a name previously defined within the same lambda.
75 * A lambda has a void result if and only if its result index is -1.
76 * If a temporary has the type "V", it cannot be the subject of a NameRef,
77 * even though possesses a number.
78 * Note that all reference types are erased to "L", which stands for {@code Object}.
79 * All subword types (boolean, byte, short, char) are erased to "I" which is {@code int}.
80 * The other types stand for the usual primitive types.
81 * <p>
82 * Function invocation closely follows the static rules of the Java verifier.
83 * Arguments and return values must exactly match when their "Name" types are
84 * considered.
85 * Conversions are allowed only if they do not change the erased type.
86 * <ul>
87 * <li>L = Object: casts are used freely to convert into and out of reference types
88 * <li>I = int: subword types are forcibly narrowed when passed as arguments (see {@code explicitCastArguments})
89 * <li>J = long: no implicit conversions
90 * <li>F = float: no implicit conversions
91 * <li>D = double: no implicit conversions
92 * <li>V = void: a function result may be void if and only if its Name is of type "V"
93 * </ul>
94 * Although implicit conversions are not allowed, explicit ones can easily be
95 * encoded by using temporary expressions which call type-transformed identity functions.
96 * <p>
97 * Examples:
98 * <blockquote><pre>{@code
99 * (a0:J)=>{ a0 }
100 * == identity(long)
101 * (a0:I)=>{ t1:V = System.out#println(a0); void }
102 * == System.out#println(int)
103 * (a0:L)=>{ t1:V = System.out#println(a0); a0 }
104 * == identity, with printing side-effect
105 * (a0:L, a1:L)=>{ t2:L = BoundMethodHandle#argument(a0);
106 * t3:L = BoundMethodHandle#target(a0);
107 * t4:L = MethodHandle#invoke(t3, t2, a1); t4 }
108 * == general invoker for unary insertArgument combination
109 * (a0:L, a1:L)=>{ t2:L = FilterMethodHandle#filter(a0);
110 * t3:L = MethodHandle#invoke(t2, a1);
111 * t4:L = FilterMethodHandle#target(a0);
112 * t5:L = MethodHandle#invoke(t4, t3); t5 }
113 * == general invoker for unary filterArgument combination
114 * (a0:L, a1:L)=>{ ...(same as previous example)...
115 * t5:L = MethodHandle#invoke(t4, t3, a1); t5 }
116 * == general invoker for unary/unary foldArgument combination
117 * (a0:L, a1:I)=>{ t2:I = identity(long).asType((int)->long)(a1); t2 }
118 * == invoker for identity method handle which performs i2l
119 * (a0:L, a1:L)=>{ t2:L = BoundMethodHandle#argument(a0);
120 * t3:L = Class#cast(t2,a1); t3 }
121 * == invoker for identity method handle which performs cast
122 * }</pre></blockquote>
123 * <p>
124 * @author John Rose, JSR 292 EG
125 */
126 @AOTSafeClassInitializer
127 class LambdaForm {
128 final int arity;
129 final int result;
130 final boolean forceInline;
131 final MethodHandle customized;
132 @Stable final Name[] names;
133 final Kind kind;
134 MemberName vmentry; // low-level behavior, or null if not yet prepared
135 private boolean isCompiled;
136
137 // Either a LambdaForm cache (managed by LambdaFormEditor) or a link to uncustomized version (for customized LF)
138 volatile Object transformCache;
139
140 public static final int VOID_RESULT = -1, LAST_RESULT = -2;
141
142 /// Represents the "basic" types that exist in the JVM linkage and stack/locals.
143 /// All objects are erased to a reference.
144 /// All subwords (boolean, byte, char, short) are promoted to int.
145 enum BasicType {
146 L_TYPE('L', Object.class, Wrapper.OBJECT, TypeKind.REFERENCE),
147 I_TYPE('I', int.class, Wrapper.INT, TypeKind.INT),
148 J_TYPE('J', long.class, Wrapper.LONG, TypeKind.LONG),
149 F_TYPE('F', float.class, Wrapper.FLOAT, TypeKind.FLOAT),
150 D_TYPE('D', double.class, Wrapper.DOUBLE, TypeKind.DOUBLE), // end arg types
151 V_TYPE('V', void.class, Wrapper.VOID, TypeKind.VOID); // only valid in method return
152
153 static final @Stable BasicType[] ALL_TYPES = BasicType.values();
154 static final @Stable BasicType[] ARG_TYPES = Arrays.copyOf(ALL_TYPES, ALL_TYPES.length-1);
155
156 static final int ARG_TYPE_LIMIT = ARG_TYPES.length;
157 static final int TYPE_LIMIT = ALL_TYPES.length;
158
159 final char btChar;
160 final Class<?> btClass;
161 final Wrapper btWrapper;
162 final TypeKind btKind;
163
164 private BasicType(char btChar, Class<?> btClass, Wrapper wrapper, TypeKind typeKind) {
165 this.btChar = btChar;
166 this.btClass = btClass;
167 this.btWrapper = wrapper;
168 this.btKind = typeKind;
169 }
170
171 char basicTypeChar() {
172 return btChar;
173 }
174 Class<?> basicTypeClass() {
175 return btClass;
176 }
177 Wrapper basicTypeWrapper() {
178 return btWrapper;
179 }
180 TypeKind basicTypeKind() {
181 return btKind;
182 }
183 int basicTypeSlots() {
184 return btWrapper.stackSlots();
185 }
186
187 static BasicType basicType(byte type) {
188 return ALL_TYPES[type];
189 }
190 static BasicType basicType(char type) {
191 return switch (type) {
192 case 'L' -> L_TYPE;
193 case 'I' -> I_TYPE;
194 case 'J' -> J_TYPE;
195 case 'F' -> F_TYPE;
196 case 'D' -> D_TYPE;
197 case 'V' -> V_TYPE;
198 // all subword types are represented as ints
199 case 'Z', 'B', 'S', 'C' -> I_TYPE;
200 default -> throw newInternalError("Unknown type char: '" + type + "'");
201 };
202 }
203 static BasicType basicType(Class<?> type) {
204 return basicType(Wrapper.basicTypeChar(type));
205 }
206 static int[] basicTypeOrds(BasicType[] types) {
207 if (types == null) {
208 return null;
209 }
210 int[] a = new int[types.length];
211 for(int i = 0; i < types.length; ++i) {
212 a[i] = types[i].ordinal();
213 }
214 return a;
215 }
216
217 static char basicTypeChar(Class<?> type) {
218 return basicType(type).btChar;
219 }
220
221 static int[] basicTypesOrd(Class<?>[] types) {
222 int[] ords = new int[types.length];
223 for (int i = 0; i < ords.length; i++) {
224 ords[i] = basicType(types[i]).ordinal();
225 }
226 return ords;
227 }
228
229 static boolean isBasicTypeChar(char c) {
230 return "LIJFDV".indexOf(c) >= 0;
231 }
232 static boolean isArgBasicTypeChar(char c) {
233 return "LIJFD".indexOf(c) >= 0;
234 }
235
236 static { assert(checkBasicType()); }
237 private static boolean checkBasicType() {
238 for (int i = 0; i < ARG_TYPE_LIMIT; i++) {
239 assert ARG_TYPES[i].ordinal() == i;
240 assert ARG_TYPES[i] == ALL_TYPES[i];
241 }
242 for (int i = 0; i < TYPE_LIMIT; i++) {
243 assert ALL_TYPES[i].ordinal() == i;
244 }
245 assert ALL_TYPES[TYPE_LIMIT - 1] == V_TYPE;
246 assert !Arrays.asList(ARG_TYPES).contains(V_TYPE);
247 return true;
248 }
249 }
250
251 enum Kind {
252 GENERIC("invoke"),
253 IDENTITY("identity"),
254 CONSTANT("constant"),
255 BOUND_REINVOKER("BMH.reinvoke", "reinvoke"),
256 REINVOKER("MH.reinvoke", "reinvoke"),
257 DELEGATE("MH.delegate", "delegate"),
258 EXACT_LINKER("MH.invokeExact_MT", "invokeExact_MT"),
259 EXACT_INVOKER("MH.exactInvoker", "exactInvoker"),
260 GENERIC_LINKER("MH.invoke_MT", "invoke_MT"),
261 GENERIC_INVOKER("MH.invoker", "invoker"),
262 LINK_TO_TARGET_METHOD("linkToTargetMethod"),
263 LINK_TO_CALL_SITE("linkToCallSite"),
264 DIRECT_INVOKE_VIRTUAL("DMH.invokeVirtual", "invokeVirtual"),
265 DIRECT_INVOKE_SPECIAL("DMH.invokeSpecial", "invokeSpecial"),
266 DIRECT_INVOKE_SPECIAL_IFC("DMH.invokeSpecialIFC", "invokeSpecialIFC"),
267 DIRECT_INVOKE_STATIC("DMH.invokeStatic", "invokeStatic"),
268 DIRECT_NEW_INVOKE_SPECIAL("DMH.newInvokeSpecial", "newInvokeSpecial"),
269 DIRECT_INVOKE_INTERFACE("DMH.invokeInterface", "invokeInterface"),
270 DIRECT_INVOKE_STATIC_INIT("DMH.invokeStaticInit", "invokeStaticInit"),
271 // Start field forms
272 // IJFDL, instance/static differ in method type, can share form
273 // init form only applicable to static
274 FIELD_ACCESS("fieldAccess"),
275 FIELD_ACCESS_INIT("fieldAccessInit"),
276 VOLATILE_FIELD_ACCESS("volatileFieldAccess"),
277 VOLATILE_FIELD_ACCESS_INIT("volatileFieldAccessInit"),
278 // BCSZ need own forms to avoid clashing with basic type I, +-init/volatile
279 FIELD_ACCESS_B("fieldAccessB"),
280 FIELD_ACCESS_INIT_B("fieldAccessInitB"),
281 VOLATILE_FIELD_ACCESS_B("volatileFieldAccessB"),
282 VOLATILE_FIELD_ACCESS_INIT_B("volatileFieldAccessInitB"),
283 FIELD_ACCESS_C("fieldAccessC"),
284 FIELD_ACCESS_INIT_C("fieldAccessInitC"),
285 VOLATILE_FIELD_ACCESS_C("volatileFieldAccessC"),
286 VOLATILE_FIELD_ACCESS_INIT_C("volatileFieldAccessInitC"),
287 FIELD_ACCESS_S("fieldAccessS"),
288 FIELD_ACCESS_INIT_S("fieldAccessInitS"),
289 VOLATILE_FIELD_ACCESS_S("volatileFieldAccessS"),
290 VOLATILE_FIELD_ACCESS_INIT_S("volatileFieldAccessInitS"),
291 FIELD_ACCESS_Z("fieldAccessZ"),
292 FIELD_ACCESS_INIT_Z("fieldAccessInitZ"),
293 VOLATILE_FIELD_ACCESS_Z("volatileFieldAccessZ"),
294 VOLATILE_FIELD_ACCESS_INIT_Z("volatileFieldAccessInitZ"),
295 // cast, nr, flat need their own forms to avoid clashing with L
296 FIELD_ACCESS_CAST("fieldAccessCast"),
297 FIELD_ACCESS_INIT_CAST("fieldAccessInitCast"),
298 VOLATILE_FIELD_ACCESS_CAST("volatileFieldAccessCast"),
299 VOLATILE_FIELD_ACCESS_INIT_CAST("volatileFieldAccessInitCast"),
300 // null-check and put reference, +-cast, +-init/volatile
301 // non-cast forms serve bytecode emulation purpose, which always enforces null checks
302 PUT_NULL_RESTRICTED_REFERENCE("putNullRestrictedReference"),
303 PUT_NULL_RESTRICTED_REFERENCE_INIT("putNullRestrictedReferenceInit"),
304 VOLATILE_PUT_NULL_RESTRICTED_REFERENCE("volatilePutNullRestrictedReference"),
305 VOLATILE_PUT_NULL_RESTRICTED_REFERENCE_INIT("volatilePutNullRestrictedReferenceInit"),
306 PUT_NULL_RESTRICTED_REFERENCE_CAST("putNullRestrictedReferenceCast"),
307 PUT_NULL_RESTRICTED_REFERENCE_CAST_INIT("putNullRestrictedReferenceInitCast"),
308 VOLATILE_PUT_NULL_RESTRICTED_REFERENCE_CAST("volatilePutNullRestrictedReferenceCast"),
309 VOLATILE_PUT_NULL_RESTRICTED_REFERENCE_CAST_INIT("volatilePutNullRestrictedReferenceCastInit"),
310 // flat implies cast, +-init/volatile
311 FIELD_ACCESS_FLAT("fieldAccessFlat"),
312 FIELD_ACCESS_INIT_FLAT("fieldAccessInitFlat"),
313 VOLATILE_FIELD_ACCESS_FLAT("volatileFieldAccessFlat"),
314 VOLATILE_FIELD_ACCESS_INIT_FLAT("volatileFieldAccessInitFlat"),
315 // write guard NR flat, implies cast; +-volatile; no init forms - no flat in static fields yet
316 PUT_NULL_RESTRICTED_FLAT_VALUE("putNullRestrictedFlatValue"),
317 VOLATILE_PUT_NULL_RESTRICTED_FLAT_VALUE("volatilePutNullRestrictedFlatValue"),
318 // End fields
319 TRY_FINALLY("tryFinally"),
320 TABLE_SWITCH("tableSwitch"),
321 COLLECTOR("collector"),
322 LOOP("loop"),
323 GUARD("guard"),
324 GUARD_WITH_CATCH("guardWithCatch"),
325 VARHANDLE_EXACT_INVOKER("VH.exactInvoker"),
326 VARHANDLE_INVOKER("VH.invoker", "invoker"),
327 VARHANDLE_LINKER("VH.invoke_MT", "invoke_MT");
328
329 final String defaultLambdaName;
330 final String methodName;
331
332 private Kind(String defaultLambdaName) {
333 this(defaultLambdaName, defaultLambdaName);
334 }
335
336 private Kind(String defaultLambdaName, String methodName) {
337 this.defaultLambdaName = defaultLambdaName;
338 this.methodName = methodName;
339 }
340 }
341
342 // private version that doesn't do checks or defensive copies
343 private LambdaForm(int arity, int result, boolean forceInline, MethodHandle customized, Name[] names, Kind kind) {
344 this.arity = arity;
345 this.result = result;
346 this.forceInline = forceInline;
347 this.customized = customized;
348 this.names = names;
349 this.kind = kind;
350 this.vmentry = null;
351 this.isCompiled = false;
352 }
353
354 // root factory pre/post processing and calls simple constructor
355 private static LambdaForm create(int arity, Name[] names, int result, boolean forceInline, MethodHandle customized, Kind kind) {
356 names = names.clone();
357 assert(namesOK(arity, names));
358 result = fixResult(result, names);
359
360 boolean canInterpret = normalizeNames(arity, names);
361 LambdaForm form = new LambdaForm(arity, result, forceInline, customized, names, kind);
362 assert(form.nameRefsAreLegal());
363 if (!canInterpret) {
364 form.compileToBytecode();
365 }
366 return form;
367 }
368
369 // derived factories with defaults
370 private static final int DEFAULT_RESULT = LAST_RESULT;
371 private static final boolean DEFAULT_FORCE_INLINE = true;
372 private static final MethodHandle DEFAULT_CUSTOMIZED = null;
373 private static final Kind DEFAULT_KIND = Kind.GENERIC;
374
375 static LambdaForm create(int arity, Name[] names, int result) {
376 return create(arity, names, result, DEFAULT_FORCE_INLINE, DEFAULT_CUSTOMIZED, DEFAULT_KIND);
377 }
378 static LambdaForm create(int arity, Name[] names, int result, Kind kind) {
379 return create(arity, names, result, DEFAULT_FORCE_INLINE, DEFAULT_CUSTOMIZED, kind);
380 }
381 static LambdaForm create(int arity, Name[] names) {
382 return create(arity, names, DEFAULT_RESULT, DEFAULT_FORCE_INLINE, DEFAULT_CUSTOMIZED, DEFAULT_KIND);
383 }
384 static LambdaForm create(int arity, Name[] names, Kind kind) {
385 return create(arity, names, DEFAULT_RESULT, DEFAULT_FORCE_INLINE, DEFAULT_CUSTOMIZED, kind);
386 }
387 static LambdaForm create(int arity, Name[] names, boolean forceInline, Kind kind) {
388 return create(arity, names, DEFAULT_RESULT, forceInline, DEFAULT_CUSTOMIZED, kind);
389 }
390
391 private static int fixResult(int result, Name[] names) {
392 if (result == LAST_RESULT)
393 result = names.length - 1; // might still be void
394 if (result >= 0 && names[result].type == V_TYPE)
395 result = VOID_RESULT;
396 return result;
397 }
398
399 static boolean debugNames() {
400 return DEBUG_NAME_COUNTERS != null;
401 }
402
403 static void associateWithDebugName(LambdaForm form, String name) {
404 assert (debugNames());
405 synchronized (DEBUG_NAMES) {
406 DEBUG_NAMES.put(form, name);
407 }
408 }
409
410 String lambdaName() {
411 if (DEBUG_NAMES != null) {
412 synchronized (DEBUG_NAMES) {
413 String name = DEBUG_NAMES.get(this);
414 if (name == null) {
415 name = generateDebugName();
416 }
417 return name;
418 }
419 }
420 return kind.defaultLambdaName;
421 }
422
423 private String generateDebugName() {
424 assert (debugNames());
425 String debugNameStem = kind.defaultLambdaName;
426 Integer ctr = DEBUG_NAME_COUNTERS.getOrDefault(debugNameStem, 0);
427 DEBUG_NAME_COUNTERS.put(debugNameStem, ctr + 1);
428 StringBuilder buf = new StringBuilder(debugNameStem);
429 int leadingZero = buf.length();
430 buf.append((int) ctr);
431 for (int i = buf.length() - leadingZero; i < 3; i++) {
432 buf.insert(leadingZero, '0');
433 }
434 buf.append('_');
435 buf.append(basicTypeSignature());
436 String name = buf.toString();
437 associateWithDebugName(this, name);
438 return name;
439 }
440
441 private static boolean namesOK(int arity, Name[] names) {
442 for (int i = 0; i < names.length; i++) {
443 Name n = names[i];
444 assert(n != null) : "n is null";
445 if (i < arity)
446 assert( n.isParam()) : n + " is not param at " + i;
447 else
448 assert(!n.isParam()) : n + " is param at " + i;
449 }
450 return true;
451 }
452
453 /** Customize LambdaForm for a particular MethodHandle */
454 LambdaForm customize(MethodHandle mh) {
455 if (customized == mh) {
456 return this;
457 }
458 LambdaForm customForm = LambdaForm.create(arity, names, result, forceInline, mh, kind);
459 if (COMPILE_THRESHOLD >= 0 && isCompiled) {
460 // If shared LambdaForm has been compiled, compile customized version as well.
461 customForm.compileToBytecode();
462 }
463 customForm.transformCache = this; // LambdaFormEditor should always use uncustomized form.
464 return customForm;
465 }
466
467 /** Get uncustomized flavor of the LambdaForm */
468 LambdaForm uncustomize() {
469 if (customized == null) {
470 return this;
471 }
472 assert(transformCache != null); // Customized LambdaForm should always has a link to uncustomized version.
473 LambdaForm uncustomizedForm = (LambdaForm)transformCache;
474 if (COMPILE_THRESHOLD >= 0 && isCompiled) {
475 // If customized LambdaForm has been compiled, compile uncustomized version as well.
476 uncustomizedForm.compileToBytecode();
477 }
478 return uncustomizedForm;
479 }
480
481 /** Renumber and/or replace params so that they are interned and canonically numbered.
482 * @return true if we can interpret
483 */
484 private static boolean normalizeNames(int arity, Name[] names) {
485 Name[] oldNames = names.clone();
486 int maxOutArity = 0;
487 for (int i = 0; i < names.length; i++) {
488 Name n = names[i];
489 names[i] = n.withIndex(i);
490 if (n.arguments != null && maxOutArity < n.arguments.length)
491 maxOutArity = n.arguments.length;
492 }
493 if (oldNames != null) {
494 for (int i = Math.max(1, arity); i < names.length; i++) {
495 Name fixed = names[i].replaceNames(oldNames, names, 0, i);
496 names[i] = fixed.withIndex(i);
497 }
498 }
499 int maxInterned = Math.min(arity, INTERNED_ARGUMENT_LIMIT);
500 boolean needIntern = false;
501 for (int i = 0; i < maxInterned; i++) {
502 Name n = names[i], n2 = internArgument(n);
503 if (n != n2) {
504 names[i] = n2;
505 needIntern = true;
506 }
507 }
508 if (needIntern) {
509 for (int i = arity; i < names.length; i++) {
510 names[i].internArguments();
511 }
512 }
513
514 // return true if we can interpret
515 if (maxOutArity > MethodType.MAX_MH_INVOKER_ARITY) {
516 // Cannot use LF interpreter on very high arity expressions.
517 assert(maxOutArity <= MethodType.MAX_JVM_ARITY);
518 return false;
519 }
520 return true;
521 }
522
523 /**
524 * Check that all embedded Name references are localizable to this lambda,
525 * and are properly ordered after their corresponding definitions.
526 * <p>
527 * Note that a Name can be local to multiple lambdas, as long as
528 * it possesses the same index in each use site.
529 * This allows Name references to be freely reused to construct
530 * fresh lambdas, without confusion.
531 */
532 boolean nameRefsAreLegal() {
533 assert(arity >= 0 && arity <= names.length);
534 assert(result >= -1 && result < names.length);
535 // Do all names possess an index consistent with their local definition order?
536 for (int i = 0; i < arity; i++) {
537 Name n = names[i];
538 assert(n.index() == i) : Arrays.asList(n.index(), i);
539 assert(n.isParam());
540 }
541 // Also, do all local name references
542 for (int i = arity; i < names.length; i++) {
543 Name n = names[i];
544 assert(n.index() == i);
545 for (Object arg : n.arguments) {
546 if (arg instanceof Name n2) {
547 int i2 = n2.index;
548 assert(0 <= i2 && i2 < names.length) : n.debugString() + ": 0 <= i2 && i2 < names.length: 0 <= " + i2 + " < " + names.length;
549 assert(names[i2] == n2) : Arrays.asList("-1-", i, "-2-", n.debugString(), "-3-", i2, "-4-", n2.debugString(), "-5-", names[i2].debugString(), "-6-", this);
550 assert(i2 < i); // ref must come after def!
551 }
552 }
553 }
554 return true;
555 }
556
557 // /** Invoke this form on the given arguments. */
558 // final Object invoke(Object... args) throws Throwable {
559 // // NYI: fit this into the fast path?
560 // return interpretWithArguments(args);
561 // }
562
563 /** Report the return type. */
564 BasicType returnType() {
565 if (result < 0) return V_TYPE;
566 Name n = names[result];
567 return n.type;
568 }
569
570 /** Report the N-th argument type. */
571 BasicType parameterType(int n) {
572 return parameter(n).type;
573 }
574
575 /** Report the N-th argument name. */
576 Name parameter(int n) {
577 Name param = names[n];
578 assert(n < arity && param.isParam());
579 return param;
580 }
581
582 /** Report the N-th argument type constraint. */
583 Object parameterConstraint(int n) {
584 return parameter(n).constraint;
585 }
586
587 /** Report the arity. */
588 int arity() {
589 return arity;
590 }
591
592 /** Report the number of expressions (non-parameter names). */
593 int expressionCount() {
594 return names.length - arity;
595 }
596
597 /** Return the method type corresponding to my basic type signature. */
598 MethodType methodType() {
599 Class<?>[] ptypes = new Class<?>[arity];
600 for (int i = 0; i < arity; ++i) {
601 ptypes[i] = parameterType(i).btClass;
602 }
603 return MethodType.methodType(returnType().btClass, ptypes, true);
604 }
605
606 /** Return ABC_Z, where the ABC are parameter type characters, and Z is the return type character. */
607 final String basicTypeSignature() {
608 StringBuilder buf = new StringBuilder(arity() + 3);
609 for (int i = 0, a = arity(); i < a; i++)
610 buf.append(parameterType(i).basicTypeChar());
611 return buf.append('_').append(returnType().basicTypeChar()).toString();
612 }
613 static int signatureArity(String sig) {
614 assert(isValidSignature(sig));
615 return sig.indexOf('_');
616 }
617 static boolean isValidSignature(String sig) {
618 int arity = sig.indexOf('_');
619 if (arity < 0) return false; // must be of the form *_*
620 int siglen = sig.length();
621 if (siglen != arity + 2) return false; // *_X
622 for (int i = 0; i < siglen; i++) {
623 if (i == arity) continue; // skip '_'
624 char c = sig.charAt(i);
625 if (c == 'V')
626 return (i == siglen - 1 && arity == siglen - 2);
627 if (!isArgBasicTypeChar(c)) return false; // must be [LIJFD]
628 }
629 return true; // [LIJFD]*_[LIJFDV]
630 }
631
632 /**
633 * Check if i-th name is a call to MethodHandleImpl.selectAlternative.
634 */
635 boolean isSelectAlternative(int pos) {
636 // selectAlternative idiom:
637 // t_{n}:L=MethodHandleImpl.selectAlternative(...)
638 // t_{n+1}:?=MethodHandle.invokeBasic(t_{n}, ...)
639 if (pos+1 >= names.length) return false;
640 Name name0 = names[pos];
641 Name name1 = names[pos+1];
642 return name0.refersTo(MethodHandleImpl.class, "selectAlternative") &&
643 name1.isInvokeBasic() &&
644 name1.lastUseIndex(name0) == 0 && // t_{n+1}:?=MethodHandle.invokeBasic(t_{n}, ...)
645 lastUseIndex(name0) == pos+1; // t_{n} is local: used only in t_{n+1}
646 }
647
648 private boolean isMatchingIdiom(int pos, String idiomName, int nArgs) {
649 if (pos+2 >= names.length) return false;
650 Name name0 = names[pos];
651 Name name1 = names[pos+1];
652 Name name2 = names[pos+2];
653 return name1.refersTo(MethodHandleImpl.class, idiomName) &&
654 name0.isInvokeBasic() &&
655 name2.isInvokeBasic() &&
656 name1.lastUseIndex(name0) == nArgs && // t_{n+1}:L=MethodHandleImpl.<invoker>(<args>, t_{n});
657 lastUseIndex(name0) == pos+1 && // t_{n} is local: used only in t_{n+1}
658 name2.lastUseIndex(name1) == 1 && // t_{n+2}:?=MethodHandle.invokeBasic(*, t_{n+1})
659 lastUseIndex(name1) == pos+2; // t_{n+1} is local: used only in t_{n+2}
660 }
661
662 /**
663 * Check if i-th name is a start of GuardWithCatch idiom.
664 */
665 boolean isGuardWithCatch(int pos) {
666 // GuardWithCatch idiom:
667 // t_{n}:L=MethodHandle.invokeBasic(...)
668 // t_{n+1}:L=MethodHandleImpl.guardWithCatch(*, *, *, t_{n});
669 // t_{n+2}:?=MethodHandle.invokeBasic(*, t_{n+1})
670 return isMatchingIdiom(pos, "guardWithCatch", 3);
671 }
672
673 /**
674 * Check if i-th name is a start of the tryFinally idiom.
675 */
676 boolean isTryFinally(int pos) {
677 // tryFinally idiom:
678 // t_{n}:L=MethodHandle.invokeBasic(...)
679 // t_{n+1}:L=MethodHandleImpl.tryFinally(*, *, t_{n})
680 // t_{n+2}:?=MethodHandle.invokeBasic(*, t_{n+1})
681 return isMatchingIdiom(pos, "tryFinally", 2);
682 }
683
684 /**
685 * Check if i-th name is a start of the tableSwitch idiom.
686 */
687 boolean isTableSwitch(int pos) {
688 // tableSwitch idiom:
689 // t_{n}:L=MethodHandle.invokeBasic(...) // args
690 // t_{n+1}:L=MethodHandleImpl.tableSwitch(*, *, *, t_{n})
691 // t_{n+2}:?=MethodHandle.invokeBasic(*, t_{n+1})
692 if (pos + 2 >= names.length) return false;
693
694 final int POS_COLLECT_ARGS = pos;
695 final int POS_TABLE_SWITCH = pos + 1;
696 final int POS_UNBOX_RESULT = pos + 2;
697
698 Name collectArgs = names[POS_COLLECT_ARGS];
699 Name tableSwitch = names[POS_TABLE_SWITCH];
700 Name unboxResult = names[POS_UNBOX_RESULT];
701 return tableSwitch.refersTo(MethodHandleImpl.class, "tableSwitch") &&
702 collectArgs.isInvokeBasic() &&
703 unboxResult.isInvokeBasic() &&
704 tableSwitch.lastUseIndex(collectArgs) == 3 && // t_{n+1}:L=MethodHandleImpl.<invoker>(*, *, *, t_{n});
705 lastUseIndex(collectArgs) == POS_TABLE_SWITCH && // t_{n} is local: used only in t_{n+1}
706 unboxResult.lastUseIndex(tableSwitch) == 1 && // t_{n+2}:?=MethodHandle.invokeBasic(*, t_{n+1})
707 lastUseIndex(tableSwitch) == POS_UNBOX_RESULT; // t_{n+1} is local: used only in t_{n+2}
708 }
709
710 /**
711 * Check if i-th name is a start of the loop idiom.
712 */
713 boolean isLoop(int pos) {
714 // loop idiom:
715 // t_{n}:L=MethodHandle.invokeBasic(...)
716 // t_{n+1}:L=MethodHandleImpl.loop(types, *, t_{n})
717 // t_{n+2}:?=MethodHandle.invokeBasic(*, t_{n+1})
718 return isMatchingIdiom(pos, "loop", 2);
719 }
720
721 /*
722 * Code generation issues:
723 *
724 * Compiled LFs should be reusable in general.
725 * The biggest issue is how to decide when to pull a name into
726 * the bytecode, versus loading a reified form from the MH data.
727 *
728 * For example, an asType wrapper may require execution of a cast
729 * after a call to a MH. The target type of the cast can be placed
730 * as a constant in the LF itself. This will force the cast type
731 * to be compiled into the bytecodes and native code for the MH.
732 * Or, the target type of the cast can be erased in the LF, and
733 * loaded from the MH data. (Later on, if the MH as a whole is
734 * inlined, the data will flow into the inlined instance of the LF,
735 * as a constant, and the end result will be an optimal cast.)
736 *
737 * This erasure of cast types can be done with any use of
738 * reference types. It can also be done with whole method
739 * handles. Erasing a method handle might leave behind
740 * LF code that executes correctly for any MH of a given
741 * type, and load the required MH from the enclosing MH's data.
742 * Or, the erasure might even erase the expected MT.
743 *
744 * Also, for direct MHs, the MemberName of the target
745 * could be erased, and loaded from the containing direct MH.
746 * As a simple case, a LF for all int-valued non-static
747 * field getters would perform a cast on its input argument
748 * (to non-constant base type derived from the MemberName)
749 * and load an integer value from the input object
750 * (at a non-constant offset also derived from the MemberName).
751 * Such MN-erased LFs would be inlinable back to optimized
752 * code, whenever a constant enclosing DMH is available
753 * to supply a constant MN from its data.
754 *
755 * The main problem here is to keep LFs reasonably generic,
756 * while ensuring that hot spots will inline good instances.
757 * "Reasonably generic" means that we don't end up with
758 * repeated versions of bytecode or machine code that do
759 * not differ in their optimized form. Repeated versions
760 * of machine would have the undesirable overheads of
761 * (a) redundant compilation work and (b) extra I$ pressure.
762 * To control repeated versions, we need to be ready to
763 * erase details from LFs and move them into MH data,
764 * whenever those details are not relevant to significant
765 * optimization. "Significant" means optimization of
766 * code that is actually hot.
767 *
768 * Achieving this may require dynamic splitting of MHs, by replacing
769 * a generic LF with a more specialized one, on the same MH,
770 * if (a) the MH is frequently executed and (b) the MH cannot
771 * be inlined into a containing caller, such as an invokedynamic.
772 *
773 * Compiled LFs that are no longer used should be GC-able.
774 * If they contain non-BCP references, they should be properly
775 * interlinked with the class loader(s) that their embedded types
776 * depend on. This probably means that reusable compiled LFs
777 * will be tabulated (indexed) on relevant class loaders,
778 * or else that the tables that cache them will have weak links.
779 */
780
781 /**
782 * Make this LF directly executable, as part of a MethodHandle.
783 * Invariant: Every MH which is invoked must prepare its LF
784 * before invocation.
785 * (In principle, the JVM could do this very lazily,
786 * as a sort of pre-invocation linkage step.)
787 */
788 public void prepare() {
789 if (COMPILE_THRESHOLD == 0 && !forceInterpretation() && !isCompiled) {
790 compileToBytecode();
791 }
792 if (this.vmentry != null) {
793 // already prepared (e.g., a primitive DMH invoker form)
794 return;
795 }
796 MethodType mtype = methodType();
797 MethodTypeForm form = mtype.form();
798
799 MemberName entry = form.cachedInterpretEntry();
800 if (entry == null) {
801 assert (isValidSignature(basicTypeSignature()));
802 entry = InvokerBytecodeGenerator.generateLambdaFormInterpreterEntryPoint(mtype);
803 entry = form.setCachedInterpretEntry(entry);
804 }
805 this.vmentry = entry;
806 // TO DO: Maybe add invokeGeneric, invokeWithArguments
807 }
808
809 private static @Stable PerfCounter LF_FAILED;
810
811 private static PerfCounter failedCompilationCounter() {
812 if (LF_FAILED == null) {
813 LF_FAILED = PerfCounter.newPerfCounter("java.lang.invoke.failedLambdaFormCompilations");
814 }
815 return LF_FAILED;
816 }
817
818 /** Generate optimizable bytecode for this form. */
819 void compileToBytecode() {
820 if (forceInterpretation()) {
821 return; // this should not be compiled
822 }
823 if (vmentry != null && isCompiled) {
824 return; // already compiled somehow
825 }
826
827 // Obtain the invoker MethodType outside of the following try block.
828 // This ensures that an IllegalArgumentException is directly thrown if the
829 // type would have 256 or more parameters
830 MethodType invokerType = methodType();
831 assert(vmentry == null || vmentry.getMethodType().basicType().equals(invokerType));
832 try {
833 vmentry = InvokerBytecodeGenerator.generateCustomizedCode(this, invokerType);
834 if (TRACE_INTERPRETER)
835 traceInterpreter("compileToBytecode", this);
836 isCompiled = true;
837 } catch (InvokerBytecodeGenerator.BytecodeGenerationException bge) {
838 // bytecode generation failed - mark this LambdaForm as to be run in interpretation mode only
839 invocationCounter = -1;
840 failedCompilationCounter().increment();
841 if (LOG_LF_COMPILATION_FAILURE) {
842 System.out.println("LambdaForm compilation failed: " + this);
843 bge.printStackTrace(System.out);
844 }
845 } catch (Error e) {
846 // Pass through any error
847 throw e;
848 } catch (Exception e) {
849 // Wrap any exception
850 throw newInternalError(this.toString(), e);
851 }
852 }
853
854 // The next few routines are called only from assert expressions
855 // They verify that the built-in invokers process the correct raw data types.
856 private static boolean argumentTypesMatch(String sig, Object[] av) {
857 int arity = signatureArity(sig);
858 assert(av.length == arity) : "av.length == arity: av.length=" + av.length + ", arity=" + arity;
859 assert(av[0] instanceof MethodHandle) : "av[0] not instance of MethodHandle: " + av[0];
860 MethodHandle mh = (MethodHandle) av[0];
861 MethodType mt = mh.type();
862 assert(mt.parameterCount() == arity-1);
863 for (int i = 0; i < av.length; i++) {
864 Class<?> pt = (i == 0 ? MethodHandle.class : mt.parameterType(i-1));
865 assert(valueMatches(basicType(sig.charAt(i)), pt, av[i]));
866 }
867 return true;
868 }
869 private static boolean valueMatches(BasicType tc, Class<?> type, Object x) {
870 // The following line is needed because (...)void method handles can use non-void invokers
871 if (type == void.class) tc = V_TYPE; // can drop any kind of value
872 assert tc == basicType(type) : tc + " == basicType(" + type + ")=" + basicType(type);
873 switch (tc) {
874 case I_TYPE: assert checkInt(type, x) : "checkInt(" + type + "," + x +")"; break;
875 case J_TYPE: assert x instanceof Long : "instanceof Long: " + x; break;
876 case F_TYPE: assert x instanceof Float : "instanceof Float: " + x; break;
877 case D_TYPE: assert x instanceof Double : "instanceof Double: " + x; break;
878 case L_TYPE: assert checkRef(type, x) : "checkRef(" + type + "," + x + ")"; break;
879 case V_TYPE: break; // allow anything here; will be dropped
880 default: assert(false);
881 }
882 return true;
883 }
884 private static boolean checkInt(Class<?> type, Object x) {
885 assert(x instanceof Integer);
886 if (type == int.class) return true;
887 Wrapper w = Wrapper.forBasicType(type);
888 assert(w.isSubwordOrInt());
889 Object x1 = Wrapper.INT.wrap(w.wrap(x));
890 return x.equals(x1);
891 }
892 private static boolean checkRef(Class<?> type, Object x) {
893 assert(!type.isPrimitive());
894 if (x == null) return true;
895 if (type.isInterface()) return true;
896 return type.isInstance(x);
897 }
898
899 /** If the invocation count hits the threshold we spin bytecodes and call that subsequently. */
900 private static final int COMPILE_THRESHOLD;
901 static {
902 COMPILE_THRESHOLD = Math.max(-1, MethodHandleStatics.COMPILE_THRESHOLD);
903 }
904 private int invocationCounter = 0; // a value of -1 indicates LambdaForm interpretation mode forever
905
906 private boolean forceInterpretation() {
907 return invocationCounter == -1;
908 }
909
910 /** Interpretively invoke this form on the given arguments. */
911 @Hidden
912 @DontInline
913 Object interpretWithArguments(Object... argumentValues) throws Throwable {
914 if (TRACE_INTERPRETER)
915 return interpretWithArgumentsTracing(argumentValues);
916 checkInvocationCounter();
917 assert(arityCheck(argumentValues));
918 Object[] values = Arrays.copyOf(argumentValues, names.length);
919 for (int i = argumentValues.length; i < values.length; i++) {
920 values[i] = interpretName(names[i], values);
921 }
922 Object rv = (result < 0) ? null : values[result];
923 assert(resultCheck(argumentValues, rv));
924 return rv;
925 }
926
927 /** Evaluate a single Name within this form, applying its function to its arguments. */
928 @Hidden
929 @DontInline
930 Object interpretName(Name name, Object[] values) throws Throwable {
931 if (TRACE_INTERPRETER)
932 traceInterpreter("| interpretName", name.debugString(), (Object[]) null);
933 Object[] arguments = Arrays.copyOf(name.arguments, name.arguments.length, Object[].class);
934 for (int i = 0; i < arguments.length; i++) {
935 Object a = arguments[i];
936 if (a instanceof Name n) {
937 int i2 = n.index();
938 assert(names[i2] == a);
939 a = values[i2];
940 arguments[i] = a;
941 }
942 }
943 return name.function.invokeWithArguments(arguments);
944 }
945
946 private void checkInvocationCounter() {
947 if (COMPILE_THRESHOLD != 0 &&
948 !forceInterpretation() && invocationCounter < COMPILE_THRESHOLD) {
949 invocationCounter++; // benign race
950 if (invocationCounter >= COMPILE_THRESHOLD) {
951 // Replace vmentry with a bytecode version of this LF.
952 compileToBytecode();
953 }
954 }
955 }
956 Object interpretWithArgumentsTracing(Object... argumentValues) throws Throwable {
957 traceInterpreter("[ interpretWithArguments", this, argumentValues);
958 if (!forceInterpretation() && invocationCounter < COMPILE_THRESHOLD) {
959 int ctr = invocationCounter++; // benign race
960 traceInterpreter("| invocationCounter", ctr);
961 if (invocationCounter >= COMPILE_THRESHOLD) {
962 compileToBytecode();
963 }
964 }
965 Object rval;
966 try {
967 assert(arityCheck(argumentValues));
968 Object[] values = Arrays.copyOf(argumentValues, names.length);
969 for (int i = argumentValues.length; i < values.length; i++) {
970 values[i] = interpretName(names[i], values);
971 }
972 rval = (result < 0) ? null : values[result];
973 } catch (Throwable ex) {
974 traceInterpreter("] throw =>", ex);
975 throw ex;
976 }
977 traceInterpreter("] return =>", rval);
978 return rval;
979 }
980
981 static void traceInterpreter(String event, Object obj, Object... args) {
982 if (TRACE_INTERPRETER) {
983 System.out.println("LFI: "+event+" "+(obj != null ? obj : "")+(args != null && args.length != 0 ? Arrays.asList(args) : ""));
984 }
985 }
986 static void traceInterpreter(String event, Object obj) {
987 traceInterpreter(event, obj, (Object[])null);
988 }
989 private boolean arityCheck(Object[] argumentValues) {
990 assert(argumentValues.length == arity) : arity+"!="+Arrays.asList(argumentValues)+".length";
991 // also check that the leading (receiver) argument is somehow bound to this LF:
992 assert(argumentValues[0] instanceof MethodHandle) : "not MH: " + argumentValues[0];
993 MethodHandle mh = (MethodHandle) argumentValues[0];
994 assert(mh.internalForm() == this);
995 // note: argument #0 could also be an interface wrapper, in the future
996 argumentTypesMatch(basicTypeSignature(), argumentValues);
997 return true;
998 }
999 private boolean resultCheck(Object[] argumentValues, Object result) {
1000 MethodHandle mh = (MethodHandle) argumentValues[0];
1001 MethodType mt = mh.type();
1002 assert(valueMatches(returnType(), mt.returnType(), result));
1003 return true;
1004 }
1005
1006 public String toString() {
1007 return debugString(-1);
1008 }
1009
1010 String debugString(int indentLevel) {
1011 String prefix = MethodHandle.debugPrefix(indentLevel);
1012 String lambdaName = lambdaName();
1013 StringBuilder buf = new StringBuilder(lambdaName);
1014 buf.append("=Lambda(");
1015 for (int i = 0; i < names.length; i++) {
1016 if (i == arity) buf.append(")=>{");
1017 Name n = names[i];
1018 if (i >= arity) buf.append("\n ").append(prefix);
1019 buf.append(n.paramString());
1020 if (i < arity) {
1021 if (i+1 < arity) buf.append(",");
1022 continue;
1023 }
1024 buf.append("=").append(n.exprString());
1025 buf.append(";");
1026 }
1027 if (arity == names.length) buf.append(")=>{");
1028 buf.append(result < 0 ? "void" : names[result]).append("}");
1029 if (TRACE_INTERPRETER) {
1030 // Extra verbosity:
1031 buf.append(":").append(basicTypeSignature());
1032 buf.append("/").append(vmentry);
1033 }
1034 return buf.toString();
1035 }
1036
1037 @Override
1038 public boolean equals(Object obj) {
1039 return obj instanceof LambdaForm lf && equals(lf);
1040 }
1041 public boolean equals(LambdaForm that) {
1042 if (this.result != that.result) return false;
1043 return Arrays.equals(this.names, that.names);
1044 }
1045 public int hashCode() {
1046 return result + 31 * Arrays.hashCode(names);
1047 }
1048 LambdaFormEditor editor() {
1049 return LambdaFormEditor.lambdaFormEditor(this);
1050 }
1051
1052 boolean contains(Name name) {
1053 int pos = name.index();
1054 if (pos >= 0) {
1055 return pos < names.length && name.equals(names[pos]);
1056 }
1057 for (int i = arity; i < names.length; i++) {
1058 if (name.equals(names[i]))
1059 return true;
1060 }
1061 return false;
1062 }
1063
1064 @AOTSafeClassInitializer
1065 static class NamedFunction {
1066 final MemberName member;
1067 private @Stable MethodHandle resolvedHandle;
1068 private @Stable MethodType type;
1069
1070 NamedFunction(MethodHandle resolvedHandle) {
1071 this(resolvedHandle.internalMemberName(), resolvedHandle);
1072 }
1073 NamedFunction(MemberName member, MethodHandle resolvedHandle) {
1074 this.member = member;
1075 this.resolvedHandle = resolvedHandle;
1076 // The following assert is almost always correct, but will fail for corner cases, such as PrivateInvokeTest.
1077 //assert(!isInvokeBasic(member));
1078 }
1079 NamedFunction(MethodType basicInvokerType) {
1080 assert(basicInvokerType == basicInvokerType.basicType()) : basicInvokerType;
1081 if (basicInvokerType.parameterSlotCount() < MethodType.MAX_MH_INVOKER_ARITY) {
1082 this.resolvedHandle = basicInvokerType.invokers().basicInvoker();
1083 this.member = resolvedHandle.internalMemberName();
1084 } else {
1085 // necessary to pass BigArityTest
1086 this.member = Invokers.invokeBasicMethod(basicInvokerType);
1087 }
1088 assert(isInvokeBasic(member));
1089 }
1090
1091 private static boolean isInvokeBasic(MemberName member) {
1092 return member != null &&
1093 member.getDeclaringClass() == MethodHandle.class &&
1094 "invokeBasic".equals(member.getName());
1095 }
1096
1097 // The next 2 constructors are used to break circular dependencies on MH.invokeStatic, etc.
1098 // Any LambdaForm containing such a member is not interpretable.
1099 // This is OK, since all such LFs are prepared with special primitive vmentry points.
1100 // And even without the resolvedHandle, the name can still be compiled and optimized.
1101 NamedFunction(Method method) {
1102 this(new MemberName(method));
1103 }
1104 NamedFunction(MemberName member) {
1105 this(member, null);
1106 }
1107
1108 MethodHandle resolvedHandle() {
1109 if (resolvedHandle == null) resolve();
1110 return resolvedHandle;
1111 }
1112
1113 synchronized void resolve() {
1114 if (resolvedHandle == null) {
1115 resolvedHandle = DirectMethodHandle.make(member);
1116 }
1117 }
1118
1119 @Override
1120 public boolean equals(Object other) {
1121 if (this == other) return true;
1122 if (other == null) return false;
1123 return (other instanceof NamedFunction that)
1124 && this.member != null
1125 && this.member.equals(that.member);
1126 }
1127
1128 @Override
1129 public int hashCode() {
1130 if (member != null)
1131 return member.hashCode();
1132 return super.hashCode();
1133 }
1134
1135 static final MethodType INVOKER_METHOD_TYPE =
1136 MethodType.methodType(Object.class, MethodHandle.class, Object[].class);
1137
1138 private static MethodHandle computeInvoker(MethodTypeForm typeForm) {
1139 typeForm = typeForm.basicType().form(); // normalize to basic type
1140 MethodHandle mh = typeForm.cachedMethodHandle(MethodTypeForm.MH_NF_INV);
1141 if (mh != null) return mh;
1142 MemberName invoker = InvokerBytecodeGenerator.generateNamedFunctionInvoker(typeForm); // this could take a while
1143 mh = DirectMethodHandle.make(invoker);
1144 MethodHandle mh2 = typeForm.cachedMethodHandle(MethodTypeForm.MH_NF_INV);
1145 if (mh2 != null) return mh2; // benign race
1146 if (!mh.type().equals(INVOKER_METHOD_TYPE))
1147 throw newInternalError(mh.debugString());
1148 return typeForm.setCachedMethodHandle(MethodTypeForm.MH_NF_INV, mh);
1149 }
1150
1151 @Hidden
1152 Object invokeWithArguments(Object... arguments) throws Throwable {
1153 // If we have a cached invoker, call it right away.
1154 // NOTE: The invoker always returns a reference value.
1155 if (TRACE_INTERPRETER) return invokeWithArgumentsTracing(arguments);
1156 return invoker().invokeBasic(resolvedHandle(), arguments);
1157 }
1158
1159 @Hidden
1160 Object invokeWithArgumentsTracing(Object[] arguments) throws Throwable {
1161 Object rval;
1162 try {
1163 traceInterpreter("[ call", this, arguments);
1164 // resolvedHandle might be uninitialized, ok for tracing
1165 if (resolvedHandle == null) {
1166 traceInterpreter("| resolve", this);
1167 resolvedHandle();
1168 }
1169 rval = invoker().invokeBasic(resolvedHandle(), arguments);
1170 } catch (Throwable ex) {
1171 traceInterpreter("] throw =>", ex);
1172 throw ex;
1173 }
1174 traceInterpreter("] return =>", rval);
1175 return rval;
1176 }
1177
1178 private MethodHandle invoker() {
1179 return computeInvoker(methodType().form());
1180 }
1181
1182 MethodType methodType() {
1183 MethodType type = this.type;
1184 if (type == null) {
1185 this.type = type = calculateMethodType(member, resolvedHandle);
1186 }
1187 return type;
1188 }
1189
1190 private static MethodType calculateMethodType(MemberName member, MethodHandle resolvedHandle) {
1191 if (resolvedHandle != null) {
1192 return resolvedHandle.type();
1193 } else {
1194 // only for certain internal LFs during bootstrapping
1195 return member.getInvocationType();
1196 }
1197 }
1198
1199 MemberName member() {
1200 assert(assertMemberIsConsistent());
1201 return member;
1202 }
1203
1204 // Called only from assert.
1205 private boolean assertMemberIsConsistent() {
1206 if (resolvedHandle instanceof DirectMethodHandle) {
1207 MemberName m = resolvedHandle.internalMemberName();
1208 assert(m.equals(member));
1209 }
1210 return true;
1211 }
1212
1213 Class<?> memberDeclaringClassOrNull() {
1214 return (member == null) ? null : member.getDeclaringClass();
1215 }
1216
1217 BasicType returnType() {
1218 return basicType(methodType().returnType());
1219 }
1220
1221 BasicType parameterType(int n) {
1222 return basicType(methodType().parameterType(n));
1223 }
1224
1225 int arity() {
1226 return methodType().parameterCount();
1227 }
1228
1229 public String toString() {
1230 if (member == null) return String.valueOf(resolvedHandle);
1231 return member.getDeclaringClass().getSimpleName()+"."+member.getName();
1232 }
1233
1234 public boolean isIdentity() {
1235 return this.equals(identity(returnType()));
1236 }
1237
1238 public MethodHandleImpl.Intrinsic intrinsicName() {
1239 return resolvedHandle != null
1240 ? resolvedHandle.intrinsicName()
1241 : MethodHandleImpl.Intrinsic.NONE;
1242 }
1243
1244 public Object intrinsicData() {
1245 return resolvedHandle != null
1246 ? resolvedHandle.intrinsicData()
1247 : null;
1248 }
1249 }
1250
1251 public static String basicTypeSignature(MethodType type) {
1252 int params = type.parameterCount();
1253 char[] sig = new char[params + 2];
1254 int sigp = 0;
1255 while (sigp < params) {
1256 sig[sigp] = basicTypeChar(type.parameterType(sigp++));
1257 }
1258 sig[sigp++] = '_';
1259 sig[sigp++] = basicTypeChar(type.returnType());
1260 assert(sigp == sig.length);
1261 return String.valueOf(sig);
1262 }
1263
1264 /** Hack to make signatures more readable when they show up in method names.
1265 * Signature should start with a sequence of uppercase ASCII letters.
1266 * Runs of three or more are replaced by a single letter plus a decimal repeat count.
1267 * A tail of anything other than uppercase ASCII is passed through unchanged.
1268 * @param signature sequence of uppercase ASCII letters with possible repetitions
1269 * @return same sequence, with repetitions counted by decimal numerals
1270 */
1271 public static String shortenSignature(String signature) {
1272 final int NO_CHAR = -1, MIN_RUN = 3;
1273 int c0, c1 = NO_CHAR, c1reps = 0;
1274 StringBuilder buf = null;
1275 int len = signature.length();
1276 if (len < MIN_RUN) return signature;
1277 for (int i = 0; i <= len; i++) {
1278 if (c1 != NO_CHAR && !('A' <= c1 && c1 <= 'Z')) {
1279 // wrong kind of char; bail out here
1280 if (buf != null) {
1281 buf.append(signature, i - c1reps, len);
1282 }
1283 break;
1284 }
1285 // shift in the next char:
1286 c0 = c1; c1 = (i == len ? NO_CHAR : signature.charAt(i));
1287 if (c1 == c0) { ++c1reps; continue; }
1288 // shift in the next count:
1289 int c0reps = c1reps; c1reps = 1;
1290 // end of a character run
1291 if (c0reps < MIN_RUN) {
1292 if (buf != null) {
1293 while (--c0reps >= 0)
1294 buf.append((char)c0);
1295 }
1296 continue;
1297 }
1298 // found three or more in a row
1299 if (buf == null)
1300 buf = new StringBuilder().append(signature, 0, i - c0reps);
1301 buf.append((char)c0).append(c0reps);
1302 }
1303 return (buf == null) ? signature : buf.toString();
1304 }
1305
1306 static final class Name {
1307 final BasicType type;
1308 final short index;
1309 final NamedFunction function;
1310 final Object constraint; // additional type information, if not null
1311 @Stable final Object[] arguments;
1312
1313 private static final Object[] EMPTY_ARGS = new Object[0];
1314
1315 private Name(int index, BasicType type, NamedFunction function, Object[] arguments, Object constraint) {
1316 this.index = (short)index;
1317 this.type = type;
1318 this.function = function;
1319 this.arguments = arguments;
1320 this.constraint = constraint;
1321 assert(this.index == index && typesMatch(function, arguments));
1322 assert(constraint == null || isParam()); // only params have constraints
1323 assert(constraint == null || constraint instanceof ClassSpecializer.SpeciesData || constraint instanceof Class);
1324 }
1325
1326 Name(MethodHandle function, Object... arguments) {
1327 this(new NamedFunction(function), arguments);
1328 }
1329 Name(MethodType functionType, Object... arguments) {
1330 this(new NamedFunction(functionType), arguments);
1331 assert(arguments[0] instanceof Name name && name.type == L_TYPE);
1332 }
1333 Name(MemberName function, Object... arguments) {
1334 this(new NamedFunction(function), arguments);
1335 }
1336 Name(NamedFunction function) {
1337 this(-1, function.returnType(), function, EMPTY_ARGS, null);
1338 }
1339 Name(NamedFunction function, Object arg) {
1340 this(-1, function.returnType(), function, new Object[] { arg }, null);
1341 }
1342 Name(NamedFunction function, Object arg0, Object arg1) {
1343 this(-1, function.returnType(), function, new Object[] { arg0, arg1 }, null);
1344 }
1345 Name(NamedFunction function, Object... arguments) {
1346 this(-1, function.returnType(), function, Arrays.copyOf(arguments, arguments.length, Object[].class), null);
1347 }
1348 /** Create a raw parameter of the given type, with an expected index. */
1349 Name(int index, BasicType type) {
1350 this(index, type, null, null, null);
1351 }
1352 /** Create a raw parameter of the given type. */
1353 Name(BasicType type) { this(-1, type); }
1354
1355 BasicType type() { return type; }
1356 int index() { return index; }
1357
1358 char typeChar() {
1359 return type.btChar;
1360 }
1361
1362 Name withIndex(int i) {
1363 if (i == this.index) return this;
1364 return new Name(i, type, function, arguments, constraint);
1365 }
1366
1367 Name withConstraint(Object constraint) {
1368 if (constraint == this.constraint) return this;
1369 return new Name(index, type, function, arguments, constraint);
1370 }
1371
1372 Name replaceName(Name oldName, Name newName) { // FIXME: use replaceNames uniformly
1373 if (oldName == newName) return this;
1374 @SuppressWarnings("LocalVariableHidesMemberVariable")
1375 Object[] arguments = this.arguments;
1376 if (arguments == null) return this;
1377 boolean replaced = false;
1378 for (int j = 0; j < arguments.length; j++) {
1379 if (arguments[j] == oldName) {
1380 if (!replaced) {
1381 replaced = true;
1382 arguments = arguments.clone();
1383 }
1384 arguments[j] = newName;
1385 }
1386 }
1387 if (!replaced) return this;
1388 return new Name(function, arguments);
1389 }
1390 /** In the arguments of this Name, replace oldNames[i] pairwise by newNames[i].
1391 * Limit such replacements to {@code start<=i<end}. Return possibly changed self.
1392 */
1393 Name replaceNames(Name[] oldNames, Name[] newNames, int start, int end) {
1394 if (start >= end) return this;
1395 @SuppressWarnings("LocalVariableHidesMemberVariable")
1396 Object[] arguments = this.arguments;
1397 boolean replaced = false;
1398 eachArg:
1399 for (int j = 0; j < arguments.length; j++) {
1400 if (arguments[j] instanceof Name n) {
1401 int check = n.index;
1402 // harmless check to see if the thing is already in newNames:
1403 if (check >= 0 && check < newNames.length && n == newNames[check])
1404 continue eachArg;
1405 // n might not have the correct index: n != oldNames[n.index].
1406 for (int i = start; i < end; i++) {
1407 if (n == oldNames[i]) {
1408 if (n == newNames[i])
1409 continue eachArg;
1410 if (!replaced) {
1411 replaced = true;
1412 arguments = arguments.clone();
1413 }
1414 arguments[j] = newNames[i];
1415 continue eachArg;
1416 }
1417 }
1418 }
1419 }
1420 if (!replaced) return this;
1421 return new Name(function, arguments);
1422 }
1423 void internArguments() {
1424 @SuppressWarnings("LocalVariableHidesMemberVariable")
1425 Object[] arguments = this.arguments;
1426 for (int j = 0; j < arguments.length; j++) {
1427 if (arguments[j] instanceof Name n) {
1428 if (n.isParam() && n.index < INTERNED_ARGUMENT_LIMIT)
1429 arguments[j] = internArgument(n);
1430 }
1431 }
1432 }
1433 boolean isParam() {
1434 return function == null;
1435 }
1436
1437 boolean refersTo(Class<?> declaringClass, String methodName) {
1438 return function != null &&
1439 function.member() != null && function.member().refersTo(declaringClass, methodName);
1440 }
1441
1442 /**
1443 * Check if MemberName is a call to MethodHandle.invokeBasic.
1444 */
1445 boolean isInvokeBasic() {
1446 if (function == null)
1447 return false;
1448 if (arguments.length < 1)
1449 return false; // must have MH argument
1450 MemberName member = function.member();
1451 return member != null && member.refersTo(MethodHandle.class, "invokeBasic") &&
1452 !member.isPublic() && !member.isStatic();
1453 }
1454
1455 /**
1456 * Check if MemberName is a call to MethodHandle.linkToStatic, etc.
1457 */
1458 boolean isLinkerMethodInvoke() {
1459 if (function == null)
1460 return false;
1461 if (arguments.length < 1)
1462 return false; // must have MH argument
1463 MemberName member = function.member();
1464 return member != null &&
1465 member.getDeclaringClass() == MethodHandle.class &&
1466 !member.isPublic() && member.isStatic() &&
1467 member.getName().startsWith("linkTo");
1468 }
1469
1470 public String toString() {
1471 return (isParam()?"a":"t")+(index >= 0 ? index : System.identityHashCode(this))+":"+typeChar();
1472 }
1473 public String debugString() {
1474 String s = paramString();
1475 return (function == null) ? s : s + "=" + exprString();
1476 }
1477 public String paramString() {
1478 String s = toString();
1479 Object c = constraint;
1480 if (c == null)
1481 return s;
1482 if (c instanceof Class<?> cl) c = cl.getSimpleName();
1483 return s + "/" + c;
1484 }
1485 public String exprString() {
1486 if (function == null) return toString();
1487 StringBuilder buf = new StringBuilder(function.toString());
1488 buf.append("(");
1489 String cma = "";
1490 for (Object a : arguments) {
1491 buf.append(cma); cma = ",";
1492 if (a instanceof Name || a instanceof Integer)
1493 buf.append(a);
1494 else
1495 buf.append("(").append(a).append(")");
1496 }
1497 buf.append(")");
1498 return buf.toString();
1499 }
1500
1501 private boolean typesMatch(NamedFunction function, Object ... arguments) {
1502 if (arguments == null) {
1503 assert(function == null);
1504 return true;
1505 }
1506 assert(arguments.length == function.arity()) : "arity mismatch: arguments.length=" + arguments.length + " == function.arity()=" + function.arity() + " in " + debugString();
1507 for (int i = 0; i < arguments.length; i++) {
1508 assert (typesMatch(function.parameterType(i), arguments[i])) : "types don't match: function.parameterType(" + i + ")=" + function.parameterType(i) + ", arguments[" + i + "]=" + arguments[i] + " in " + debugString();
1509 }
1510 return true;
1511 }
1512
1513 private static boolean typesMatch(BasicType parameterType, Object object) {
1514 if (object instanceof Name name) {
1515 return name.type == parameterType;
1516 }
1517 switch (parameterType) {
1518 case I_TYPE: return object instanceof Integer;
1519 case J_TYPE: return object instanceof Long;
1520 case F_TYPE: return object instanceof Float;
1521 case D_TYPE: return object instanceof Double;
1522 }
1523 assert(parameterType == L_TYPE);
1524 return true;
1525 }
1526
1527 /** Return the index of the last occurrence of n in the argument array.
1528 * Return -1 if the name is not used.
1529 */
1530 int lastUseIndex(Name n) {
1531 Object[] arguments = this.arguments;
1532 if (arguments == null) return -1;
1533 for (int i = arguments.length; --i >= 0; ) {
1534 if (arguments[i] == n) return i;
1535 }
1536 return -1;
1537 }
1538
1539 public boolean equals(Name that) {
1540 if (this == that) return true;
1541 if (isParam())
1542 // each parameter is a unique atom
1543 return false; // this != that
1544 return
1545 //this.index == that.index &&
1546 this.type == that.type &&
1547 this.function.equals(that.function) &&
1548 Arrays.equals(this.arguments, that.arguments);
1549 }
1550 @Override
1551 public boolean equals(Object x) {
1552 return x instanceof Name n && equals(n);
1553 }
1554 @Override
1555 public int hashCode() {
1556 if (isParam())
1557 return index | (type.ordinal() << 8);
1558 return function.hashCode() ^ Arrays.hashCode(arguments);
1559 }
1560 }
1561
1562 /** Return the index of the last name which contains n as an argument.
1563 * Return -1 if the name is not used. Return names.length if it is the return value.
1564 */
1565 int lastUseIndex(Name n) {
1566 int ni = n.index, nmax = names.length;
1567 assert(names[ni] == n);
1568 if (result == ni) return nmax; // live all the way beyond the end
1569 for (int i = nmax; --i > ni; ) {
1570 if (names[i].lastUseIndex(n) >= 0)
1571 return i;
1572 }
1573 return -1;
1574 }
1575
1576 /** Return the number of times n is used as an argument or return value. */
1577 int useCount(Name n) {
1578 int count = (result == n.index) ? 1 : 0;
1579 int i = Math.max(n.index + 1, arity);
1580 Name[] names = this.names;
1581 while (i < names.length) {
1582 Object[] arguments = names[i++].arguments;
1583 if (arguments != null) {
1584 for (Object argument : arguments) {
1585 if (argument == n) {
1586 count++;
1587 }
1588 }
1589 }
1590 }
1591 return count;
1592 }
1593
1594 static Name argument(int which, BasicType type) {
1595 if (which >= INTERNED_ARGUMENT_LIMIT)
1596 return new Name(which, type);
1597 return INTERNED_ARGUMENTS[type.ordinal()][which];
1598 }
1599 static Name internArgument(Name n) {
1600 assert(n.isParam()) : "not param: " + n;
1601 assert(n.index < INTERNED_ARGUMENT_LIMIT);
1602 if (n.constraint != null) return n;
1603 return argument(n.index, n.type);
1604 }
1605 static Name[] arguments(int extra, MethodType types) {
1606 int length = types.parameterCount();
1607 Name[] names = new Name[length + extra];
1608 for (int i = 0; i < length; i++)
1609 names[i] = argument(i, basicType(types.parameterType(i)));
1610 return names;
1611 }
1612
1613 static Name[] invokeArguments(int extra, MethodType types) {
1614 int length = types.parameterCount();
1615 Name[] names = new Name[length + extra + 1];
1616 names[0] = argument(0, L_TYPE);
1617 for (int i = 0; i < length; i++)
1618 names[i + 1] = argument(i + 1, basicType(types.parameterType(i)));
1619 return names;
1620 }
1621
1622 static final int INTERNED_ARGUMENT_LIMIT = 10;
1623 private static final Name[][] INTERNED_ARGUMENTS
1624 = new Name[ARG_TYPE_LIMIT][INTERNED_ARGUMENT_LIMIT];
1625 static {
1626 for (BasicType type : BasicType.ARG_TYPES) {
1627 int ord = type.ordinal();
1628 for (int i = 0; i < INTERNED_ARGUMENTS[ord].length; i++) {
1629 INTERNED_ARGUMENTS[ord][i] = new Name(i, type);
1630 }
1631 }
1632 }
1633
1634 private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
1635
1636 static LambdaForm identityForm(BasicType type) {
1637 int ord = type.ordinal();
1638 LambdaForm form = LF_identity[ord];
1639 if (form != null) {
1640 return form;
1641 }
1642 createIdentityForm(type);
1643 return LF_identity[ord];
1644 }
1645
1646 static NamedFunction identity(BasicType type) {
1647 int ord = type.ordinal();
1648 NamedFunction function = NF_identity[ord];
1649 if (function != null) {
1650 return function;
1651 }
1652 createIdentityForm(type);
1653 return NF_identity[ord];
1654 }
1655
1656 static LambdaForm constantForm(BasicType type) {
1657 assert type != null && type != V_TYPE : type;
1658 var cached = LF_constant[type.ordinal()];
1659 if (cached != null)
1660 return cached;
1661 return createConstantForm(type);
1662 }
1663
1664 private static LambdaForm createConstantForm(BasicType type) {
1665 UNSAFE.ensureClassInitialized(BoundMethodHandle.class); // defend access to SimpleMethodHandle
1666 var species = SimpleMethodHandle.BMH_SPECIES.extendWith(type);
1667 var carrier = argument(0, L_TYPE).withConstraint(species); // BMH bound with data
1668 Name[] constNames = new Name[] { carrier, new Name(species.getterFunction(0), carrier) };
1669 return LF_constant[type.ordinal()] = create(1, constNames, Kind.CONSTANT);
1670 }
1671
1672 private static final @Stable LambdaForm[] LF_identity = new LambdaForm[TYPE_LIMIT];
1673 private static final @Stable NamedFunction[] NF_identity = new NamedFunction[TYPE_LIMIT];
1674 private static final @Stable LambdaForm[] LF_constant = new LambdaForm[ARG_TYPE_LIMIT]; // no void
1675
1676 private static final Object createIdentityFormLock = new Object();
1677 private static void createIdentityForm(BasicType type) {
1678 // Avoid racy initialization during bootstrap
1679 UNSAFE.ensureClassInitialized(BoundMethodHandle.class);
1680 synchronized (createIdentityFormLock) {
1681 final int ord = type.ordinal();
1682 LambdaForm idForm = LF_identity[ord];
1683 if (idForm != null) {
1684 return;
1685 }
1686 char btChar = type.basicTypeChar();
1687 boolean isVoid = (type == V_TYPE);
1688 Class<?> btClass = type.btClass;
1689 MethodType idType = (isVoid) ? MethodType.methodType(btClass) : MethodType.methodType(btClass, btClass);
1690
1691 // Look up symbolic names. It might not be necessary to have these,
1692 // but if we need to emit direct references to bytecodes, it helps.
1693 MemberName idMem = new MemberName(LambdaForm.class, "identity_"+btChar, idType, REF_invokeStatic);
1694 try {
1695 idMem = IMPL_NAMES.resolveOrFail(REF_invokeStatic, idMem, null, LM_TRUSTED, NoSuchMethodException.class);
1696 } catch (IllegalAccessException|NoSuchMethodException ex) {
1697 throw newInternalError(ex);
1698 }
1699
1700 NamedFunction idFun;
1701
1702 // Create the LFs and NamedFunctions. Precompiling LFs to byte code is needed to break circular
1703 // bootstrap dependency on this method in case we're interpreting LFs
1704 if (isVoid) {
1705 Name[] idNames = new Name[] { argument(0, L_TYPE) };
1706 idForm = LambdaForm.create(1, idNames, VOID_RESULT, Kind.IDENTITY);
1707 idForm.compileToBytecode();
1708 idFun = new NamedFunction(idMem, SimpleMethodHandle.make(idMem.getInvocationType(), idForm));
1709 } else {
1710 Name[] idNames = new Name[] { argument(0, L_TYPE), argument(1, type) };
1711 idForm = LambdaForm.create(2, idNames, 1, Kind.IDENTITY);
1712 idForm.compileToBytecode();
1713 idFun = new NamedFunction(idMem, MethodHandleImpl.makeIntrinsic(idMem.getInvocationType(), idForm,
1714 MethodHandleImpl.Intrinsic.IDENTITY));
1715 }
1716
1717 LF_identity[ord] = idForm;
1718 NF_identity[ord] = idFun;
1719
1720 assert(idFun.isIdentity());
1721 }
1722 }
1723
1724 // Avoid appealing to ValueConversions at bootstrap time:
1725 private static int identity_I(int x) { return x; }
1726 private static long identity_J(long x) { return x; }
1727 private static float identity_F(float x) { return x; }
1728 private static double identity_D(double x) { return x; }
1729 private static Object identity_L(Object x) { return x; }
1730 private static void identity_V() { return; }
1731 /**
1732 * Internal marker for byte-compiled LambdaForms.
1733 */
1734 /*non-public*/
1735 @Target(ElementType.METHOD)
1736 @Retention(RetentionPolicy.RUNTIME)
1737 @interface Compiled {
1738 }
1739
1740 private static final HashMap<String,Integer> DEBUG_NAME_COUNTERS;
1741 private static final HashMap<LambdaForm,String> DEBUG_NAMES;
1742 static {
1743 if (debugEnabled()) {
1744 DEBUG_NAME_COUNTERS = new HashMap<>();
1745 DEBUG_NAMES = new HashMap<>();
1746 } else {
1747 DEBUG_NAME_COUNTERS = null;
1748 DEBUG_NAMES = null;
1749 }
1750 }
1751
1752 static {
1753 // The Holder class will contain pre-generated forms resolved
1754 // using MemberName.getFactory(). However, that doesn't initialize the
1755 // class, which subtly breaks inlining etc. By forcing
1756 // initialization of the Holder class we avoid these issues.
1757 UNSAFE.ensureClassInitialized(Holder.class);
1758 }
1759
1760 /// Holds pre-generated bytecode for common lambda forms.
1761 ///
1762 /// This class may be substituted in the JDK's modules image, or in an AOT
1763 /// cache, by a version generated by [GenerateJLIClassesHelper].
1764 ///
1765 /// The method names of this class are internal tokens recognized by
1766 /// [InvokerBytecodeGenerator#lookupPregenerated] and are subject to change.
1767 @AOTSafeClassInitializer
1768 final class Holder {}
1769
1770 // The following hack is necessary in order to suppress TRACE_INTERPRETER
1771 // during execution of the static initializes of this class.
1772 // Turning on TRACE_INTERPRETER too early will cause
1773 // stack overflows and other misbehavior during attempts to trace events
1774 // that occur during LambdaForm.<clinit>.
1775 // Therefore, do not move this line higher in this file, and do not remove.
1776 private static final boolean TRACE_INTERPRETER = MethodHandleStatics.TRACE_INTERPRETER;
1777 }