< prev index next >

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

Print this page
rev 15353 : 8164044: Generate the corresponding BoundMethodHandle to all generated DirectMethodHandles
Reviewed-by: vlivanov, mhaupt

*** 39,48 **** --- 39,49 ---- import java.util.HashMap; import static java.lang.invoke.LambdaForm.BasicType.*; import static java.lang.invoke.MethodHandleNatives.Constants.REF_invokeStatic; import static java.lang.invoke.MethodHandleStatics.*; + import java.util.Objects; /** * The symbolic, non-executable form of a method handle's invocation semantics. * It consists of a series of names. * The first N (N=arity) names are parameters,
*** 125,134 **** --- 126,136 ---- final int result; final boolean forceInline; final MethodHandle customized; @Stable final Name[] names; final String debugName; + final Kind kind; MemberName vmentry; // low-level behavior, or null if not yet prepared private boolean isCompiled; // Either a LambdaForm cache (managed by LambdaFormEditor) or a link to uncustomized version (for customized LF) volatile Object transformCache;
*** 264,300 **** assert !Arrays.asList(ARG_TYPES).contains(V_TYPE); return true; } } LambdaForm(String debugName, int arity, Name[] names, int result) { ! this(debugName, arity, names, result, /*forceInline=*/true, /*customized=*/null); } LambdaForm(String debugName, int arity, Name[] names, int result, boolean forceInline, MethodHandle customized) { assert(namesOK(arity, names)); this.arity = arity; this.result = fixResult(result, names); this.names = names.clone(); this.debugName = fixDebugName(debugName); this.forceInline = forceInline; this.customized = customized; int maxOutArity = normalize(); if (maxOutArity > MethodType.MAX_MH_INVOKER_ARITY) { // Cannot use LF interpreter on very high arity expressions. assert(maxOutArity <= MethodType.MAX_JVM_ARITY); compileToBytecode(); } } LambdaForm(String debugName, int arity, Name[] names) { ! this(debugName, arity, names, LAST_RESULT, /*forceInline=*/true, /*customized=*/null); } LambdaForm(String debugName, int arity, Name[] names, boolean forceInline) { ! this(debugName, arity, names, LAST_RESULT, forceInline, /*customized=*/null); } LambdaForm(String debugName, Name[] formals, Name[] temps, Name result) { this(debugName, formals.length, buildNames(formals, temps, result), LAST_RESULT, /*forceInline=*/true, /*customized=*/null); --- 266,341 ---- assert !Arrays.asList(ARG_TYPES).contains(V_TYPE); return true; } } + enum Kind { + GENERIC(""), + BOUND_REINVOKER("BMH.reinvoke"), + REINVOKER("MH.reinvoke"), + DELEGATE("MH.delegate"), + DIRECT_INVOKE_VIRTUAL("DMH.invokeVirtual"), + DIRECT_INVOKE_SPECIAL("DMH.invokeSpecial"), + DIRECT_INVOKE_STATIC("DMH.invokeStatic"), + DIRECT_NEW_INVOKE_SPECIAL("DMH.newInvokeSpecial"), + DIRECT_INVOKE_INTERFACE("DMH.invokeInterface"), + DIRECT_INVOKE_STATIC_INIT("DMH.invokeStaticInit"); + + final String defaultLambdaName; + final String methodName; + + private Kind(String defaultLambdaName) { + this.defaultLambdaName = defaultLambdaName; + int p = defaultLambdaName.indexOf('.'); + if (p > -1) { + this.methodName = defaultLambdaName.substring(p + 1); + } else { + this.methodName = defaultLambdaName; + } + } + } + LambdaForm(String debugName, int arity, Name[] names, int result) { ! this(debugName, arity, names, result, /*forceInline=*/true, /*customized=*/null, Kind.GENERIC); ! } ! LambdaForm(String debugName, ! int arity, Name[] names, int result, Kind kind) { ! this(debugName, arity, names, result, /*forceInline=*/true, /*customized=*/null, kind); } LambdaForm(String debugName, int arity, Name[] names, int result, boolean forceInline, MethodHandle customized) { + this(debugName, arity, names, result, forceInline, customized, Kind.GENERIC); + } + LambdaForm(String debugName, + int arity, Name[] names, int result, boolean forceInline, MethodHandle customized, Kind kind) { assert(namesOK(arity, names)); this.arity = arity; this.result = fixResult(result, names); this.names = names.clone(); this.debugName = fixDebugName(debugName); this.forceInline = forceInline; this.customized = customized; + this.kind = kind; int maxOutArity = normalize(); if (maxOutArity > MethodType.MAX_MH_INVOKER_ARITY) { // Cannot use LF interpreter on very high arity expressions. assert(maxOutArity <= MethodType.MAX_JVM_ARITY); compileToBytecode(); } } LambdaForm(String debugName, int arity, Name[] names) { ! this(debugName, arity, names, LAST_RESULT, /*forceInline=*/true, /*customized=*/null, Kind.GENERIC); } LambdaForm(String debugName, int arity, Name[] names, boolean forceInline) { ! this(debugName, arity, names, LAST_RESULT, forceInline, /*customized=*/null, Kind.GENERIC); ! } ! LambdaForm(String debugName, ! int arity, Name[] names, boolean forceInline, Kind kind) { ! this(debugName, arity, names, LAST_RESULT, forceInline, /*customized=*/null, kind); } LambdaForm(String debugName, Name[] formals, Name[] temps, Name result) { this(debugName, formals.length, buildNames(formals, temps, result), LAST_RESULT, /*forceInline=*/true, /*customized=*/null);
*** 323,332 **** --- 364,374 ---- this.result = (mt.returnType() == void.class || mt.returnType() == Void.class) ? -1 : arity; this.names = buildEmptyNames(arity, mt, result == -1); this.debugName = "LF.zero"; this.forceInline = true; this.customized = null; + this.kind = Kind.GENERIC; assert(nameRefsAreLegal()); assert(isEmpty()); String sig = null; assert(isValidSignature(sig = basicTypeSignature())); assert(sig.equals(basicTypeSignature())) : sig + " != " + basicTypeSignature();
*** 393,403 **** return true; } /** Customize LambdaForm for a particular MethodHandle */ LambdaForm customize(MethodHandle mh) { ! LambdaForm customForm = new LambdaForm(debugName, arity, names, result, forceInline, mh); if (COMPILE_THRESHOLD >= 0 && isCompiled) { // If shared LambdaForm has been compiled, compile customized version as well. customForm.compileToBytecode(); } customForm.transformCache = this; // LambdaFormEditor should always use uncustomized form. --- 435,445 ---- return true; } /** Customize LambdaForm for a particular MethodHandle */ LambdaForm customize(MethodHandle mh) { ! LambdaForm customForm = new LambdaForm(debugName, arity, names, result, forceInline, mh, kind); if (COMPILE_THRESHOLD >= 0 && isCompiled) { // If shared LambdaForm has been compiled, compile customized version as well. customForm.compileToBytecode(); } customForm.transformCache = this; // LambdaFormEditor should always use uncustomized form.
*** 771,802 **** } catch (Error | Exception e) { throw newInternalError(this.toString(), e); } } - /** - * Generate optimizable bytecode for this form after first looking for a - * pregenerated version in a specified class. - */ - void compileToBytecode(Class<?> lookupClass) { - if (vmentry != null && isCompiled) { - return; // already compiled somehow - } - MethodType invokerType = methodType(); - assert(vmentry == null || vmentry.getMethodType().basicType().equals(invokerType)); - int dot = debugName.indexOf('.'); - String methodName = (dot > 0) ? debugName.substring(dot + 1) : debugName; - MemberName member = new MemberName(lookupClass, methodName, invokerType, REF_invokeStatic); - MemberName resolvedMember = MemberName.getFactory().resolveOrNull(REF_invokeStatic, member, lookupClass); - if (resolvedMember != null) { - vmentry = resolvedMember; - isCompiled = true; - } else { - compileToBytecode(); - } - } - private static void computeInitialPreparedForms() { // Find all predefined invokers and associate them with canonical empty lambda forms. for (MemberName m : MemberName.getFactory().getMethods(LambdaForm.class, false, null, null, null)) { if (!m.isStatic() || !m.isPackage()) continue; MethodType mt = m.getMethodType(); --- 813,822 ----
< prev index next >