Skip to content

Commit b5d94cd

Browse files
committedFeb 6, 2020
8238549: Add explicit cast to correct implementation type in VarHandle implementation methods
Reviewed-by: jvernee
1 parent 20caeb8 commit b5d94cd

18 files changed

+439
-213
lines changed
 

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ void addAccessModeTypeMethod(BinderClassWriter cw) {
247247
void addAccessModeMethodIfNeeded(VarHandle.AccessMode mode, BinderClassWriter cw) {
248248
String methName = mode.methodName();
249249
MethodType methType = form.getMethodType(mode.at.ordinal())
250-
.insertParameterTypes(0, BASE_CLASS);
250+
.insertParameterTypes(0, VarHandle.class);
251251

252252
try {
253253
MethodType helperType = methType.insertParameterTypes(2, long.class);
@@ -272,6 +272,7 @@ void addAccessModeMethodIfNeeded(VarHandle.AccessMode mode, BinderClassWriter cw
272272
// offset calculation
273273
int slot = 2;
274274
mv.visitVarInsn(ALOAD, 0); // load recv
275+
mv.visitTypeInsn(CHECKCAST, Type.getInternalName(BASE_CLASS));
275276
mv.visitFieldInsn(GETFIELD, Type.getInternalName(BASE_CLASS), "offset", "J");
276277
for (int i = 0 ; i < dimensions ; i++) {
277278
// load ADD MH

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

+17-2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import jdk.internal.vm.annotation.ForceInline;
3030
import jdk.internal.vm.annotation.Stable;
3131

32+
import java.util.List;
3233
import java.util.function.BiFunction;
3334

3435
/**
@@ -48,17 +49,31 @@
4849
private final VarHandle directTarget; // cache, for performance reasons
4950
private final VarHandle target;
5051
private final BiFunction<AccessMode, MethodHandle, MethodHandle> handleFactory;
52+
private final Class<?> value;
53+
private final Class<?>[] coordinates;
5154

5255
IndirectVarHandle(VarHandle target, Class<?> value, Class<?>[] coordinates, BiFunction<AccessMode, MethodHandle, MethodHandle> handleFactory) {
5356
super(new VarForm(value, coordinates));
5457
this.handleFactory = handleFactory;
5558
this.target = target;
5659
this.directTarget = target.asDirect();
60+
this.value = value;
61+
this.coordinates = coordinates;
62+
}
63+
64+
@Override
65+
public Class<?> varType() {
66+
return value;
67+
}
68+
69+
@Override
70+
public List<Class<?>> coordinateTypes() {
71+
return List.of(coordinates);
5772
}
5873

5974
@Override
6075
MethodType accessModeTypeUncached(AccessMode accessMode) {
61-
return getMethodHandle(accessMode.ordinal()).type().dropParameterTypes(0, 1);
76+
return accessMode.at.accessModeType(directTarget.getClass(), value, coordinates);
6277
}
6378

6479
@Override
@@ -84,6 +99,6 @@ MethodHandle getMethodHandle(int mode) {
8499

85100
@Override
86101
public MethodHandle toMethodHandle(AccessMode accessMode) {
87-
return getMethodHandle(accessMode.ordinal()).bindTo(this.directTarget);
102+
return getMethodHandle(accessMode.ordinal()).bindTo(directTarget);
88103
}
89104
}

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

+5-1
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,7 @@ private static LambdaForm varHandleMethodInvokerHandleForm(VarHandle.AccessMode
415415
final int ARG_LIMIT = ARG_BASE + mtype.parameterCount();
416416
int nameCursor = ARG_LIMIT;
417417
final int VAD_ARG = nameCursor++;
418+
final int UNBOUND_VH = nameCursor++;
418419
final int CHECK_TYPE = nameCursor++;
419420
final int LINKER_CALL = nameCursor++;
420421

@@ -431,14 +432,17 @@ private static LambdaForm varHandleMethodInvokerHandleForm(VarHandle.AccessMode
431432
NamedFunction getter = speciesData.getterFunction(0);
432433
names[VAD_ARG] = new Name(getter, names[THIS_MH]);
433434

435+
names[UNBOUND_VH] = new Name(getFunction(NF_directVarHandleTarget), names[CALL_VH]);
436+
434437
if (isExact) {
435438
names[CHECK_TYPE] = new Name(getFunction(NF_checkVarHandleExactType), names[CALL_VH], names[VAD_ARG]);
436439
} else {
437440
names[CHECK_TYPE] = new Name(getFunction(NF_checkVarHandleGenericType), names[CALL_VH], names[VAD_ARG]);
438441
}
439442
Object[] outArgs = new Object[ARG_LIMIT];
440443
outArgs[0] = names[CHECK_TYPE];
441-
for (int i = 1; i < ARG_LIMIT; i++) {
444+
outArgs[1] = names[UNBOUND_VH];
445+
for (int i = 2; i < ARG_LIMIT; i++) {
442446
outArgs[i] = names[i];
443447
}
444448

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -1890,7 +1890,7 @@ public final String toString() {
18901890
*
18911891
* @return the variable type of variables referenced by this VarHandle
18921892
*/
1893-
public final Class<?> varType() {
1893+
public Class<?> varType() {
18941894
MethodType typeSet = accessModeType(AccessMode.SET);
18951895
return typeSet.parameterType(typeSet.parameterCount() - 1);
18961896
}
@@ -1901,7 +1901,7 @@ public final Class<?> varType() {
19011901
* @return the coordinate types for this VarHandle. The returned
19021902
* list is unmodifiable
19031903
*/
1904-
public final List<Class<?>> coordinateTypes() {
1904+
public List<Class<?>> coordinateTypes() {
19051905
MethodType typeGet = accessModeType(AccessMode.GET);
19061906
return typeGet.parameterList();
19071907
}

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@ private static VarHandle maybeAdapt(VarHandle target) {
334334
if (!VAR_HANDLE_IDENTITY_ADAPT) return target;
335335
target = MethodHandles.filterValue(target,
336336
MethodHandles.identity(target.varType()), MethodHandles.identity(target.varType()));
337-
MethodType mtype = target.accessModeType(VarHandle.AccessMode.GET);
337+
MethodType mtype = target.accessModeType(VarHandle.AccessMode.GET).dropParameterTypes(0, 1);
338338
for (int i = 0 ; i < mtype.parameterCount() ; i++) {
339339
target = MethodHandles.filterCoordinates(target, i, MethodHandles.identity(mtype.parameterType(i)));
340340
}

0 commit comments

Comments
 (0)
Please sign in to comment.