Skip to content

Commit

Permalink
8257164: Share LambdaForms for VH linkers/invokers
Browse files Browse the repository at this point in the history
Reviewed-by: redestad, kvn, psandoz
  • Loading branch information
Vladimir Ivanov committed Dec 2, 2020
1 parent 3e89981 commit 7104400
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 27 deletions.
58 changes: 33 additions & 25 deletions src/java.base/share/classes/java/lang/invoke/Invokers.java
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -578,7 +578,7 @@ VarHandleGuards.class, getVarHandleGuardMethodName(guardType),
// 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_";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,10 @@ final class MethodTypeForm {
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.
Expand Down

1 comment on commit 7104400

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.