mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 14:54:52 +02:00
8257164: Share LambdaForms for VH linkers/invokers
Reviewed-by: redestad, kvn, psandoz
This commit is contained in:
parent
3e89981d98
commit
7104400ad8
3 changed files with 38 additions and 27 deletions
|
@ -139,7 +139,7 @@ class Invokers {
|
|||
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 @@ class Invokers {
|
|||
}
|
||||
|
||||
|
||||
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 @@ class Invokers {
|
|||
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 @@ class Invokers {
|
|||
}
|
||||
|
||||
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 @@ class Invokers {
|
|||
// 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 @@ class MethodHandleNatives {
|
|||
// 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 @@ 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.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue