Search in sources :

Example 76 with ResolvedJavaType

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

the class JNIJavaCallWrapperMethod method createSignature.

private JNISignature createSignature(MetaAccessProvider metaAccess) {
    ResolvedJavaType objectHandle = metaAccess.lookupJavaType(JNIObjectHandle.class);
    List<JavaType> args = new ArrayList<>();
    args.add(metaAccess.lookupJavaType(JNIEnvironment.class));
    // this (instance method) or class (static method)
    args.add(objectHandle);
    if (nonVirtual) {
        // class of implementation to invoke
        args.add(objectHandle);
    }
    args.add(metaAccess.lookupJavaType(JNIMethodId.class));
    Signature targetSignature = targetMethod.getSignature();
    if (callVariant == CallVariant.VARARGS) {
        for (JavaType targetArg : targetSignature.toParameterTypes(null)) {
            JavaKind kind = targetArg.getJavaKind();
            if (kind.isObject()) {
                args.add(objectHandle);
            } else if (kind == JavaKind.Float) {
                // C varargs promote float to double
                args.add(metaAccess.lookupJavaType(JavaKind.Double.toJavaClass()));
            } else {
                args.add(targetArg);
            }
        }
    } else if (callVariant == CallVariant.ARRAY) {
        // const jvalue *
        args.add(metaAccess.lookupJavaType(JNIValue.class));
    } else if (callVariant == CallVariant.VA_LIST) {
        // va_list (a pointer of some kind)
        args.add(metaAccess.lookupJavaType(WordBase.class));
    } else {
        throw VMError.shouldNotReachHere();
    }
    JavaType returnType = targetSignature.getReturnType(null);
    if (returnType.getJavaKind().isObject() || targetMethod.isConstructor()) {
        // Constructor: returns `this` to implement NewObject
        returnType = objectHandle;
    }
    return new JNISignature(args, returnType);
}
Also used : ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) JavaType(jdk.vm.ci.meta.JavaType) JNIEnvironment(com.oracle.svm.jni.nativeapi.JNIEnvironment) Signature(jdk.vm.ci.meta.Signature) ArrayList(java.util.ArrayList) WordBase(org.graalvm.word.WordBase) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) JNIMethodId(com.oracle.svm.jni.nativeapi.JNIMethodId) JavaKind(jdk.vm.ci.meta.JavaKind)

Example 77 with ResolvedJavaType

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

the class JNIJavaCallWrapperMethod method buildGraph.

@Override
public StructuredGraph buildGraph(DebugContext debug, ResolvedJavaMethod method, HostedProviders providers, Purpose purpose) {
    UniverseMetaAccess metaAccess = (UniverseMetaAccess) providers.getMetaAccess();
    JNIGraphKit kit = new JNIGraphKit(debug, providers, method);
    StructuredGraph graph = kit.getGraph();
    FrameStateBuilder state = new FrameStateBuilder(null, method, graph);
    state.initializeForMethodStart(null, true, providers.getGraphBuilderPlugins());
    JavaKind vmThreadKind = metaAccess.lookupJavaType(JNIEnvironment.class).getJavaKind();
    ValueNode vmThread = kit.loadLocal(0, vmThreadKind);
    kit.append(new CEntryPointEnterNode(EnterAction.Enter, vmThread));
    ResolvedJavaMethod invokeMethod = providers.getMetaAccess().lookupJavaMethod(reflectMethod);
    Signature invokeSignature = invokeMethod.getSignature();
    List<Pair<ValueNode, ResolvedJavaType>> argsWithTypes = loadAndUnboxArguments(kit, providers, invokeMethod, invokeSignature);
    JavaKind returnKind = invokeSignature.getReturnKind();
    if (invokeMethod.isConstructor()) {
        // return `this` to implement NewObject
        assert returnKind == JavaKind.Void;
        returnKind = JavaKind.Object;
    }
    IfNode ifNode = kit.startIf(null, BranchProbabilityNode.FAST_PATH_PROBABILITY);
    kit.thenPart();
    LogicNode typeChecks = LogicConstantNode.tautology(kit.getGraph());
    ValueNode[] args = new ValueNode[argsWithTypes.size()];
    for (int i = 0; i < argsWithTypes.size(); i++) {
        ValueNode value = argsWithTypes.get(i).getLeft();
        ResolvedJavaType type = argsWithTypes.get(i).getRight();
        if (!type.isPrimitive() && !type.isJavaLangObject()) {
            TypeReference typeRef = TypeReference.createTrusted(kit.getAssumptions(), type);
            LogicNode instanceOf = kit.unique(InstanceOfNode.createAllowNull(typeRef, value, null, null));
            typeChecks = LogicNode.and(typeChecks, instanceOf, BranchProbabilityNode.FAST_PATH_PROBABILITY);
            FixedGuardNode guard = kit.append(new FixedGuardNode(instanceOf, DeoptimizationReason.ClassCastException, DeoptimizationAction.None, false));
            value = kit.append(PiNode.create(value, StampFactory.object(typeRef), guard));
        }
        args[i] = value;
    }
    // safe because logic nodes are floating
    ifNode.setCondition(typeChecks);
    InvokeKind kind = // 
    invokeMethod.isStatic() ? // 
    InvokeKind.Static : ((nonVirtual || invokeMethod.isConstructor()) ? InvokeKind.Special : InvokeKind.Virtual);
    ValueNode invokeResult = createInvoke(kit, invokeMethod, kind, state, kit.bci(), args);
    if (invokeMethod.isConstructor()) {
        // return `this` to implement NewObject
        invokeResult = args[0];
    }
    // illegal parameter types
    kit.elsePart();
    ConstantNode exceptionObject = kit.createObject(cachedArgumentClassCastException);
    kit.retainPendingException(exceptionObject);
    ValueNode typeMismatchValue = null;
    if (returnKind != JavaKind.Void) {
        typeMismatchValue = kit.unique(ConstantNode.defaultForKind(returnKind.getStackKind()));
    }
    AbstractMergeNode merge = kit.endIf();
    ValueNode returnValue = null;
    if (returnKind != JavaKind.Void) {
        ValueNode[] inputs = { invokeResult, typeMismatchValue };
        returnValue = kit.getGraph().addWithoutUnique(new ValuePhiNode(invokeResult.stamp(NodeView.DEFAULT), merge, inputs));
        state.push(returnKind, returnValue);
    }
    merge.setStateAfter(state.create(kit.bci(), merge));
    if (returnKind != JavaKind.Void) {
        state.pop(returnKind);
        if (returnKind.isObject()) {
            returnValue = kit.boxObjectInLocalHandle(returnValue);
        }
    }
    kit.append(new CEntryPointLeaveNode(LeaveAction.Leave));
    kit.createReturn(returnValue, returnKind);
    assert graph.verify();
    return graph;
}
Also used : UniverseMetaAccess(com.oracle.graal.pointsto.infrastructure.UniverseMetaAccess) ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) IfNode(org.graalvm.compiler.nodes.IfNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) InvokeKind(org.graalvm.compiler.nodes.CallTargetNode.InvokeKind) CEntryPointLeaveNode(com.oracle.svm.core.graal.nodes.CEntryPointLeaveNode) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) LogicConstantNode(org.graalvm.compiler.nodes.LogicConstantNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) JNIEnvironment(com.oracle.svm.jni.nativeapi.JNIEnvironment) CEntryPointEnterNode(com.oracle.svm.core.graal.nodes.CEntryPointEnterNode) Signature(jdk.vm.ci.meta.Signature) ValueNode(org.graalvm.compiler.nodes.ValueNode) FrameStateBuilder(org.graalvm.compiler.java.FrameStateBuilder) LogicNode(org.graalvm.compiler.nodes.LogicNode) TypeReference(org.graalvm.compiler.core.common.type.TypeReference) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod) JavaKind(jdk.vm.ci.meta.JavaKind) Pair(org.graalvm.collections.Pair)

Example 78 with ResolvedJavaType

use of jdk.vm.ci.meta.ResolvedJavaType 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 79 with ResolvedJavaType

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

the class JNIPrimitiveArrayOperationMethod method createSignature.

private JNISignature createSignature(MetaAccessProvider metaAccess) {
    ResolvedJavaType objectHandleType = metaAccess.lookupJavaType(JNIObjectHandle.class);
    ResolvedJavaType intType = metaAccess.lookupJavaType(int.class);
    ResolvedJavaType returnType;
    List<JavaType> args = new ArrayList<>();
    args.add(metaAccess.lookupJavaType(JNIEnvironment.class));
    if (operation == Operation.NEW) {
        // jsize length;
        args.add(intType);
        returnType = objectHandleType;
    } else {
        // j<PrimitiveType>Array array;
        args.add(objectHandleType);
        if (operation == Operation.GET_ELEMENTS) {
            // jboolean *isCopy;
            args.add(metaAccess.lookupJavaType(CIntPointer.class));
            returnType = metaAccess.lookupJavaType(WordPointer.class);
        } else if (operation == Operation.RELEASE_ELEMENTS) {
            // NativeType *elems;
            args.add(metaAccess.lookupJavaType(WordPointer.class));
            // jint mode;
            args.add(intType);
            returnType = metaAccess.lookupJavaType(Void.TYPE);
        } else if (operation == Operation.GET_REGION || operation == Operation.SET_REGION) {
            // jsize start;
            args.add(intType);
            // jsize len;
            args.add(intType);
            // NativeType *buf;
            args.add(metaAccess.lookupJavaType(WordPointer.class));
            returnType = metaAccess.lookupJavaType(Void.TYPE);
        } else {
            throw VMError.shouldNotReachHere();
        }
    }
    return new JNISignature(args, returnType);
}
Also used : ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) JavaType(jdk.vm.ci.meta.JavaType) CIntPointer(org.graalvm.nativeimage.c.type.CIntPointer) WordPointer(org.graalvm.nativeimage.c.type.WordPointer) JNIEnvironment(com.oracle.svm.jni.nativeapi.JNIEnvironment) ArrayList(java.util.ArrayList) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType)

Example 80 with ResolvedJavaType

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

the class JNIPrimitiveArrayOperationMethod method newArray.

private ValueNode newArray(HostedProviders providers, JNIGraphKit kit, List<ValueNode> arguments) {
    ResolvedJavaType elementType = providers.getMetaAccess().lookupJavaType(elementKind.toJavaClass());
    ValueNode length = arguments.get(1);
    ConstantNode zero = kit.createInt(0);
    kit.startIf(new IntegerLessThanNode(length, zero), BranchProbabilityNode.VERY_SLOW_PATH_PROBABILITY);
    kit.thenPart();
    ValueNode nullHandle = kit.createConstant(JavaConstant.INT_0, providers.getWordTypes().getWordKind());
    kit.elsePart();
    ValueNode array = kit.append(new NewArrayNode(elementType, length, true));
    ValueNode arrayHandle = kit.boxObjectInLocalHandle(array);
    AbstractMergeNode merge = kit.endIf();
    Stamp handleStamp = providers.getWordTypes().getWordStamp(providers.getMetaAccess().lookupJavaType(JNIObjectHandle.class));
    return kit.unique(new ValuePhiNode(handleStamp, merge, new ValueNode[] { nullHandle, arrayHandle }));
}
Also used : ConstantNode(org.graalvm.compiler.nodes.ConstantNode) NewArrayNode(org.graalvm.compiler.nodes.java.NewArrayNode) Stamp(org.graalvm.compiler.core.common.type.Stamp) ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) IntegerLessThanNode(org.graalvm.compiler.nodes.calc.IntegerLessThanNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) JNIObjectHandle(com.oracle.svm.jni.nativeapi.JNIObjectHandle)

Aggregations

ResolvedJavaType (jdk.vm.ci.meta.ResolvedJavaType)161 ResolvedJavaMethod (jdk.vm.ci.meta.ResolvedJavaMethod)63 ValueNode (org.graalvm.compiler.nodes.ValueNode)60 JavaKind (jdk.vm.ci.meta.JavaKind)25 JavaType (jdk.vm.ci.meta.JavaType)25 MethodCallTargetNode (org.graalvm.compiler.nodes.java.MethodCallTargetNode)19 Stamp (org.graalvm.compiler.core.common.type.Stamp)17 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)17 MetaAccessProvider (jdk.vm.ci.meta.MetaAccessProvider)16 ObjectStamp (org.graalvm.compiler.core.common.type.ObjectStamp)13 TypeReference (org.graalvm.compiler.core.common.type.TypeReference)13 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)13 Signature (jdk.vm.ci.meta.Signature)11 FixedGuardNode (org.graalvm.compiler.nodes.FixedGuardNode)11 LogicNode (org.graalvm.compiler.nodes.LogicNode)11 GraphBuilderContext (org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext)11 Registration (org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration)11 ArrayList (java.util.ArrayList)10 InvocationPlugin (org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin)10 ResolvedJavaField (jdk.vm.ci.meta.ResolvedJavaField)9