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,
Object[] appendixResult) {
// Get the signature method type
MethodType sigType = mtype.basicType();
final MethodType sigType = mtype.basicType();
// Get the access kind from the method name
VarHandle.AccessMode ak;
@ -430,8 +430,14 @@ class MethodHandleNatives {
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
// methods that return boolean
Class<?> guardReturnType = sigType.returnType();
if (ak.at.isMonomorphicInReturnType) {
if (ak.at.returnType != mtype.returnType()) {
// The caller contains a different return type than that
@ -439,23 +445,22 @@ class MethodHandleNatives {
throw newNoSuchMethodErrorOnVarHandle(name, mtype);
}
// 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
MethodType guardType = sigType
final Class<?>[] guardParams = new Class<?>[sigType.parameterCount() + 2];
// 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
.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(
VarHandleGuards.class, "guard_" + getVarHandleMethodSignature(sigType),
VarHandleGuards.class, getVarHandleGuardMethodName(guardType),
guardType, REF_invokeStatic);
linker = MemberName.getFactory().resolveOrNull(REF_invokeStatic, linker,
@ -468,14 +473,16 @@ class MethodHandleNatives {
}
return Invokers.varHandleInvokeLinkerMethod(name, mtype);
}
static String getVarHandleMethodSignature(MethodType mt) {
StringBuilder sb = new StringBuilder(mt.parameterCount() + 2);
static String getVarHandleGuardMethodName(MethodType guardType) {
String prefix = "guard_";
StringBuilder sb = new StringBuilder(prefix.length() + guardType.parameterCount());
for (int i = 0; i < mt.parameterCount(); i++) {
Class<?> pt = mt.parameterType(i);
sb.append(prefix);
for (int i = 1; i < guardType.parameterCount() - 1; i++) {
Class<?> pt = guardType.parameterType(i);
sb.append(getCharType(pt));
}
sb.append('_').append(getCharType(mt.returnType()));
sb.append('_').append(getCharType(guardType.returnType()));
return sb.toString();
}
static char getCharType(Class<?> pt) {