Search in sources :

Example 6 with Signature

use of jdk.vm.ci.meta.Signature in project graal by oracle.

the class JNINativeCallWrapperMethod method buildGraph.

@Override
public StructuredGraph buildGraph(DebugContext debug, ResolvedJavaMethod method, HostedProviders providers, Purpose purpose) {
    JNIGraphKit kit = new JNIGraphKit(debug, providers, method);
    StructuredGraph graph = kit.getGraph();
    InvokeWithExceptionNode handleFrame = kit.nativeCallPrologue();
    ValueNode callAddress = kit.nativeCallAddress(kit.createObject(linkage));
    ValueNode environment = kit.environment();
    JavaType javaReturnType = method.getSignature().getReturnType(null);
    JavaType[] javaArgumentTypes = method.toParameterTypes();
    List<ValueNode> javaArguments = kit.loadArguments(javaArgumentTypes);
    List<ValueNode> jniArguments = new ArrayList<>(2 + javaArguments.size());
    List<JavaType> jniArgumentTypes = new ArrayList<>(jniArguments.size());
    JavaType environmentType = providers.getMetaAccess().lookupJavaType(JNIEnvironment.class);
    JavaType objectHandleType = providers.getMetaAccess().lookupJavaType(JNIObjectHandle.class);
    jniArguments.add(environment);
    jniArgumentTypes.add(environmentType);
    if (method.isStatic()) {
        JavaConstant clazz = providers.getConstantReflection().asJavaClass(method.getDeclaringClass());
        ConstantNode clazzNode = ConstantNode.forConstant(clazz, providers.getMetaAccess(), graph);
        ValueNode box = kit.boxObjectInLocalHandle(clazzNode);
        jniArguments.add(box);
        jniArgumentTypes.add(objectHandleType);
    }
    for (int i = 0; i < javaArguments.size(); i++) {
        ValueNode arg = javaArguments.get(i);
        JavaType argType = javaArgumentTypes[i];
        if (javaArgumentTypes[i].getJavaKind().isObject()) {
            ValueNode obj = javaArguments.get(i);
            arg = kit.boxObjectInLocalHandle(obj);
            argType = objectHandleType;
        }
        jniArguments.add(arg);
        jniArgumentTypes.add(argType);
    }
    assert jniArguments.size() == jniArgumentTypes.size();
    JavaType jniReturnType = javaReturnType;
    if (jniReturnType.getJavaKind().isObject()) {
        jniReturnType = objectHandleType;
    }
    if (getOriginal().isSynchronized()) {
        ValueNode monitorObject;
        if (method.isStatic()) {
            Constant hubConstant = providers.getConstantReflection().asObjectHub(method.getDeclaringClass());
            DynamicHub hub = (DynamicHub) SubstrateObjectConstant.asObject(hubConstant);
            monitorObject = ConstantNode.forConstant(SubstrateObjectConstant.forObject(hub), providers.getMetaAccess(), graph);
        } else {
            monitorObject = javaArguments.get(0);
        }
        MonitorIdNode monitorId = graph.add(new MonitorIdNode(kit.getFrameState().lockDepth(false)));
        MonitorEnterNode monitorEnter = kit.append(new MonitorEnterNode(monitorObject, monitorId));
        kit.getFrameState().pushLock(monitorEnter.object(), monitorEnter.getMonitorId());
        monitorEnter.setStateAfter(kit.getFrameState().create(kit.bci(), monitorEnter));
    }
    kit.getFrameState().clearLocals();
    Signature jniSignature = new JNISignature(jniArgumentTypes, jniReturnType);
    ValueNode returnValue = kit.createCFunctionCall(callAddress, method, jniArguments, jniSignature, true, false);
    if (getOriginal().isSynchronized()) {
        MonitorIdNode monitorId = kit.getFrameState().peekMonitorId();
        ValueNode monitorObject = kit.getFrameState().popLock();
        MonitorExitNode monitorExit = kit.append(new MonitorExitNode(monitorObject, monitorId, null));
        monitorExit.setStateAfter(kit.getFrameState().create(kit.bci(), monitorExit));
    }
    if (javaReturnType.getJavaKind().isObject()) {
        // before destroying handles in epilogue
        returnValue = kit.unboxHandle(returnValue);
    }
    kit.nativeCallEpilogue(handleFrame);
    kit.rethrowPendingException();
    if (javaReturnType.getJavaKind().isObject()) {
        // Just before return to always run the epilogue and never suppress a pending exception
        returnValue = castObject(kit, returnValue, (ResolvedJavaType) javaReturnType);
    }
    kit.createReturn(returnValue, javaReturnType.getJavaKind());
    kit.mergeUnwinds();
    assert graph.verify();
    return graph;
}
Also used : MonitorIdNode(org.graalvm.compiler.nodes.java.MonitorIdNode) Constant(jdk.vm.ci.meta.Constant) SubstrateObjectConstant(com.oracle.svm.core.meta.SubstrateObjectConstant) JavaConstant(jdk.vm.ci.meta.JavaConstant) ArrayList(java.util.ArrayList) JavaConstant(jdk.vm.ci.meta.JavaConstant) MonitorExitNode(org.graalvm.compiler.nodes.java.MonitorExitNode) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) JavaType(jdk.vm.ci.meta.JavaType) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) InvokeWithExceptionNode(org.graalvm.compiler.nodes.InvokeWithExceptionNode) MonitorEnterNode(org.graalvm.compiler.nodes.java.MonitorEnterNode) Signature(jdk.vm.ci.meta.Signature) ValueNode(org.graalvm.compiler.nodes.ValueNode) DynamicHub(com.oracle.svm.core.hub.DynamicHub)

Example 7 with Signature

use of jdk.vm.ci.meta.Signature in project graal by oracle.

the class JNINativeCallWrapperMethod method getMaxLocals.

@Override
public int getMaxLocals() {
    if (maxLocals == -1) {
        maxLocals = 0;
        Signature sig = getOriginal().getSignature();
        int count = sig.getParameterCount(false);
        if (!getOriginal().isStatic()) {
            maxLocals++;
        }
        for (int i = 0; i < count; i++) {
            maxLocals++;
            if (sig.getParameterKind(i).needsTwoSlots()) {
                maxLocals++;
            }
        }
    }
    return maxLocals;
}
Also used : Signature(jdk.vm.ci.meta.Signature)

Example 8 with Signature

use of jdk.vm.ci.meta.Signature in project graal by oracle.

the class GraphKit method checkArgs.

/**
 * Determines if a given set of arguments is compatible with the signature of a given method.
 *
 * @return true if {@code args} are compatible with the signature if {@code method}
 * @throws AssertionError if {@code args} are not compatible with the signature if
 *             {@code method}
 */
public boolean checkArgs(ResolvedJavaMethod method, ValueNode... args) {
    Signature signature = method.getSignature();
    boolean isStatic = method.isStatic();
    if (signature.getParameterCount(!isStatic) != args.length) {
        throw new AssertionError(graph + ": wrong number of arguments to " + method);
    }
    int argIndex = 0;
    if (!isStatic) {
        JavaKind expected = asKind(method.getDeclaringClass());
        JavaKind actual = args[argIndex++].stamp(NodeView.DEFAULT).getStackKind();
        assert expected == actual : graph + ": wrong kind of value for receiver argument of call to " + method + " [" + actual + " != " + expected + "]";
    }
    for (int i = 0; i != signature.getParameterCount(false); i++) {
        JavaKind expected = asKind(signature.getParameterType(i, method.getDeclaringClass())).getStackKind();
        JavaKind actual = args[argIndex++].stamp(NodeView.DEFAULT).getStackKind();
        if (expected != actual) {
            throw new AssertionError(graph + ": wrong kind of value for argument " + i + " of call to " + method + " [" + actual + " != " + expected + "]");
        }
    }
    return true;
}
Also used : Signature(jdk.vm.ci.meta.Signature) JavaKind(jdk.vm.ci.meta.JavaKind)

Example 9 with Signature

use of jdk.vm.ci.meta.Signature in project graal by oracle.

the class GraphKit method createInvoke.

/**
 * Creates and appends an {@link InvokeNode} for a call to a given method with a given set of
 * arguments.
 */
@SuppressWarnings("try")
public InvokeNode createInvoke(ResolvedJavaMethod method, InvokeKind invokeKind, FrameStateBuilder frameStateBuilder, int bci, ValueNode... args) {
    try (DebugCloseable context = graph.withNodeSourcePosition(NodeSourcePosition.substitution(graph.currentNodeSourcePosition(), method))) {
        assert method.isStatic() == (invokeKind == InvokeKind.Static);
        Signature signature = method.getSignature();
        JavaType returnType = signature.getReturnType(null);
        assert checkArgs(method, args);
        StampPair returnStamp = graphBuilderPlugins.getOverridingStamp(this, returnType, false);
        if (returnStamp == null) {
            returnStamp = StampFactory.forDeclaredType(graph.getAssumptions(), returnType, false);
        }
        MethodCallTargetNode callTarget = graph.add(createMethodCallTarget(invokeKind, method, args, returnStamp, bci));
        InvokeNode invoke = append(new InvokeNode(callTarget, bci));
        if (frameStateBuilder != null) {
            if (invoke.getStackKind() != JavaKind.Void) {
                frameStateBuilder.push(invoke.getStackKind(), invoke);
            }
            invoke.setStateAfter(frameStateBuilder.create(bci, invoke));
            if (invoke.getStackKind() != JavaKind.Void) {
                frameStateBuilder.pop(invoke.getStackKind());
            }
        }
        return invoke;
    }
}
Also used : JavaType(jdk.vm.ci.meta.JavaType) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) Signature(jdk.vm.ci.meta.Signature) StampPair(org.graalvm.compiler.core.common.type.StampPair) InvokeNode(org.graalvm.compiler.nodes.InvokeNode) DebugCloseable(org.graalvm.compiler.debug.DebugCloseable)

Example 10 with Signature

use of jdk.vm.ci.meta.Signature in project graal by oracle.

the class MethodHandleNode method getTargetInvokeNode.

/**
 * Helper function to get the {@link InvokeNode} for the targetMethod of a
 * java.lang.invoke.MemberName.
 *
 * @param adder
 * @param target the target, already loaded from the member name node
 *
 * @return invoke node for the member name target
 */
private static InvokeNode getTargetInvokeNode(GraphAdder adder, IntrinsicMethod intrinsicMethod, int bci, StampPair returnStamp, ValueNode[] originalArguments, ResolvedJavaMethod target, ResolvedJavaMethod original) {
    if (target == null) {
        return null;
    }
    // In lambda forms we erase signature types to avoid resolving issues
    // involving class loaders. When we optimize a method handle invoke
    // to a direct call we must cast the receiver and arguments to its
    // actual types.
    Signature signature = target.getSignature();
    final boolean isStatic = target.isStatic();
    final int receiverSkip = isStatic ? 0 : 1;
    Assumptions assumptions = adder.getAssumptions();
    ResolvedJavaMethod realTarget = null;
    if (target.canBeStaticallyBound()) {
        realTarget = target;
    } else {
        ResolvedJavaType targetType = target.getDeclaringClass();
        // Try to bind based on the declaredType
        AssumptionResult<ResolvedJavaMethod> concreteMethod = targetType.findUniqueConcreteMethod(target);
        if (concreteMethod == null) {
            // Try to get the most accurate receiver type
            if (intrinsicMethod == IntrinsicMethod.LINK_TO_VIRTUAL || intrinsicMethod == IntrinsicMethod.LINK_TO_INTERFACE) {
                ValueNode receiver = getReceiver(originalArguments);
                TypeReference receiverType = StampTool.typeReferenceOrNull(receiver.stamp(NodeView.DEFAULT));
                if (receiverType != null) {
                    concreteMethod = receiverType.getType().findUniqueConcreteMethod(target);
                }
            }
        }
        if (concreteMethod != null && concreteMethod.canRecordTo(assumptions)) {
            concreteMethod.recordTo(assumptions);
            realTarget = concreteMethod.getResult();
        }
    }
    if (realTarget != null) {
        // Don't mutate the passed in arguments
        ValueNode[] arguments = originalArguments.clone();
        // Cast receiver to its type.
        if (!isStatic) {
            JavaType receiverType = target.getDeclaringClass();
            maybeCastArgument(adder, arguments, 0, receiverType);
        }
        // Cast reference arguments to its type.
        for (int index = 0; index < signature.getParameterCount(false); index++) {
            JavaType parameterType = signature.getParameterType(index, target.getDeclaringClass());
            maybeCastArgument(adder, arguments, receiverSkip + index, parameterType);
        }
        InvokeNode invoke = createTargetInvokeNode(assumptions, intrinsicMethod, realTarget, original, bci, returnStamp, arguments);
        assert invoke != null : "graph has been modified so this must result an invoke";
        return invoke;
    }
    return null;
}
Also used : ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) JavaType(jdk.vm.ci.meta.JavaType) Signature(jdk.vm.ci.meta.Signature) Assumptions(jdk.vm.ci.meta.Assumptions) ValueNode(org.graalvm.compiler.nodes.ValueNode) InvokeNode(org.graalvm.compiler.nodes.InvokeNode) TypeReference(org.graalvm.compiler.core.common.type.TypeReference) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType)

Aggregations

Signature (jdk.vm.ci.meta.Signature)16 ResolvedJavaType (jdk.vm.ci.meta.ResolvedJavaType)10 JavaType (jdk.vm.ci.meta.JavaType)9 JavaKind (jdk.vm.ci.meta.JavaKind)8 ResolvedJavaMethod (jdk.vm.ci.meta.ResolvedJavaMethod)6 ValueNode (org.graalvm.compiler.nodes.ValueNode)5 FrameStateBuilder (org.graalvm.compiler.java.FrameStateBuilder)4 StampPair (org.graalvm.compiler.core.common.type.StampPair)3 InvokeKind (org.graalvm.compiler.nodes.CallTargetNode.InvokeKind)3 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)3 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)3 CFunction (org.graalvm.nativeimage.c.function.CFunction)3 CGlobalDataLoadAddressNode (com.oracle.svm.core.graal.nodes.CGlobalDataLoadAddressNode)2 SharedMethod (com.oracle.svm.core.meta.SharedMethod)2 NativeLibraries (com.oracle.svm.hosted.c.NativeLibraries)2 JNIEnvironment (com.oracle.svm.jni.nativeapi.JNIEnvironment)2 ArrayList (java.util.ArrayList)2 MetaAccessProvider (jdk.vm.ci.meta.MetaAccessProvider)2 TypeReference (org.graalvm.compiler.core.common.type.TypeReference)2 InvokeNode (org.graalvm.compiler.nodes.InvokeNode)2