Skip to content
Permalink
Browse files
8257164: Share LambdaForms for VH linkers/invokers
Reviewed-by: redestad, kvn, psandoz
  • Loading branch information
Vladimir Ivanov committed Dec 2, 2020
1 parent 3e89981 commit 7104400ad8b5864d646d2b2792f1fdb20d35eaef
@@ -139,7 +139,7 @@ private MethodHandle makeVarHandleMethodInvoker(VarHandle.AccessMode ak, boolean
MethodType mtype = targetType;
MethodType invokerType = mtype.insertParameterTypes(0, VarHandle.class);

LambdaForm lform = varHandleMethodInvokerHandleForm(ak, mtype, isExact);
LambdaForm lform = varHandleMethodInvokerHandleForm(mtype, isExact);
VarHandle.AccessDescriptor ad = new VarHandle.AccessDescriptor(mtype, ak.at.ordinal(), ak.ordinal());
MethodHandle invoker = BoundMethodHandle.bindSingle(invokerType, lform, ad);

@@ -346,20 +346,22 @@ static LambdaForm invokeHandleForm(MethodType mtype, boolean customized, int whi
}


static MemberName varHandleInvokeLinkerMethod(VarHandle.AccessMode ak, MethodType mtype) {
LambdaForm lform;
if (mtype.parameterSlotCount() <= MethodType.MAX_MH_ARITY - MH_LINKER_ARG_APPENDED) {
lform = varHandleMethodGenericLinkerHandleForm(ak, mtype);
} else {
// TODO
static MemberName varHandleInvokeLinkerMethod(MethodType mtype) {
if (mtype.parameterSlotCount() > MethodType.MAX_MH_ARITY - MH_LINKER_ARG_APPENDED) {
throw newInternalError("Unsupported parameter slot count " + mtype.parameterSlotCount());
}
LambdaForm lform = varHandleMethodGenericLinkerHandleForm(mtype);
return lform.vmentry;
}

private static LambdaForm varHandleMethodGenericLinkerHandleForm(VarHandle.AccessMode ak,
MethodType mtype) {
// TODO Cache form?
private static LambdaForm varHandleMethodGenericLinkerHandleForm(MethodType mtype) {
mtype = mtype.basicType(); // normalize Z to I, String to Object, etc.

int which = MethodTypeForm.LF_VH_GEN_LINKER;
LambdaForm lform = mtype.form().cachedLambdaForm(which);
if (lform != null) {
return lform;
}

final int THIS_VH = 0;
final int ARG_BASE = THIS_VH + 1;
@@ -396,19 +398,26 @@ private static LambdaForm varHandleMethodGenericLinkerHandleForm(VarHandle.Acces
MethodType outCallType = mtype.insertParameterTypes(0, VarHandle.class)
.basicType();
names[LINKER_CALL] = new Name(outCallType, outArgs);
LambdaForm lform = new LambdaForm(ARG_LIMIT + 1, names, VARHANDLE_LINKER);
lform = new LambdaForm(ARG_LIMIT + 1, names, VARHANDLE_LINKER);
if (LambdaForm.debugNames()) {
String name = ak.methodName() + ":VarHandle_invoke_MT_" +
shortenSignature(basicTypeSignature(mtype));
String name = "VarHandle_invoke_MT_" + shortenSignature(basicTypeSignature(mtype));
LambdaForm.associateWithDebugName(lform, name);
}
lform.compileToBytecode();

lform = mtype.form().setCachedLambdaForm(which, lform);

return lform;
}

private static LambdaForm varHandleMethodInvokerHandleForm(VarHandle.AccessMode ak,
MethodType mtype, boolean isExact) {
// TODO Cache form?
private static LambdaForm varHandleMethodInvokerHandleForm(MethodType mtype, boolean isExact) {
mtype = mtype.basicType(); // normalize Z to I, String to Object, etc.

int which = (isExact ? MethodTypeForm.LF_VH_EX_INVOKER : MethodTypeForm.LF_VH_GEN_INVOKER);
LambdaForm lform = mtype.form().cachedLambdaForm(which);
if (lform != null) {
return lform;
}

final int THIS_MH = 0;
final int CALL_VH = THIS_MH + 1;
@@ -448,17 +457,18 @@ private static LambdaForm varHandleMethodInvokerHandleForm(VarHandle.AccessMode
}

MethodType outCallType = mtype.insertParameterTypes(0, VarHandle.class)
.basicType();
.basicType();
names[LINKER_CALL] = new Name(outCallType, outArgs);
Kind kind = isExact ? VARHANDLE_EXACT_INVOKER : VARHANDLE_INVOKER;
LambdaForm lform = new LambdaForm(ARG_LIMIT, names, kind);
lform = new LambdaForm(ARG_LIMIT, names, kind);
if (LambdaForm.debugNames()) {
String name = ak.methodName() +
(isExact ? ":VarHandle_exactInvoker_" : ":VarHandle_invoker_") +
shortenSignature(basicTypeSignature(mtype));
String name = (isExact ? "VarHandle_exactInvoker_" : "VarHandle_invoker_") + shortenSignature(basicTypeSignature(mtype));
LambdaForm.associateWithDebugName(lform, name);
}
lform.prepare();

lform = mtype.form().setCachedLambdaForm(which, lform);

return lform;
}

@@ -473,12 +483,10 @@ static MethodHandle checkVarHandleGenericType(VarHandle handle, VarHandle.Access
// Test for exact match on invoker types
// TODO match with erased types and add cast of return value to lambda form
MethodHandle mh = handle.getMethodHandle(ad.mode);
if (mh.type() == ad.symbolicMethodTypeInvoker) {
return mh;
}
else {
if (mh.type() != ad.symbolicMethodTypeInvoker) {
return mh.asType(ad.symbolicMethodTypeInvoker);
}
return mh;
}

@ForceInline
@@ -578,7 +578,7 @@ private static MemberName varHandleOperationLinkerMethod(String name,
// Fall back to lambda form linkage if guard method is not available
// TODO Optionally log fallback ?
}
return Invokers.varHandleInvokeLinkerMethod(ak, mtype);
return Invokers.varHandleInvokeLinkerMethod(mtype);
}
static String getVarHandleGuardMethodName(MethodType guardType) {
String prefix = "guard_";
@@ -87,7 +87,10 @@
LF_LOOP = 19, // loop
LF_INVSPECIAL_IFC = 20, // DMH invokeSpecial of (private) interface method
LF_INVNATIVE = 21, // NMH invokeNative
LF_LIMIT = 22;
LF_VH_EX_INVOKER = 22, // VarHandle exact invoker
LF_VH_GEN_INVOKER = 23, // VarHandle generic invoker
LF_VH_GEN_LINKER = 24, // VarHandle generic linker
LF_LIMIT = 25;

/** Return the type corresponding uniquely (1-1) to this MT-form.
* It might have any primitive returns or arguments, but will have no references except Object.

1 comment on commit 7104400

@openjdk-notifier

This comment has been minimized.

Copy link

@openjdk-notifier openjdk-notifier bot commented on 7104400 Dec 2, 2020

Please sign in to comment.