Skip to content

Commit 7104400

Browse files
author
Vladimir Ivanov
committedDec 2, 2020
8257164: Share LambdaForms for VH linkers/invokers
Reviewed-by: redestad, kvn, psandoz
1 parent 3e89981 commit 7104400

File tree

3 files changed

+38
-27
lines changed

3 files changed

+38
-27
lines changed
 

‎src/java.base/share/classes/java/lang/invoke/Invokers.java

+33-25
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ private MethodHandle makeVarHandleMethodInvoker(VarHandle.AccessMode ak, boolean
139139
MethodType mtype = targetType;
140140
MethodType invokerType = mtype.insertParameterTypes(0, VarHandle.class);
141141

142-
LambdaForm lform = varHandleMethodInvokerHandleForm(ak, mtype, isExact);
142+
LambdaForm lform = varHandleMethodInvokerHandleForm(mtype, isExact);
143143
VarHandle.AccessDescriptor ad = new VarHandle.AccessDescriptor(mtype, ak.at.ordinal(), ak.ordinal());
144144
MethodHandle invoker = BoundMethodHandle.bindSingle(invokerType, lform, ad);
145145

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

348348

349-
static MemberName varHandleInvokeLinkerMethod(VarHandle.AccessMode ak, MethodType mtype) {
350-
LambdaForm lform;
351-
if (mtype.parameterSlotCount() <= MethodType.MAX_MH_ARITY - MH_LINKER_ARG_APPENDED) {
352-
lform = varHandleMethodGenericLinkerHandleForm(ak, mtype);
353-
} else {
354-
// TODO
349+
static MemberName varHandleInvokeLinkerMethod(MethodType mtype) {
350+
if (mtype.parameterSlotCount() > MethodType.MAX_MH_ARITY - MH_LINKER_ARG_APPENDED) {
355351
throw newInternalError("Unsupported parameter slot count " + mtype.parameterSlotCount());
356352
}
353+
LambdaForm lform = varHandleMethodGenericLinkerHandleForm(mtype);
357354
return lform.vmentry;
358355
}
359356

360-
private static LambdaForm varHandleMethodGenericLinkerHandleForm(VarHandle.AccessMode ak,
361-
MethodType mtype) {
362-
// TODO Cache form?
357+
private static LambdaForm varHandleMethodGenericLinkerHandleForm(MethodType mtype) {
358+
mtype = mtype.basicType(); // normalize Z to I, String to Object, etc.
359+
360+
int which = MethodTypeForm.LF_VH_GEN_LINKER;
361+
LambdaForm lform = mtype.form().cachedLambdaForm(which);
362+
if (lform != null) {
363+
return lform;
364+
}
363365

364366
final int THIS_VH = 0;
365367
final int ARG_BASE = THIS_VH + 1;
@@ -396,19 +398,26 @@ private static LambdaForm varHandleMethodGenericLinkerHandleForm(VarHandle.Acces
396398
MethodType outCallType = mtype.insertParameterTypes(0, VarHandle.class)
397399
.basicType();
398400
names[LINKER_CALL] = new Name(outCallType, outArgs);
399-
LambdaForm lform = new LambdaForm(ARG_LIMIT + 1, names, VARHANDLE_LINKER);
401+
lform = new LambdaForm(ARG_LIMIT + 1, names, VARHANDLE_LINKER);
400402
if (LambdaForm.debugNames()) {
401-
String name = ak.methodName() + ":VarHandle_invoke_MT_" +
402-
shortenSignature(basicTypeSignature(mtype));
403+
String name = "VarHandle_invoke_MT_" + shortenSignature(basicTypeSignature(mtype));
403404
LambdaForm.associateWithDebugName(lform, name);
404405
}
405406
lform.compileToBytecode();
407+
408+
lform = mtype.form().setCachedLambdaForm(which, lform);
409+
406410
return lform;
407411
}
408412

409-
private static LambdaForm varHandleMethodInvokerHandleForm(VarHandle.AccessMode ak,
410-
MethodType mtype, boolean isExact) {
411-
// TODO Cache form?
413+
private static LambdaForm varHandleMethodInvokerHandleForm(MethodType mtype, boolean isExact) {
414+
mtype = mtype.basicType(); // normalize Z to I, String to Object, etc.
415+
416+
int which = (isExact ? MethodTypeForm.LF_VH_EX_INVOKER : MethodTypeForm.LF_VH_GEN_INVOKER);
417+
LambdaForm lform = mtype.form().cachedLambdaForm(which);
418+
if (lform != null) {
419+
return lform;
420+
}
412421

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

450459
MethodType outCallType = mtype.insertParameterTypes(0, VarHandle.class)
451-
.basicType();
460+
.basicType();
452461
names[LINKER_CALL] = new Name(outCallType, outArgs);
453462
Kind kind = isExact ? VARHANDLE_EXACT_INVOKER : VARHANDLE_INVOKER;
454-
LambdaForm lform = new LambdaForm(ARG_LIMIT, names, kind);
463+
lform = new LambdaForm(ARG_LIMIT, names, kind);
455464
if (LambdaForm.debugNames()) {
456-
String name = ak.methodName() +
457-
(isExact ? ":VarHandle_exactInvoker_" : ":VarHandle_invoker_") +
458-
shortenSignature(basicTypeSignature(mtype));
465+
String name = (isExact ? "VarHandle_exactInvoker_" : "VarHandle_invoker_") + shortenSignature(basicTypeSignature(mtype));
459466
LambdaForm.associateWithDebugName(lform, name);
460467
}
461468
lform.prepare();
469+
470+
lform = mtype.form().setCachedLambdaForm(which, lform);
471+
462472
return lform;
463473
}
464474

@@ -473,12 +483,10 @@ static MethodHandle checkVarHandleGenericType(VarHandle handle, VarHandle.Access
473483
// Test for exact match on invoker types
474484
// TODO match with erased types and add cast of return value to lambda form
475485
MethodHandle mh = handle.getMethodHandle(ad.mode);
476-
if (mh.type() == ad.symbolicMethodTypeInvoker) {
477-
return mh;
478-
}
479-
else {
486+
if (mh.type() != ad.symbolicMethodTypeInvoker) {
480487
return mh.asType(ad.symbolicMethodTypeInvoker);
481488
}
489+
return mh;
482490
}
483491

484492
@ForceInline

‎src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -578,7 +578,7 @@ VarHandleGuards.class, getVarHandleGuardMethodName(guardType),
578578
// Fall back to lambda form linkage if guard method is not available
579579
// TODO Optionally log fallback ?
580580
}
581-
return Invokers.varHandleInvokeLinkerMethod(ak, mtype);
581+
return Invokers.varHandleInvokeLinkerMethod(mtype);
582582
}
583583
static String getVarHandleGuardMethodName(MethodType guardType) {
584584
String prefix = "guard_";

‎src/java.base/share/classes/java/lang/invoke/MethodTypeForm.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,10 @@ final class MethodTypeForm {
8787
LF_LOOP = 19, // loop
8888
LF_INVSPECIAL_IFC = 20, // DMH invokeSpecial of (private) interface method
8989
LF_INVNATIVE = 21, // NMH invokeNative
90-
LF_LIMIT = 22;
90+
LF_VH_EX_INVOKER = 22, // VarHandle exact invoker
91+
LF_VH_GEN_INVOKER = 23, // VarHandle generic invoker
92+
LF_VH_GEN_LINKER = 24, // VarHandle generic linker
93+
LF_LIMIT = 25;
9194

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

0 commit comments

Comments
 (0)
Please sign in to comment.