diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNIJavaCallWrapperMethod.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNIJavaCallWrapperMethod.java index 10504c3a663e..76e650e417dc 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNIJavaCallWrapperMethod.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNIJavaCallWrapperMethod.java @@ -36,7 +36,6 @@ import org.graalvm.compiler.nodes.ConstantNode; import org.graalvm.compiler.nodes.IndirectCallTargetNode; import org.graalvm.compiler.nodes.InvokeWithExceptionNode; -import org.graalvm.compiler.nodes.LogicNode; import org.graalvm.compiler.nodes.NodeView; import org.graalvm.compiler.nodes.ProfileData.BranchProbabilityData; import org.graalvm.compiler.nodes.StructuredGraph; @@ -47,7 +46,6 @@ import org.graalvm.compiler.nodes.calc.ObjectEqualsNode; import org.graalvm.compiler.nodes.extended.BranchProbabilityNode; import org.graalvm.compiler.nodes.java.ExceptionObjectNode; -import org.graalvm.compiler.nodes.java.InstanceOfDynamicNode; import org.graalvm.compiler.nodes.type.StampTool; import org.graalvm.compiler.word.WordTypes; @@ -85,7 +83,6 @@ * JNI functions documentation */ public class JNIJavaCallWrapperMethod extends NonBytecodeMethod { - private static final Constructor CLASS_CAST_EXCEPTION_CONSTRUCTOR = ReflectionUtil.lookupConstructor(ClassCastException.class); private static final Constructor INSTANTIATION_EXCEPTION_CONSTRUCTOR = ReflectionUtil.lookupConstructor(InstantiationException.class); public static class Factory { @@ -100,9 +97,14 @@ public boolean canInvokeConstructorOnObject(ResolvedJavaMethod constructor, Meta } public static SimpleSignature getGeneralizedSignatureForTarget(ResolvedJavaMethod targetMethod, MetaAccessProvider originalMetaAccess) { + ResolvedJavaType objectType = originalMetaAccess.lookupJavaType(Object.class); JavaType[] paramTypes = targetMethod.getSignature().toParameterTypes(null); - // Note: our parameters do not include the receiver, but we can do a type check based on the - // JNIAccessibleMethod object we get from the method id. + // Note: does not include the receiver. + for (int i = 0; i < paramTypes.length; i++) { + if (paramTypes[i].getJavaKind().isObject()) { + paramTypes[i] = objectType; + } + } JavaKind returnKind = targetMethod.getSignature().getReturnKind(); if (targetMethod.isConstructor()) { returnKind = JavaKind.Object; // return new (or previously allocated) object @@ -111,9 +113,7 @@ public static SimpleSignature getGeneralizedSignatureForTarget(ResolvedJavaMetho // wrappers. This is fine with our supported 64-bit calling conventions. returnKind = JavaKind.Long; } - // Note: no need to distinguish between object return types for us, the return value must - // match in Java code and we return it as handle anyway. - JavaType returnType = originalMetaAccess.lookupJavaType(returnKind.isObject() ? Object.class : returnKind.toJavaClass()); + JavaType returnType = returnKind.isObject() ? objectType : originalMetaAccess.lookupJavaType(returnKind.toJavaClass()); return new SimpleSignature(paramTypes, returnType); } @@ -195,13 +195,13 @@ public StructuredGraph buildGraph(DebugContext debug, ResolvedJavaMethod method, private ValueNode createCall(JNIGraphKit kit, Signature invokeSignature, ValueNode methodId, ValueNode receiverOrClass, ValueNode nonVirtual, ValueNode[] args) { ValueNode declaringClass = kit.getDeclaringClassForMethod(methodId); if (!invokeSignature.getReturnKind().isObject()) { - return createRegularMethodCall(kit, invokeSignature, methodId, declaringClass, receiverOrClass, nonVirtual, args); + return createRegularMethodCall(kit, invokeSignature, methodId, receiverOrClass, nonVirtual, args); } ValueNode newObjectAddress = kit.getNewObjectAddress(methodId); kit.startIf(IntegerEqualsNode.create(newObjectAddress, kit.createWord(0), NodeView.DEFAULT), BranchProbabilityData.unknown()); kit.thenPart(); - ValueNode methodReturnValue = createRegularMethodCall(kit, invokeSignature, methodId, declaringClass, receiverOrClass, nonVirtual, args); + ValueNode methodReturnValue = createRegularMethodCall(kit, invokeSignature, methodId, receiverOrClass, nonVirtual, args); kit.elsePart(); ValueNode receiverOrCreatedObject = createNewObjectOrConstructorCall(kit, invokeSignature, methodId, declaringClass, newObjectAddress, receiverOrClass, args); AbstractMergeNode merge = kit.endIf(); @@ -209,12 +209,12 @@ private ValueNode createCall(JNIGraphKit kit, Signature invokeSignature, ValueNo } private static ValueNode createRegularMethodCall(JNIGraphKit kit, Signature invokeSignature, ValueNode methodId, - ValueNode declaringClass, ValueNode receiverOrClass, ValueNode nonVirtual, ValueNode[] args) { + ValueNode receiverOrClass, ValueNode nonVirtual, ValueNode[] args) { ValueNode methodAddress = kit.getJavaCallAddress(methodId, receiverOrClass, nonVirtual); ValueNode isStatic = kit.isStaticMethod(methodId); kit.startIf(IntegerEqualsNode.create(isStatic, kit.createInt(0), NodeView.DEFAULT), BranchProbabilityData.unknown()); kit.thenPart(); - ValueNode nonstaticResult = createMethodCallWithReceiver(kit, invokeSignature, declaringClass, methodAddress, receiverOrClass, args); + ValueNode nonstaticResult = createMethodCallWithReceiver(kit, invokeSignature, methodAddress, receiverOrClass, args); kit.elsePart(); ValueNode staticResult = createMethodCall(kit, invokeSignature.getReturnType(null), invokeSignature.toParameterTypes(null), methodAddress, args); AbstractMergeNode merge = kit.endIf(); @@ -243,36 +243,20 @@ protected ValueNode createNewObjectOrConstructorCall(JNIGraphKit kit, Signature return mergeValues(kit, merge, kit.bci(), createdObject, receiverOrClass); } - protected ValueNode createConstructorCall(JNIGraphKit kit, Signature invokeSignature, ValueNode methodId, ValueNode declaringClass, ValueNode receiverOrClass, ValueNode[] args) { + protected ValueNode createConstructorCall(JNIGraphKit kit, Signature invokeSignature, ValueNode methodId, + @SuppressWarnings("unused") ValueNode declaringClass, ValueNode receiverOrClass, ValueNode[] args) { ValueNode methodAddress = kit.getJavaCallAddress(methodId, receiverOrClass, kit.createInt(1)); - return createMethodCallWithReceiver(kit, invokeSignature, declaringClass, methodAddress, receiverOrClass, args); + return createMethodCallWithReceiver(kit, invokeSignature, methodAddress, receiverOrClass, args); } - private static ValueNode createMethodCallWithReceiver(JNIGraphKit kit, Signature invokeSignature, ValueNode declaringClass, ValueNode methodAddress, ValueNode receiver, ValueNode[] args) { - dynamicTypeCheckReceiver(kit, declaringClass, receiver); - + private static ValueNode createMethodCallWithReceiver(JNIGraphKit kit, Signature invokeSignature, ValueNode methodAddress, ValueNode receiver, ValueNode[] args) { ValueNode[] argsWithReceiver = new ValueNode[1 + args.length]; - argsWithReceiver[0] = receiver; + argsWithReceiver[0] = kit.maybeCreateExplicitNullCheck(receiver); System.arraycopy(args, 0, argsWithReceiver, 1, args.length); JavaType[] paramTypes = invokeSignature.toParameterTypes(kit.getMetaAccess().lookupJavaType(Object.class)); return createMethodCall(kit, invokeSignature.getReturnType(null), paramTypes, methodAddress, argsWithReceiver); } - private static void dynamicTypeCheckReceiver(JNIGraphKit kit, ValueNode declaringClass, ValueNode receiver) { - ValueNode nonNullReceiver = kit.maybeCreateExplicitNullCheck(receiver); - - LogicNode isInstance = kit.append(InstanceOfDynamicNode.create(kit.getAssumptions(), kit.getConstantReflection(), declaringClass, nonNullReceiver, false, false)); - kit.startIf(isInstance, BranchProbabilityNode.FAST_PATH_PROFILE); - kit.elsePart(); - - ResolvedJavaMethod exceptionCtor = kit.getMetaAccess().lookupJavaMethod(CLASS_CAST_EXCEPTION_CONSTRUCTOR); - ResolvedJavaMethod throwMethod = FactoryMethodSupport.singleton().lookup((UniverseMetaAccess) kit.getMetaAccess(), exceptionCtor, true); - kit.createInvokeWithExceptionAndUnwind(throwMethod, CallTargetNode.InvokeKind.Static, kit.getFrameState(), kit.bci()); - kit.append(new LoweredDeadEndNode()); - - kit.endIf(); - } - private static ValueNode createNewObjectCall(JNIGraphKit kit, Signature invokeSignature, ValueNode newObjectAddress, ValueNode[] args) { ConstantNode abstractTypeSentinel = kit.createWord(JNIAccessibleMethod.NEW_OBJECT_INVALID_FOR_ABSTRACT_TYPE); kit.startIf(IntegerEqualsNode.create(newObjectAddress, abstractTypeSentinel, NodeView.DEFAULT), BranchProbabilityNode.SLOW_PATH_PROFILE);