mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-26 14:24:46 +02:00
8340280: Avoid calling MT.invokerType() when creating LambdaForms
Reviewed-by: liach, jvernee
This commit is contained in:
parent
147e30070d
commit
d23c59e408
6 changed files with 48 additions and 43 deletions
|
@ -143,7 +143,7 @@ abstract sealed class DelegatingMethodHandle extends MethodHandle
|
|||
final int PRE_ACTION = hasPreAction ? nameCursor++ : -1;
|
||||
final int NEXT_MH = customized ? -1 : nameCursor++;
|
||||
final int REINVOKE = nameCursor++;
|
||||
LambdaForm.Name[] names = LambdaForm.arguments(nameCursor - ARG_LIMIT, mtype.invokerType());
|
||||
LambdaForm.Name[] names = LambdaForm.invokeArguments(nameCursor - ARG_LIMIT, mtype);
|
||||
assert(names.length == nameCursor);
|
||||
names[THIS_DMH] = names[THIS_DMH].withConstraint(constraint);
|
||||
Object[] targetArgs;
|
||||
|
|
|
@ -250,11 +250,17 @@ sealed class DirectMethodHandle extends MethodHandle {
|
|||
default: throw new InternalError("which="+which);
|
||||
}
|
||||
|
||||
MethodType mtypeWithArg = mtype.appendParameterTypes(MemberName.class);
|
||||
if (doesAlloc)
|
||||
mtypeWithArg = mtypeWithArg
|
||||
.insertParameterTypes(0, Object.class) // insert newly allocated obj
|
||||
.changeReturnType(void.class); // <init> returns void
|
||||
MethodType mtypeWithArg;
|
||||
if (doesAlloc) {
|
||||
var ptypes = mtype.ptypes();
|
||||
var newPtypes = new Class<?>[ptypes.length + 2];
|
||||
newPtypes[0] = Object.class; // insert newly allocated obj
|
||||
System.arraycopy(ptypes, 0, newPtypes, 1, ptypes.length);
|
||||
newPtypes[newPtypes.length - 1] = MemberName.class;
|
||||
mtypeWithArg = MethodType.methodType(void.class, newPtypes, true);
|
||||
} else {
|
||||
mtypeWithArg = mtype.appendParameterTypes(MemberName.class);
|
||||
}
|
||||
MemberName linker = new MemberName(MethodHandle.class, linkerName, mtypeWithArg, REF_invokeStatic);
|
||||
try {
|
||||
linker = IMPL_NAMES.resolveOrFail(REF_invokeStatic, linker, null, LM_TRUSTED,
|
||||
|
@ -270,7 +276,7 @@ sealed class DirectMethodHandle extends MethodHandle {
|
|||
final int GET_MEMBER = nameCursor++;
|
||||
final int CHECK_RECEIVER = (needsReceiverCheck ? nameCursor++ : -1);
|
||||
final int LINKER_CALL = nameCursor++;
|
||||
Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.invokerType());
|
||||
Name[] names = invokeArguments(nameCursor - ARG_LIMIT, mtype);
|
||||
assert(names.length == nameCursor);
|
||||
if (doesAlloc) {
|
||||
// names = { argx,y,z,... new C, init method }
|
||||
|
@ -786,7 +792,7 @@ sealed class DirectMethodHandle extends MethodHandle {
|
|||
final int LINKER_CALL = nameCursor++;
|
||||
final int POST_CAST = (needsCast && isGetter ? nameCursor++ : -1);
|
||||
final int RESULT = nameCursor-1; // either the call or the cast
|
||||
Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.invokerType());
|
||||
Name[] names = invokeArguments(nameCursor - ARG_LIMIT, mtype);
|
||||
if (needsInit)
|
||||
names[INIT_BAR] = new Name(getFunction(NF_ensureInitialized), names[DMH_THIS]);
|
||||
if (needsCast && !isGetter)
|
||||
|
|
|
@ -314,14 +314,14 @@ class Invokers {
|
|||
final int CHECK_TYPE = nameCursor++;
|
||||
final int CHECK_CUSTOM = (CUSTOMIZE_THRESHOLD >= 0) ? nameCursor++ : -1;
|
||||
final int LINKER_CALL = nameCursor++;
|
||||
MethodType invokerFormType = mtype.invokerType();
|
||||
MethodType invokerFormType = mtype;
|
||||
if (isLinker) {
|
||||
if (!customized)
|
||||
invokerFormType = invokerFormType.appendParameterTypes(MemberName.class);
|
||||
} else {
|
||||
invokerFormType = invokerFormType.invokerType();
|
||||
}
|
||||
Name[] names = arguments(nameCursor - INARG_LIMIT, invokerFormType);
|
||||
Name[] names = invokeArguments(nameCursor - INARG_LIMIT, invokerFormType);
|
||||
assert(names.length == nameCursor)
|
||||
: Arrays.asList(mtype, customized, which, nameCursor, names.length);
|
||||
if (MTYPE_ARG >= INARG_LIMIT) {
|
||||
|
@ -390,11 +390,11 @@ class Invokers {
|
|||
final int LINKER_CALL = nameCursor++;
|
||||
|
||||
Name[] names = new Name[LINKER_CALL + 1];
|
||||
names[THIS_VH] = argument(THIS_VH, BasicType.basicType(Object.class));
|
||||
names[THIS_VH] = argument(THIS_VH, BasicType.L_TYPE);
|
||||
for (int i = 0; i < mtype.parameterCount(); i++) {
|
||||
names[ARG_BASE + i] = argument(ARG_BASE + i, BasicType.basicType(mtype.parameterType(i)));
|
||||
}
|
||||
names[VAD_ARG] = new Name(ARG_LIMIT, BasicType.basicType(Object.class));
|
||||
names[VAD_ARG] = new Name(ARG_LIMIT, BasicType.L_TYPE);
|
||||
|
||||
names[UNBOUND_VH] = new Name(getFunction(NF_directVarHandleTarget), names[THIS_VH]);
|
||||
|
||||
|
@ -446,8 +446,8 @@ class Invokers {
|
|||
final int LINKER_CALL = nameCursor++;
|
||||
|
||||
Name[] names = new Name[LINKER_CALL + 1];
|
||||
names[THIS_MH] = argument(THIS_MH, BasicType.basicType(Object.class));
|
||||
names[CALL_VH] = argument(CALL_VH, BasicType.basicType(Object.class));
|
||||
names[THIS_MH] = argument(THIS_MH, BasicType.L_TYPE);
|
||||
names[CALL_VH] = argument(CALL_VH, BasicType.L_TYPE);
|
||||
for (int i = 0; i < mtype.parameterCount(); i++) {
|
||||
names[ARG_BASE + i] = argument(ARG_BASE + i, BasicType.basicType(mtype.parameterType(i)));
|
||||
}
|
||||
|
@ -589,17 +589,16 @@ class Invokers {
|
|||
final int CSITE_ARG = skipCallSite ? -1 : APPENDIX_ARG;
|
||||
final int CALL_MH = skipCallSite ? APPENDIX_ARG : nameCursor++; // result of getTarget
|
||||
final int LINKER_CALL = nameCursor++;
|
||||
MethodType invokerFormType = mtype.appendParameterTypes(skipCallSite ? MethodHandle.class : CallSite.class);
|
||||
Name[] names = arguments(nameCursor - INARG_LIMIT, invokerFormType);
|
||||
assert(names.length == nameCursor);
|
||||
assert(names[APPENDIX_ARG] != null);
|
||||
Name[] names = arguments(nameCursor - INARG_LIMIT + 1, mtype);
|
||||
assert(names.length == nameCursor && names[APPENDIX_ARG] == null);
|
||||
names[APPENDIX_ARG] = argument(APPENDIX_ARG, BasicType.L_TYPE);
|
||||
if (!skipCallSite)
|
||||
names[CALL_MH] = new Name(getFunction(NF_getCallSiteTarget), names[CSITE_ARG]);
|
||||
// (site.)invokedynamic(a*):R => mh = site.getTarget(); mh.invokeBasic(a*)
|
||||
final int PREPEND_MH = 0, PREPEND_COUNT = 1;
|
||||
Object[] outArgs = Arrays.copyOfRange(names, ARG_BASE, OUTARG_LIMIT + PREPEND_COUNT, Object[].class);
|
||||
Object[] outArgs = new Object[OUTARG_LIMIT + PREPEND_COUNT];
|
||||
System.arraycopy(names, 0, outArgs, PREPEND_COUNT, outArgs.length - PREPEND_COUNT);
|
||||
// prepend MH argument:
|
||||
System.arraycopy(outArgs, 0, outArgs, PREPEND_COUNT, outArgs.length - PREPEND_COUNT);
|
||||
outArgs[PREPEND_MH] = names[CALL_MH];
|
||||
names[LINKER_CALL] = new Name(mtype, outArgs);
|
||||
lform = LambdaForm.create(INARG_LIMIT, names,
|
||||
|
|
|
@ -1636,6 +1636,16 @@ class LambdaForm {
|
|||
names[i] = argument(i, basicType(types.parameterType(i)));
|
||||
return names;
|
||||
}
|
||||
|
||||
static Name[] invokeArguments(int extra, MethodType types) {
|
||||
int length = types.parameterCount();
|
||||
Name[] names = new Name[length + extra + 1];
|
||||
names[0] = argument(0, L_TYPE);
|
||||
for (int i = 0; i < length; i++)
|
||||
names[i + 1] = argument(i + 1, basicType(types.parameterType(i)));
|
||||
return names;
|
||||
}
|
||||
|
||||
static final int INTERNED_ARGUMENT_LIMIT = 10;
|
||||
private static final Name[][] INTERNED_ARGUMENTS
|
||||
= new Name[ARG_TYPE_LIMIT][INTERNED_ARGUMENT_LIMIT];
|
||||
|
|
|
@ -810,8 +810,7 @@ abstract class MethodHandleImpl {
|
|||
final int CALL_TARGET = nameCursor++;
|
||||
assert(CALL_TARGET == SELECT_ALT+1); // must be true to trigger IBG.emitSelectAlternative
|
||||
|
||||
MethodType lambdaType = basicType.invokerType();
|
||||
Name[] names = arguments(nameCursor - ARG_LIMIT, lambdaType);
|
||||
Name[] names = invokeArguments(nameCursor - ARG_LIMIT, basicType);
|
||||
|
||||
BoundMethodHandle.SpeciesData data =
|
||||
(GET_COUNTERS != -1) ? BoundMethodHandle.speciesData_LLLL()
|
||||
|
@ -843,7 +842,7 @@ abstract class MethodHandleImpl {
|
|||
invokeArgs[0] = names[SELECT_ALT];
|
||||
names[CALL_TARGET] = new Name(basicType, invokeArgs);
|
||||
|
||||
lform = LambdaForm.create(lambdaType.parameterCount(), names, /*forceInline=*/true, Kind.GUARD);
|
||||
lform = LambdaForm.create(basicType.parameterCount() + 1, names, /*forceInline=*/true, Kind.GUARD);
|
||||
|
||||
return basicType.form().setCachedLambdaForm(MethodTypeForm.LF_GWT, lform);
|
||||
}
|
||||
|
@ -870,8 +869,6 @@ abstract class MethodHandleImpl {
|
|||
* among catchException combinators with the same basic type.
|
||||
*/
|
||||
private static LambdaForm makeGuardWithCatchForm(MethodType basicType) {
|
||||
MethodType lambdaType = basicType.invokerType();
|
||||
|
||||
LambdaForm lform = basicType.form().cachedLambdaForm(MethodTypeForm.LF_GWC);
|
||||
if (lform != null) {
|
||||
return lform;
|
||||
|
@ -890,7 +887,7 @@ abstract class MethodHandleImpl {
|
|||
final int TRY_CATCH = nameCursor++;
|
||||
final int UNBOX_RESULT = nameCursor++;
|
||||
|
||||
Name[] names = arguments(nameCursor - ARG_LIMIT, lambdaType);
|
||||
Name[] names = invokeArguments(nameCursor - ARG_LIMIT, basicType);
|
||||
|
||||
BoundMethodHandle.SpeciesData data = BoundMethodHandle.speciesData_LLLLL();
|
||||
names[THIS_MH] = names[THIS_MH].withConstraint(data);
|
||||
|
@ -919,7 +916,7 @@ abstract class MethodHandleImpl {
|
|||
Object[] unboxArgs = new Object[] {names[GET_UNBOX_RESULT], names[TRY_CATCH]};
|
||||
names[UNBOX_RESULT] = new Name(invokeBasicUnbox, unboxArgs);
|
||||
|
||||
lform = LambdaForm.create(lambdaType.parameterCount(), names, Kind.GUARD_WITH_CATCH);
|
||||
lform = LambdaForm.create(basicType.parameterCount() + 1, names, Kind.GUARD_WITH_CATCH);
|
||||
|
||||
return basicType.form().setCachedLambdaForm(MethodTypeForm.LF_GWC, lform);
|
||||
}
|
||||
|
@ -1733,8 +1730,6 @@ abstract class MethodHandleImpl {
|
|||
* bytecode generation}.
|
||||
*/
|
||||
private static LambdaForm makeLoopForm(MethodType basicType, BasicType[] localVarTypes) {
|
||||
MethodType lambdaType = basicType.invokerType();
|
||||
|
||||
final int THIS_MH = 0; // the BMH_LLL
|
||||
final int ARG_BASE = 1; // start of incoming arguments
|
||||
final int ARG_LIMIT = ARG_BASE + basicType.parameterCount();
|
||||
|
@ -1749,7 +1744,7 @@ abstract class MethodHandleImpl {
|
|||
|
||||
LambdaForm lform = basicType.form().cachedLambdaForm(MethodTypeForm.LF_LOOP);
|
||||
if (lform == null) {
|
||||
Name[] names = arguments(nameCursor - ARG_LIMIT, lambdaType);
|
||||
Name[] names = invokeArguments(nameCursor - ARG_LIMIT, basicType);
|
||||
|
||||
BoundMethodHandle.SpeciesData data = BoundMethodHandle.speciesData_LLL();
|
||||
names[THIS_MH] = names[THIS_MH].withConstraint(data);
|
||||
|
@ -1777,7 +1772,7 @@ abstract class MethodHandleImpl {
|
|||
names[UNBOX_RESULT] = new Name(invokeBasicUnbox, unboxArgs);
|
||||
|
||||
lform = basicType.form().setCachedLambdaForm(MethodTypeForm.LF_LOOP,
|
||||
LambdaForm.create(lambdaType.parameterCount(), names, Kind.LOOP));
|
||||
LambdaForm.create(basicType.parameterCount() + 1, names, Kind.LOOP));
|
||||
}
|
||||
|
||||
// BOXED_ARGS is the index into the names array where the loop idiom starts
|
||||
|
@ -1966,8 +1961,6 @@ abstract class MethodHandleImpl {
|
|||
* forms among tryFinally combinators with the same basic type.
|
||||
*/
|
||||
private static LambdaForm makeTryFinallyForm(MethodType basicType) {
|
||||
MethodType lambdaType = basicType.invokerType();
|
||||
|
||||
LambdaForm lform = basicType.form().cachedLambdaForm(MethodTypeForm.LF_TF);
|
||||
if (lform != null) {
|
||||
return lform;
|
||||
|
@ -1985,7 +1978,7 @@ abstract class MethodHandleImpl {
|
|||
final int TRY_FINALLY = nameCursor++;
|
||||
final int UNBOX_RESULT = nameCursor++;
|
||||
|
||||
Name[] names = arguments(nameCursor - ARG_LIMIT, lambdaType);
|
||||
Name[] names = invokeArguments(nameCursor - ARG_LIMIT, basicType);
|
||||
|
||||
BoundMethodHandle.SpeciesData data = BoundMethodHandle.speciesData_LLLL();
|
||||
names[THIS_MH] = names[THIS_MH].withConstraint(data);
|
||||
|
@ -2011,7 +2004,7 @@ abstract class MethodHandleImpl {
|
|||
Object[] unboxArgs = new Object[] {names[GET_UNBOX_RESULT], names[TRY_FINALLY]};
|
||||
names[UNBOX_RESULT] = new Name(invokeBasicUnbox, unboxArgs);
|
||||
|
||||
lform = LambdaForm.create(lambdaType.parameterCount(), names, Kind.TRY_FINALLY);
|
||||
lform = LambdaForm.create(basicType.parameterCount() + 1, names, Kind.TRY_FINALLY);
|
||||
|
||||
return basicType.form().setCachedLambdaForm(MethodTypeForm.LF_TF, lform);
|
||||
}
|
||||
|
@ -2055,7 +2048,6 @@ abstract class MethodHandleImpl {
|
|||
}
|
||||
|
||||
private static LambdaForm makeCollectorForm(MethodType basicType, Class<?> arrayType) {
|
||||
MethodType lambdaType = basicType.invokerType();
|
||||
int parameterCount = basicType.parameterCount();
|
||||
|
||||
// Only share the lambda form for empty arrays and reference types.
|
||||
|
@ -2088,7 +2080,7 @@ abstract class MethodHandleImpl {
|
|||
final int STORE_ELEMENT_LIMIT = STORE_ELEMENT_BASE + parameterCount;
|
||||
nameCursor = STORE_ELEMENT_LIMIT;
|
||||
|
||||
Name[] names = arguments(nameCursor - ARG_LIMIT, lambdaType);
|
||||
Name[] names = invokeArguments(nameCursor - ARG_LIMIT, basicType);
|
||||
|
||||
BoundMethodHandle.SpeciesData data = BoundMethodHandle.speciesData_L();
|
||||
names[THIS_MH] = names[THIS_MH].withConstraint(data);
|
||||
|
@ -2106,7 +2098,7 @@ abstract class MethodHandleImpl {
|
|||
names[CALL_NEW_ARRAY], storeIndex, names[argCursor]);
|
||||
}
|
||||
|
||||
LambdaForm lform = LambdaForm.create(lambdaType.parameterCount(), names, CALL_NEW_ARRAY, Kind.COLLECTOR);
|
||||
LambdaForm lform = LambdaForm.create(basicType.parameterCount() + 1, names, CALL_NEW_ARRAY, Kind.COLLECTOR);
|
||||
if (isSharedLambdaForm) {
|
||||
lform = basicType.form().setCachedLambdaForm(MethodTypeForm.LF_COLLECTOR, lform);
|
||||
}
|
||||
|
@ -2169,8 +2161,6 @@ abstract class MethodHandleImpl {
|
|||
|
||||
private static LambdaForm makeTableSwitchForm(MethodType basicType, BoundMethodHandle.SpeciesData data,
|
||||
int numCases) {
|
||||
MethodType lambdaType = basicType.invokerType();
|
||||
|
||||
// We need to cache based on the basic type X number of cases,
|
||||
// since the number of cases is used when generating bytecode.
|
||||
// This also means that we can't use the cache in MethodTypeForm,
|
||||
|
@ -2202,7 +2192,7 @@ abstract class MethodHandleImpl {
|
|||
final int FIELD_UNBOX_RESULT = fieldCursor++;
|
||||
final int FIELD_CASES = fieldCursor++;
|
||||
|
||||
Name[] names = arguments(nameCursor - ARG_LIMIT, lambdaType);
|
||||
Name[] names = invokeArguments(nameCursor - ARG_LIMIT, basicType);
|
||||
|
||||
names[THIS_MH] = names[THIS_MH].withConstraint(data);
|
||||
names[GET_DEFAULT_CASE] = new Name(data.getterFunction(FIELD_DEFAULT_CASE), names[THIS_MH]);
|
||||
|
@ -2231,7 +2221,7 @@ abstract class MethodHandleImpl {
|
|||
names[UNBOXED_RESULT] = new Name(invokeBasic, unboxArgs);
|
||||
}
|
||||
|
||||
lform = LambdaForm.create(lambdaType.parameterCount(), names, Kind.TABLE_SWITCH);
|
||||
lform = LambdaForm.create(basicType.parameterCount() + 1, names, Kind.TABLE_SWITCH);
|
||||
LambdaForm prev = TableSwitchCacheKey.CACHE.putIfAbsent(key, lform);
|
||||
return prev != null ? prev : lform;
|
||||
}
|
||||
|
|
|
@ -108,7 +108,7 @@ import static java.lang.invoke.MethodHandleStatics.newInternalError;
|
|||
final int GET_NEP = nameCursor++;
|
||||
final int LINKER_CALL = nameCursor++;
|
||||
|
||||
LambdaForm.Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.invokerType());
|
||||
LambdaForm.Name[] names = invokeArguments(nameCursor - ARG_LIMIT, mtype);
|
||||
assert (names.length == nameCursor);
|
||||
|
||||
names[GET_NEP] = new LambdaForm.Name(Lazy.NF_internalNativeEntryPoint, names[NMH_THIS]);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue