Search in sources :

Example 1 with Pair

use of org.graalvm.collections.Pair in project graal by oracle.

the class GraphComparison method verifyGraphsEqual.

public static boolean verifyGraphsEqual(StructuredGraph expectedGraph, StructuredGraph actualGraph) {
    NodeMap<Node> nodeMapping = new NodeMap<>(expectedGraph);
    Deque<Pair<Node, Node>> workList = new ArrayDeque<>();
    pushToWorklist(expectedGraph.start(), actualGraph.start(), nodeMapping, workList);
    while (!workList.isEmpty()) {
        Pair<Node, Node> pair = workList.removeFirst();
        Node expectedNode = pair.getLeft();
        Node actualNode = pair.getRight();
        assert expectedNode.getClass() == actualNode.getClass();
        NodeClass<?> nodeClass = expectedNode.getNodeClass();
        assert nodeClass == actualNode.getNodeClass();
        if (expectedNode instanceof MergeNode) {
            /* The order of the ends can be different, so ignore them. */
            verifyNodesEqual(expectedNode.inputs(), actualNode.inputs(), nodeMapping, workList, true);
        } else if (expectedNode instanceof PhiNode) {
            verifyPhi((PhiNode) expectedNode, (PhiNode) actualNode, nodeMapping, workList);
        } else {
            verifyNodesEqual(expectedNode.inputs(), actualNode.inputs(), nodeMapping, workList, false);
        }
        verifyNodesEqual(expectedNode.successors(), actualNode.successors(), nodeMapping, workList, false);
        if (expectedNode instanceof LoopEndNode) {
            LoopEndNode actualLoopEnd = (LoopEndNode) actualNode;
            assert actualLoopEnd.loopBegin().loopEnds().snapshot().indexOf(actualLoopEnd) == actualLoopEnd.endIndex();
        } else {
            for (int i = 0; i < nodeClass.getData().getCount(); i++) {
                Object expectedProperty = nodeClass.getData().get(expectedNode, i);
                Object actualProperty = nodeClass.getData().get(actualNode, i);
                assert Objects.equals(expectedProperty, actualProperty);
            }
        }
        if (expectedNode instanceof EndNode) {
            /* Visit the merge node, which is the one and only usage of the EndNode. */
            assert expectedNode.usages().count() == 1;
            assert actualNode.usages().count() == 1;
            verifyNodesEqual(expectedNode.usages(), actualNode.usages(), nodeMapping, workList, false);
        }
        if (expectedNode instanceof AbstractEndNode) {
            /* Visit the input values of the merge phi functions for this EndNode. */
            verifyPhis((AbstractEndNode) expectedNode, (AbstractEndNode) actualNode, nodeMapping, workList);
        }
    }
    return true;
}
Also used : ExceptionObjectNode(org.graalvm.compiler.nodes.java.ExceptionObjectNode) Node(org.graalvm.compiler.graph.Node) ArrayDeque(java.util.ArrayDeque) NodeMap(org.graalvm.compiler.graph.NodeMap) Pair(org.graalvm.collections.Pair)

Example 2 with Pair

use of org.graalvm.collections.Pair in project graal by oracle.

the class PEReadEliminationClosure method processInitialLoopState.

@SuppressWarnings("unchecked")
@Override
protected void processInitialLoopState(Loop<Block> loop, PEReadEliminationBlockState initialState) {
    super.processInitialLoopState(loop, initialState);
    if (!initialState.getReadCache().isEmpty()) {
        EconomicMap<ValueNode, Pair<ValueNode, Object>> firstValueSet = null;
        for (PhiNode phi : ((LoopBeginNode) loop.getHeader().getBeginNode()).phis()) {
            ValueNode firstValue = phi.valueAt(0);
            if (firstValue != null && phi.getStackKind().isObject()) {
                ValueNode unproxified = GraphUtil.unproxify(firstValue);
                if (firstValueSet == null) {
                    firstValueSet = EconomicMap.create(Equivalence.IDENTITY_WITH_SYSTEM_HASHCODE);
                }
                Pair<ValueNode, Object> pair = Pair.create(unproxified, firstValueSet.get(unproxified));
                firstValueSet.put(unproxified, pair);
            }
        }
        if (firstValueSet != null) {
            ReadCacheEntry[] entries = new ReadCacheEntry[initialState.getReadCache().size()];
            int z = 0;
            for (ReadCacheEntry entry : initialState.getReadCache().getKeys()) {
                entries[z++] = entry;
            }
            for (ReadCacheEntry entry : entries) {
                ValueNode object = entry.object;
                if (object != null) {
                    Pair<ValueNode, Object> pair = firstValueSet.get(object);
                    while (pair != null) {
                        initialState.addReadCache(pair.getLeft(), entry.identity, entry.index, entry.kind, entry.overflowAccess, initialState.getReadCache().get(entry), this);
                        pair = (Pair<ValueNode, Object>) pair.getRight();
                    }
                }
            }
        }
    }
}
Also used : LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) ReadCacheEntry(org.graalvm.compiler.virtual.phases.ea.PEReadEliminationBlockState.ReadCacheEntry) MemoryCheckpoint(org.graalvm.compiler.nodes.memory.MemoryCheckpoint) Pair(org.graalvm.collections.Pair)

Example 3 with Pair

use of org.graalvm.collections.Pair in project graal by oracle.

the class JNIJavaCallWrapperMethod method loadAndUnboxArguments.

private List<Pair<ValueNode, ResolvedJavaType>> loadAndUnboxArguments(JNIGraphKit kit, HostedProviders providers, ResolvedJavaMethod invokeMethod, Signature invokeSignature) {
    MetaAccessProvider metaAccess = providers.getMetaAccess();
    List<Pair<ValueNode, ResolvedJavaType>> args = new ArrayList<>();
    int javaIndex = 0;
    javaIndex += metaAccess.lookupJavaType(JNIEnvironment.class).getJavaKind().getSlotCount();
    if (!invokeMethod.isStatic()) {
        JavaKind kind = metaAccess.lookupJavaType(JNIObjectHandle.class).getJavaKind();
        ValueNode handle = kit.loadLocal(javaIndex, kind);
        ValueNode unboxed = kit.unboxHandle(handle);
        ValueNode receiver;
        ResolvedJavaType receiverClass = invokeMethod.getDeclaringClass();
        if (invokeMethod.isConstructor()) {
            /*
                 * Our target method is a constructor and we might be called via `NewObject`, in
                 * which case we need to allocate the object before calling the constructor. We can
                 * detect when this is the case because unlike with `Call<Type>Method`, we are
                 * passed the object hub of our target class in place of the receiver object.
                 */
            Constant hub = providers.getConstantReflection().asObjectHub(receiverClass);
            ConstantNode hubNode = kit.createConstant(hub, JavaKind.Object);
            kit.startIf(kit.unique(new ObjectEqualsNode(unboxed, hubNode)), BranchProbabilityNode.FAST_PATH_PROBABILITY);
            kit.thenPart();
            ValueNode created = kit.append(new NewInstanceNode(receiverClass, true));
            AbstractMergeNode merge = kit.endIf();
            receiver = kit.unique(new ValuePhiNode(StampFactory.object(), merge, new ValueNode[] { created, unboxed }));
        } else {
            receiver = unboxed;
        }
        args.add(Pair.create(receiver, receiverClass));
    }
    javaIndex += metaAccess.lookupJavaType(JNIObjectHandle.class).getJavaKind().getSlotCount();
    if (nonVirtual) {
        javaIndex += metaAccess.lookupJavaType(JNIObjectHandle.class).getJavaKind().getSlotCount();
    }
    javaIndex += metaAccess.lookupJavaType(JNIMethodId.class).getJavaKind().getSlotCount();
    int count = invokeSignature.getParameterCount(false);
    if (callVariant == CallVariant.VARARGS) {
        for (int i = 0; i < count; i++) {
            ResolvedJavaType type = (ResolvedJavaType) invokeSignature.getParameterType(i, null);
            JavaKind kind = type.getJavaKind();
            JavaKind loadKind = kind;
            if (loadKind == JavaKind.Float) {
                // C varargs promote float to double
                loadKind = JavaKind.Double;
            }
            ValueNode value = kit.loadLocal(javaIndex, loadKind);
            if (kind == JavaKind.Float) {
                value = kit.unique(new FloatConvertNode(FloatConvert.D2F, value));
            } else if (kind.isObject()) {
                value = kit.unboxHandle(value);
            }
            args.add(Pair.create(value, type));
            javaIndex += loadKind.getSlotCount();
        }
    } else if (callVariant == CallVariant.ARRAY) {
        ResolvedJavaType elementType = metaAccess.lookupJavaType(JNIValue.class);
        int elementSize = SizeOf.get(JNIValue.class);
        ValueNode array = kit.loadLocal(javaIndex, elementType.getJavaKind());
        for (int i = 0; i < count; i++) {
            ResolvedJavaType type = (ResolvedJavaType) invokeSignature.getParameterType(i, null);
            JavaKind readKind = type.getJavaKind();
            StructFieldInfo fieldInfo = getJNIValueOffsetOf(elementType, readKind);
            int offset = i * elementSize + fieldInfo.getOffsetInfo().getProperty();
            ConstantNode offsetConstant = kit.createConstant(JavaConstant.forInt(offset), providers.getWordTypes().getWordKind());
            OffsetAddressNode address = kit.unique(new OffsetAddressNode(array, offsetConstant));
            LocationIdentity locationIdentity = fieldInfo.getLocationIdentity();
            if (locationIdentity == null) {
                locationIdentity = LocationIdentity.any();
            }
            Stamp readStamp = getNarrowStamp(providers, readKind);
            ValueNode value = kit.append(new CInterfaceReadNode(address, locationIdentity, readStamp, BarrierType.NONE, "args[" + i + "]"));
            JavaKind stackKind = readKind.getStackKind();
            if (readKind != stackKind) {
                assert stackKind.getBitCount() > readKind.getBitCount() : "read kind must be narrower than stack kind";
                if (readKind.isUnsigned()) {
                    // needed or another op may illegally sign-extend
                    value = kit.unique(new ZeroExtendNode(value, stackKind.getBitCount()));
                } else {
                    value = kit.unique(new SignExtendNode(value, stackKind.getBitCount()));
                }
            } else if (readKind.isObject()) {
                value = kit.unboxHandle(value);
            }
            args.add(Pair.create(value, type));
        }
    } else if (callVariant == CallVariant.VA_LIST) {
        ValueNode valist = kit.loadLocal(javaIndex, metaAccess.lookupJavaType(WordBase.class).getJavaKind());
        for (int i = 0; i < count; i++) {
            ResolvedJavaType type = (ResolvedJavaType) invokeSignature.getParameterType(i, null);
            JavaKind loadKind = type.getJavaKind();
            if (loadKind.isObject()) {
                loadKind = providers.getWordTypes().getWordKind();
            }
            ValueNode value = kit.append(new VaListNextArgNode(loadKind, valist));
            if (type.getJavaKind().isObject()) {
                value = kit.unboxHandle(value);
            }
            args.add(Pair.create(value, type));
        }
    } else {
        throw VMError.unsupportedFeature("Call variant: " + callVariant);
    }
    return args;
}
Also used : NewInstanceNode(org.graalvm.compiler.nodes.java.NewInstanceNode) SignExtendNode(org.graalvm.compiler.nodes.calc.SignExtendNode) Constant(jdk.vm.ci.meta.Constant) JavaConstant(jdk.vm.ci.meta.JavaConstant) ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) CInterfaceReadNode(com.oracle.svm.core.graal.nodes.CInterfaceReadNode) ArrayList(java.util.ArrayList) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) LogicConstantNode(org.graalvm.compiler.nodes.LogicConstantNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) JNIValue(com.oracle.svm.jni.nativeapi.JNIValue) LocationIdentity(org.graalvm.word.LocationIdentity) JNIObjectHandle(com.oracle.svm.jni.nativeapi.JNIObjectHandle) Pair(org.graalvm.collections.Pair) JavaKind(jdk.vm.ci.meta.JavaKind) VaListNextArgNode(com.oracle.svm.core.graal.nodes.VaListNextArgNode) Stamp(org.graalvm.compiler.core.common.type.Stamp) ObjectEqualsNode(org.graalvm.compiler.nodes.calc.ObjectEqualsNode) StructFieldInfo(com.oracle.svm.hosted.c.info.StructFieldInfo) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) ZeroExtendNode(org.graalvm.compiler.nodes.calc.ZeroExtendNode) JNIMethodId(com.oracle.svm.jni.nativeapi.JNIMethodId) FloatConvertNode(org.graalvm.compiler.nodes.calc.FloatConvertNode) OffsetAddressNode(org.graalvm.compiler.nodes.memory.address.OffsetAddressNode) JNIEnvironment(com.oracle.svm.jni.nativeapi.JNIEnvironment) ValueNode(org.graalvm.compiler.nodes.ValueNode) MetaAccessProvider(jdk.vm.ci.meta.MetaAccessProvider)

Example 4 with Pair

use of org.graalvm.collections.Pair 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)

Aggregations

Pair (org.graalvm.collections.Pair)4 ValueNode (org.graalvm.compiler.nodes.ValueNode)3 JNIEnvironment (com.oracle.svm.jni.nativeapi.JNIEnvironment)2 JavaKind (jdk.vm.ci.meta.JavaKind)2 ResolvedJavaType (jdk.vm.ci.meta.ResolvedJavaType)2 AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)2 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)2 LogicConstantNode (org.graalvm.compiler.nodes.LogicConstantNode)2 ValuePhiNode (org.graalvm.compiler.nodes.ValuePhiNode)2 UniverseMetaAccess (com.oracle.graal.pointsto.infrastructure.UniverseMetaAccess)1 CEntryPointEnterNode (com.oracle.svm.core.graal.nodes.CEntryPointEnterNode)1 CEntryPointLeaveNode (com.oracle.svm.core.graal.nodes.CEntryPointLeaveNode)1 CInterfaceReadNode (com.oracle.svm.core.graal.nodes.CInterfaceReadNode)1 VaListNextArgNode (com.oracle.svm.core.graal.nodes.VaListNextArgNode)1 StructFieldInfo (com.oracle.svm.hosted.c.info.StructFieldInfo)1 JNIMethodId (com.oracle.svm.jni.nativeapi.JNIMethodId)1 JNIObjectHandle (com.oracle.svm.jni.nativeapi.JNIObjectHandle)1 JNIValue (com.oracle.svm.jni.nativeapi.JNIValue)1 ArrayDeque (java.util.ArrayDeque)1 ArrayList (java.util.ArrayList)1