8172298: Reduce memory churn when linking VarHandles operations

Reviewed-by: shade, redestad
This commit is contained in:
Paul Sandoz 2017-01-27 13:17:13 -08:00
parent 387a38df1d
commit 3b50c5f35b

View file

@ -420,7 +420,7 @@ class MethodHandleNatives {
MethodType mtype, MethodType mtype,
Object[] appendixResult) { Object[] appendixResult) {
// Get the signature method type // Get the signature method type
MethodType sigType = mtype.basicType(); final MethodType sigType = mtype.basicType();
// Get the access kind from the method name // Get the access kind from the method name
VarHandle.AccessMode ak; VarHandle.AccessMode ak;
@ -430,8 +430,14 @@ class MethodHandleNatives {
throw MethodHandleStatics.newInternalError(e); throw MethodHandleStatics.newInternalError(e);
} }
// Create the appendix descriptor constant
VarHandle.AccessDescriptor ad = new VarHandle.AccessDescriptor(mtype, ak.at.ordinal(), ak.ordinal());
appendixResult[0] = ad;
if (MethodHandleStatics.VAR_HANDLE_GUARDS) {
// If not polymorphic in the return type, such as the compareAndSet // If not polymorphic in the return type, such as the compareAndSet
// methods that return boolean // methods that return boolean
Class<?> guardReturnType = sigType.returnType();
if (ak.at.isMonomorphicInReturnType) { if (ak.at.isMonomorphicInReturnType) {
if (ak.at.returnType != mtype.returnType()) { if (ak.at.returnType != mtype.returnType()) {
// The caller contains a different return type than that // The caller contains a different return type than that
@ -439,23 +445,22 @@ class MethodHandleNatives {
throw newNoSuchMethodErrorOnVarHandle(name, mtype); throw newNoSuchMethodErrorOnVarHandle(name, mtype);
} }
// Adjust the return type of the signature method type // Adjust the return type of the signature method type
sigType = sigType.changeReturnType(ak.at.returnType); guardReturnType = ak.at.returnType;
} }
// Get the guard method type for linking // Get the guard method type for linking
MethodType guardType = sigType final Class<?>[] guardParams = new Class<?>[sigType.parameterCount() + 2];
// VarHandle at start // VarHandle at start
.insertParameterTypes(0, VarHandle.class) guardParams[0] = VarHandle.class;
for (int i = 0; i < sigType.parameterCount(); i++) {
guardParams[i + 1] = sigType.parameterType(i);
}
// Access descriptor at end // Access descriptor at end
.appendParameterTypes(VarHandle.AccessDescriptor.class); guardParams[guardParams.length - 1] = VarHandle.AccessDescriptor.class;
MethodType guardType = MethodType.makeImpl(guardReturnType, guardParams, true);
// Create the appendix descriptor constant
VarHandle.AccessDescriptor ad = new VarHandle.AccessDescriptor(mtype, ak.at.ordinal(), ak.ordinal());
appendixResult[0] = ad;
if (MethodHandleStatics.VAR_HANDLE_GUARDS) {
MemberName linker = new MemberName( MemberName linker = new MemberName(
VarHandleGuards.class, "guard_" + getVarHandleMethodSignature(sigType), VarHandleGuards.class, getVarHandleGuardMethodName(guardType),
guardType, REF_invokeStatic); guardType, REF_invokeStatic);
linker = MemberName.getFactory().resolveOrNull(REF_invokeStatic, linker, linker = MemberName.getFactory().resolveOrNull(REF_invokeStatic, linker,
@ -468,14 +473,16 @@ class MethodHandleNatives {
} }
return Invokers.varHandleInvokeLinkerMethod(name, mtype); return Invokers.varHandleInvokeLinkerMethod(name, mtype);
} }
static String getVarHandleMethodSignature(MethodType mt) { static String getVarHandleGuardMethodName(MethodType guardType) {
StringBuilder sb = new StringBuilder(mt.parameterCount() + 2); String prefix = "guard_";
StringBuilder sb = new StringBuilder(prefix.length() + guardType.parameterCount());
for (int i = 0; i < mt.parameterCount(); i++) { sb.append(prefix);
Class<?> pt = mt.parameterType(i); for (int i = 1; i < guardType.parameterCount() - 1; i++) {
Class<?> pt = guardType.parameterType(i);
sb.append(getCharType(pt)); sb.append(getCharType(pt));
} }
sb.append('_').append(getCharType(mt.returnType())); sb.append('_').append(getCharType(guardType.returnType()));
return sb.toString(); return sb.toString();
} }
static char getCharType(Class<?> pt) { static char getCharType(Class<?> pt) {