Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;

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

public static class Factory {
Expand All @@ -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
Expand All @@ -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);
}

Expand Down Expand Up @@ -195,26 +195,26 @@ 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();
return mergeValues(kit, merge, kit.bci(), methodReturnValue, receiverOrCreatedObject);
}

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();
Expand Down Expand Up @@ -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);
Expand Down