< prev index next >

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

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

*** 25,34 **** --- 25,35 ---- package java.lang.invoke; import java.util.Arrays; import static java.lang.invoke.LambdaForm.*; + import static java.lang.invoke.LambdaForm.Kind.*; import static java.lang.invoke.MethodHandleStatics.*; /** * A method handle whose invocation behavior is determined by a target. * The delegating MH itself can hold extra "intentions" beyond the simple behavior.
*** 94,121 **** static LambdaForm makeReinvokerForm(MethodHandle target, int whichCache, Object constraint, NamedFunction getTargetFn) { - String debugString; - switch(whichCache) { - case MethodTypeForm.LF_REBIND: debugString = "BMH.reinvoke"; break; - case MethodTypeForm.LF_DELEGATE: debugString = "MH.delegate"; break; - default: debugString = "MH.reinvoke"; break; - } // No pre-action needed. ! return makeReinvokerForm(target, whichCache, constraint, debugString, true, getTargetFn, null); } /** Create a LF which simply reinvokes a target of the given basic type. */ static LambdaForm makeReinvokerForm(MethodHandle target, int whichCache, Object constraint, String debugString, boolean forceInline, NamedFunction getTargetFn, NamedFunction preActionFn) { MethodType mtype = target.type().basicType(); boolean customized = (whichCache < 0 || mtype.parameterSlotCount() > MethodType.MAX_MH_INVOKER_ARITY); boolean hasPreAction = (preActionFn != null); LambdaForm form; if (!customized) { --- 95,120 ---- static LambdaForm makeReinvokerForm(MethodHandle target, int whichCache, Object constraint, NamedFunction getTargetFn) { // No pre-action needed. ! return makeReinvokerForm(target, whichCache, constraint, null, true, getTargetFn, null); } /** Create a LF which simply reinvokes a target of the given basic type. */ static LambdaForm makeReinvokerForm(MethodHandle target, int whichCache, Object constraint, String debugString, boolean forceInline, NamedFunction getTargetFn, NamedFunction preActionFn) { MethodType mtype = target.type().basicType(); + Kind kind = whichKind(whichCache); + if (debugString == null) { + debugString = kind.defaultLambdaName; + } boolean customized = (whichCache < 0 || mtype.parameterSlotCount() > MethodType.MAX_MH_INVOKER_ARITY); boolean hasPreAction = (preActionFn != null); LambdaForm form; if (!customized) {
*** 143,164 **** names[NEXT_MH] = new LambdaForm.Name(getTargetFn, names[THIS_DMH]); targetArgs = Arrays.copyOfRange(names, THIS_DMH, ARG_LIMIT, Object[].class); targetArgs[0] = names[NEXT_MH]; // overwrite this MH with next MH names[REINVOKE] = new LambdaForm.Name(mtype, targetArgs); } ! form = new LambdaForm(debugString, ARG_LIMIT, names, forceInline); if (!customized) { form = mtype.form().setCachedLambdaForm(whichCache, form); } return form; } static final NamedFunction NF_getTarget; static { try { NF_getTarget = new NamedFunction(DelegatingMethodHandle.class .getDeclaredMethod("getTarget")); } catch (ReflectiveOperationException ex) { throw newInternalError(ex); } } } --- 142,179 ---- names[NEXT_MH] = new LambdaForm.Name(getTargetFn, names[THIS_DMH]); targetArgs = Arrays.copyOfRange(names, THIS_DMH, ARG_LIMIT, Object[].class); targetArgs[0] = names[NEXT_MH]; // overwrite this MH with next MH names[REINVOKE] = new LambdaForm.Name(mtype, targetArgs); } ! form = new LambdaForm(debugString, ARG_LIMIT, names, forceInline, kind); if (!customized) { form = mtype.form().setCachedLambdaForm(whichCache, form); } return form; } + private static Kind whichKind(int whichCache) { + switch(whichCache) { + case MethodTypeForm.LF_REBIND: return BOUND_REINVOKER; + case MethodTypeForm.LF_DELEGATE: return DELEGATE; + default: return REINVOKER; + } + } + static final NamedFunction NF_getTarget; static { try { NF_getTarget = new NamedFunction(DelegatingMethodHandle.class .getDeclaredMethod("getTarget")); } catch (ReflectiveOperationException ex) { throw newInternalError(ex); } + // The Holder class will contain pre-generated DelegatingMethodHandles resolved + // speculatively using MemberName.getFactory().resolveOrNull. However, that + // doesn't initialize the class, which subtly breaks inlining etc. By forcing + // initialization of the Holder class we avoid these issues. + UNSAFE.ensureClassInitialized(Holder.class); } + + /* Placeholder class for DelegatingMethodHandles generated ahead of time */ + final class Holder {} }
< prev index next >