Skip to content

Commit 393a004

Browse files
committed
[GR-45909] Remove type checks from JNI to-Java call stubs, which can break compatibility.
PullRequest: graal/14456
2 parents f2add32 + 1c4e579 commit 393a004

File tree

1 file changed

+17
-33
lines changed

1 file changed

+17
-33
lines changed

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNIJavaCallWrapperMethod.java

Lines changed: 17 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@
3636
import org.graalvm.compiler.nodes.ConstantNode;
3737
import org.graalvm.compiler.nodes.IndirectCallTargetNode;
3838
import org.graalvm.compiler.nodes.InvokeWithExceptionNode;
39-
import org.graalvm.compiler.nodes.LogicNode;
4039
import org.graalvm.compiler.nodes.NodeView;
4140
import org.graalvm.compiler.nodes.ProfileData.BranchProbabilityData;
4241
import org.graalvm.compiler.nodes.StructuredGraph;
@@ -47,7 +46,6 @@
4746
import org.graalvm.compiler.nodes.calc.ObjectEqualsNode;
4847
import org.graalvm.compiler.nodes.extended.BranchProbabilityNode;
4948
import org.graalvm.compiler.nodes.java.ExceptionObjectNode;
50-
import org.graalvm.compiler.nodes.java.InstanceOfDynamicNode;
5149
import org.graalvm.compiler.nodes.type.StampTool;
5250
import org.graalvm.compiler.word.WordTypes;
5351

@@ -85,7 +83,6 @@
8583
* JNI functions documentation</a>
8684
*/
8785
public class JNIJavaCallWrapperMethod extends NonBytecodeMethod {
88-
private static final Constructor<ClassCastException> CLASS_CAST_EXCEPTION_CONSTRUCTOR = ReflectionUtil.lookupConstructor(ClassCastException.class);
8986
private static final Constructor<InstantiationException> INSTANTIATION_EXCEPTION_CONSTRUCTOR = ReflectionUtil.lookupConstructor(InstantiationException.class);
9087

9188
public static class Factory {
@@ -100,9 +97,14 @@ public boolean canInvokeConstructorOnObject(ResolvedJavaMethod constructor, Meta
10097
}
10198

10299
public static SimpleSignature getGeneralizedSignatureForTarget(ResolvedJavaMethod targetMethod, MetaAccessProvider originalMetaAccess) {
100+
ResolvedJavaType objectType = originalMetaAccess.lookupJavaType(Object.class);
103101
JavaType[] paramTypes = targetMethod.getSignature().toParameterTypes(null);
104-
// Note: our parameters do not include the receiver, but we can do a type check based on the
105-
// JNIAccessibleMethod object we get from the method id.
102+
// Note: does not include the receiver.
103+
for (int i = 0; i < paramTypes.length; i++) {
104+
if (paramTypes[i].getJavaKind().isObject()) {
105+
paramTypes[i] = objectType;
106+
}
107+
}
106108
JavaKind returnKind = targetMethod.getSignature().getReturnKind();
107109
if (targetMethod.isConstructor()) {
108110
returnKind = JavaKind.Object; // return new (or previously allocated) object
@@ -111,9 +113,7 @@ public static SimpleSignature getGeneralizedSignatureForTarget(ResolvedJavaMetho
111113
// wrappers. This is fine with our supported 64-bit calling conventions.
112114
returnKind = JavaKind.Long;
113115
}
114-
// Note: no need to distinguish between object return types for us, the return value must
115-
// match in Java code and we return it as handle anyway.
116-
JavaType returnType = originalMetaAccess.lookupJavaType(returnKind.isObject() ? Object.class : returnKind.toJavaClass());
116+
JavaType returnType = returnKind.isObject() ? objectType : originalMetaAccess.lookupJavaType(returnKind.toJavaClass());
117117
return new SimpleSignature(paramTypes, returnType);
118118
}
119119

@@ -195,26 +195,26 @@ public StructuredGraph buildGraph(DebugContext debug, ResolvedJavaMethod method,
195195
private ValueNode createCall(JNIGraphKit kit, Signature invokeSignature, ValueNode methodId, ValueNode receiverOrClass, ValueNode nonVirtual, ValueNode[] args) {
196196
ValueNode declaringClass = kit.getDeclaringClassForMethod(methodId);
197197
if (!invokeSignature.getReturnKind().isObject()) {
198-
return createRegularMethodCall(kit, invokeSignature, methodId, declaringClass, receiverOrClass, nonVirtual, args);
198+
return createRegularMethodCall(kit, invokeSignature, methodId, receiverOrClass, nonVirtual, args);
199199
}
200200

201201
ValueNode newObjectAddress = kit.getNewObjectAddress(methodId);
202202
kit.startIf(IntegerEqualsNode.create(newObjectAddress, kit.createWord(0), NodeView.DEFAULT), BranchProbabilityData.unknown());
203203
kit.thenPart();
204-
ValueNode methodReturnValue = createRegularMethodCall(kit, invokeSignature, methodId, declaringClass, receiverOrClass, nonVirtual, args);
204+
ValueNode methodReturnValue = createRegularMethodCall(kit, invokeSignature, methodId, receiverOrClass, nonVirtual, args);
205205
kit.elsePart();
206206
ValueNode receiverOrCreatedObject = createNewObjectOrConstructorCall(kit, invokeSignature, methodId, declaringClass, newObjectAddress, receiverOrClass, args);
207207
AbstractMergeNode merge = kit.endIf();
208208
return mergeValues(kit, merge, kit.bci(), methodReturnValue, receiverOrCreatedObject);
209209
}
210210

211211
private static ValueNode createRegularMethodCall(JNIGraphKit kit, Signature invokeSignature, ValueNode methodId,
212-
ValueNode declaringClass, ValueNode receiverOrClass, ValueNode nonVirtual, ValueNode[] args) {
212+
ValueNode receiverOrClass, ValueNode nonVirtual, ValueNode[] args) {
213213
ValueNode methodAddress = kit.getJavaCallAddress(methodId, receiverOrClass, nonVirtual);
214214
ValueNode isStatic = kit.isStaticMethod(methodId);
215215
kit.startIf(IntegerEqualsNode.create(isStatic, kit.createInt(0), NodeView.DEFAULT), BranchProbabilityData.unknown());
216216
kit.thenPart();
217-
ValueNode nonstaticResult = createMethodCallWithReceiver(kit, invokeSignature, declaringClass, methodAddress, receiverOrClass, args);
217+
ValueNode nonstaticResult = createMethodCallWithReceiver(kit, invokeSignature, methodAddress, receiverOrClass, args);
218218
kit.elsePart();
219219
ValueNode staticResult = createMethodCall(kit, invokeSignature.getReturnType(null), invokeSignature.toParameterTypes(null), methodAddress, args);
220220
AbstractMergeNode merge = kit.endIf();
@@ -243,36 +243,20 @@ protected ValueNode createNewObjectOrConstructorCall(JNIGraphKit kit, Signature
243243
return mergeValues(kit, merge, kit.bci(), createdObject, receiverOrClass);
244244
}
245245

246-
protected ValueNode createConstructorCall(JNIGraphKit kit, Signature invokeSignature, ValueNode methodId, ValueNode declaringClass, ValueNode receiverOrClass, ValueNode[] args) {
246+
protected ValueNode createConstructorCall(JNIGraphKit kit, Signature invokeSignature, ValueNode methodId,
247+
@SuppressWarnings("unused") ValueNode declaringClass, ValueNode receiverOrClass, ValueNode[] args) {
247248
ValueNode methodAddress = kit.getJavaCallAddress(methodId, receiverOrClass, kit.createInt(1));
248-
return createMethodCallWithReceiver(kit, invokeSignature, declaringClass, methodAddress, receiverOrClass, args);
249+
return createMethodCallWithReceiver(kit, invokeSignature, methodAddress, receiverOrClass, args);
249250
}
250251

251-
private static ValueNode createMethodCallWithReceiver(JNIGraphKit kit, Signature invokeSignature, ValueNode declaringClass, ValueNode methodAddress, ValueNode receiver, ValueNode[] args) {
252-
dynamicTypeCheckReceiver(kit, declaringClass, receiver);
253-
252+
private static ValueNode createMethodCallWithReceiver(JNIGraphKit kit, Signature invokeSignature, ValueNode methodAddress, ValueNode receiver, ValueNode[] args) {
254253
ValueNode[] argsWithReceiver = new ValueNode[1 + args.length];
255-
argsWithReceiver[0] = receiver;
254+
argsWithReceiver[0] = kit.maybeCreateExplicitNullCheck(receiver);
256255
System.arraycopy(args, 0, argsWithReceiver, 1, args.length);
257256
JavaType[] paramTypes = invokeSignature.toParameterTypes(kit.getMetaAccess().lookupJavaType(Object.class));
258257
return createMethodCall(kit, invokeSignature.getReturnType(null), paramTypes, methodAddress, argsWithReceiver);
259258
}
260259

261-
private static void dynamicTypeCheckReceiver(JNIGraphKit kit, ValueNode declaringClass, ValueNode receiver) {
262-
ValueNode nonNullReceiver = kit.maybeCreateExplicitNullCheck(receiver);
263-
264-
LogicNode isInstance = kit.append(InstanceOfDynamicNode.create(kit.getAssumptions(), kit.getConstantReflection(), declaringClass, nonNullReceiver, false, false));
265-
kit.startIf(isInstance, BranchProbabilityNode.FAST_PATH_PROFILE);
266-
kit.elsePart();
267-
268-
ResolvedJavaMethod exceptionCtor = kit.getMetaAccess().lookupJavaMethod(CLASS_CAST_EXCEPTION_CONSTRUCTOR);
269-
ResolvedJavaMethod throwMethod = FactoryMethodSupport.singleton().lookup((UniverseMetaAccess) kit.getMetaAccess(), exceptionCtor, true);
270-
kit.createInvokeWithExceptionAndUnwind(throwMethod, CallTargetNode.InvokeKind.Static, kit.getFrameState(), kit.bci());
271-
kit.append(new LoweredDeadEndNode());
272-
273-
kit.endIf();
274-
}
275-
276260
private static ValueNode createNewObjectCall(JNIGraphKit kit, Signature invokeSignature, ValueNode newObjectAddress, ValueNode[] args) {
277261
ConstantNode abstractTypeSentinel = kit.createWord(JNIAccessibleMethod.NEW_OBJECT_INVALID_FOR_ABSTRACT_TYPE);
278262
kit.startIf(IntegerEqualsNode.create(newObjectAddress, abstractTypeSentinel, NodeView.DEFAULT), BranchProbabilityNode.SLOW_PATH_PROFILE);

0 commit comments

Comments
 (0)