Search in sources :

Example 6 with VirtualObjectNode

use of org.graalvm.compiler.nodes.virtual.VirtualObjectNode in project graal by oracle.

the class BasicArrayCopyNode method virtualize.

@Override
public void virtualize(VirtualizerTool tool) {
    ValueNode sourcePosition = tool.getAlias(getSourcePosition());
    ValueNode destinationPosition = tool.getAlias(getDestinationPosition());
    ValueNode replacedLength = tool.getAlias(getLength());
    if (sourcePosition.isConstant() && destinationPosition.isConstant() && replacedLength.isConstant()) {
        int srcPosInt = sourcePosition.asJavaConstant().asInt();
        int destPosInt = destinationPosition.asJavaConstant().asInt();
        int len = replacedLength.asJavaConstant().asInt();
        ValueNode destAlias = tool.getAlias(getDestination());
        if (destAlias instanceof VirtualArrayNode) {
            VirtualArrayNode destVirtual = (VirtualArrayNode) destAlias;
            if (len < 0 || !checkBounds(destPosInt, len, destVirtual)) {
                return;
            }
            ValueNode srcAlias = tool.getAlias(getSource());
            if (srcAlias instanceof VirtualObjectNode) {
                if (!(srcAlias instanceof VirtualArrayNode)) {
                    return;
                }
                VirtualArrayNode srcVirtual = (VirtualArrayNode) srcAlias;
                if (destVirtual.componentType().getJavaKind() != srcVirtual.componentType().getJavaKind()) {
                    return;
                }
                if (!checkBounds(srcPosInt, len, srcVirtual)) {
                    return;
                }
                if (!checkEntryTypes(srcPosInt, len, srcVirtual, destVirtual.type().getComponentType(), tool)) {
                    return;
                }
                for (int i = 0; i < len; i++) {
                    tool.setVirtualEntry(destVirtual, destPosInt + i, tool.getEntry(srcVirtual, srcPosInt + i));
                }
                tool.delete();
                DebugContext debug = getDebug();
                if (debug.isLogEnabled()) {
                    debug.log("virtualized arraycopy(%s, %d, %s, %d, %d)", getSource(), srcPosInt, getDestination(), destPosInt, len);
                }
            } else {
                ResolvedJavaType sourceType = StampTool.typeOrNull(srcAlias);
                if (sourceType == null || !sourceType.isArray()) {
                    return;
                }
                ResolvedJavaType sourceComponentType = sourceType.getComponentType();
                ResolvedJavaType destComponentType = destVirtual.type().getComponentType();
                if (!sourceComponentType.equals(destComponentType)) {
                    return;
                }
                for (int i = 0; i < len; i++) {
                    LoadIndexedNode load = new LoadIndexedNode(graph().getAssumptions(), srcAlias, ConstantNode.forInt(i + srcPosInt, graph()), destComponentType.getJavaKind());
                    tool.addNode(load);
                    tool.setVirtualEntry(destVirtual, destPosInt + i, load);
                }
                tool.delete();
            }
        }
    }
}
Also used : VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) VirtualArrayNode(org.graalvm.compiler.nodes.virtual.VirtualArrayNode) LoadIndexedNode(org.graalvm.compiler.nodes.java.LoadIndexedNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) DebugContext(org.graalvm.compiler.debug.DebugContext) AbstractMemoryCheckpoint(org.graalvm.compiler.nodes.memory.AbstractMemoryCheckpoint) MemoryCheckpoint(org.graalvm.compiler.nodes.memory.MemoryCheckpoint) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType)

Example 7 with VirtualObjectNode

use of org.graalvm.compiler.nodes.virtual.VirtualObjectNode in project graal by oracle.

the class BasicObjectCloneNode method virtualize.

@Override
public void virtualize(VirtualizerTool tool) {
    ValueNode originalAlias = tool.getAlias(getObject());
    if (originalAlias instanceof VirtualObjectNode) {
        VirtualObjectNode originalVirtual = (VirtualObjectNode) originalAlias;
        if (originalVirtual.type().isCloneableWithAllocation()) {
            ValueNode[] newEntryState = new ValueNode[originalVirtual.entryCount()];
            for (int i = 0; i < newEntryState.length; i++) {
                newEntryState[i] = tool.getEntry(originalVirtual, i);
            }
            VirtualObjectNode newVirtual = originalVirtual.duplicate();
            tool.createVirtualObject(newVirtual, newEntryState, Collections.<MonitorIdNode>emptyList(), false);
            tool.replaceWithVirtual(newVirtual);
        }
    } else {
        ResolvedJavaType type = getConcreteType(originalAlias.stamp(NodeView.DEFAULT));
        if (type != null && !type.isArray()) {
            VirtualInstanceNode newVirtual = createVirtualInstanceNode(type, true);
            ResolvedJavaField[] fields = newVirtual.getFields();
            ValueNode[] state = new ValueNode[fields.length];
            final LoadFieldNode[] loads = new LoadFieldNode[fields.length];
            for (int i = 0; i < fields.length; i++) {
                state[i] = loads[i] = genLoadFieldNode(graph().getAssumptions(), originalAlias, fields[i]);
                tool.addNode(loads[i]);
            }
            tool.createVirtualObject(newVirtual, state, Collections.<MonitorIdNode>emptyList(), false);
            tool.replaceWithVirtual(newVirtual);
        }
    }
}
Also used : VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) VirtualInstanceNode(org.graalvm.compiler.nodes.virtual.VirtualInstanceNode) LoadFieldNode(org.graalvm.compiler.nodes.java.LoadFieldNode) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) ResolvedJavaField(jdk.vm.ci.meta.ResolvedJavaField)

Example 8 with VirtualObjectNode

use of org.graalvm.compiler.nodes.virtual.VirtualObjectNode in project graal by oracle.

the class DebugInfoBuilder method build.

public LIRFrameState build(FrameState topState, LabelRef exceptionEdge) {
    assert virtualObjects.size() == 0;
    assert objectStates.size() == 0;
    assert pendingVirtualObjects.size() == 0;
    // collect all VirtualObjectField instances:
    FrameState current = topState;
    do {
        if (current.virtualObjectMappingCount() > 0) {
            for (EscapeObjectState state : current.virtualObjectMappings()) {
                if (!objectStates.containsKey(state.object())) {
                    if (!(state instanceof MaterializedObjectState) || ((MaterializedObjectState) state).materializedValue() != state.object()) {
                        objectStates.put(state.object(), state);
                    }
                }
            }
        }
        current = current.outerFrameState();
    } while (current != null);
    BytecodeFrame frame = computeFrameForState(topState);
    VirtualObject[] virtualObjectsArray = null;
    if (virtualObjects.size() != 0) {
        // fill in the VirtualObject values
        VirtualObjectNode vobjNode;
        while ((vobjNode = pendingVirtualObjects.poll()) != null) {
            VirtualObject vobjValue = virtualObjects.get(vobjNode);
            assert vobjValue.getValues() == null;
            JavaValue[] values;
            JavaKind[] slotKinds;
            int entryCount = vobjNode.entryCount();
            if (entryCount == 0) {
                values = NO_JAVA_VALUES;
                slotKinds = NO_JAVA_KINDS;
            } else {
                values = new JavaValue[entryCount];
                slotKinds = new JavaKind[entryCount];
            }
            if (values.length > 0) {
                VirtualObjectState currentField = (VirtualObjectState) objectStates.get(vobjNode);
                assert currentField != null;
                int pos = 0;
                for (int i = 0; i < entryCount; i++) {
                    ValueNode value = currentField.values().get(i);
                    if (value == null) {
                        JavaKind entryKind = vobjNode.entryKind(i);
                        values[pos] = JavaConstant.defaultForKind(entryKind.getStackKind());
                        slotKinds[pos] = entryKind.getStackKind();
                        pos++;
                    } else if (!value.isConstant() || value.asJavaConstant().getJavaKind() != JavaKind.Illegal) {
                        values[pos] = toJavaValue(value);
                        slotKinds[pos] = toSlotKind(value);
                        pos++;
                    } else {
                        assert value.getStackKind() == JavaKind.Illegal;
                        ValueNode previousValue = currentField.values().get(i - 1);
                        assert (previousValue != null && previousValue.getStackKind().needsTwoSlots()) : vobjNode + " " + i + " " + previousValue + " " + currentField.values().snapshot();
                        if (previousValue == null || !previousValue.getStackKind().needsTwoSlots()) {
                            // Don't allow the IllegalConstant to leak into the debug info
                            JavaKind entryKind = vobjNode.entryKind(i);
                            values[pos] = JavaConstant.defaultForKind(entryKind.getStackKind());
                            slotKinds[pos] = entryKind.getStackKind();
                            pos++;
                        }
                    }
                }
                if (pos != entryCount) {
                    values = Arrays.copyOf(values, pos);
                    slotKinds = Arrays.copyOf(slotKinds, pos);
                }
            }
            assert checkValues(vobjValue.getType(), values, slotKinds);
            vobjValue.setValues(values, slotKinds);
        }
        virtualObjectsArray = new VirtualObject[virtualObjects.size()];
        int index = 0;
        for (VirtualObject value : virtualObjects.getValues()) {
            virtualObjectsArray[index++] = value;
        }
        virtualObjects.clear();
    }
    objectStates.clear();
    return newLIRFrameState(exceptionEdge, frame, virtualObjectsArray);
}
Also used : VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) VirtualObjectState(org.graalvm.compiler.virtual.nodes.VirtualObjectState) JavaValue(jdk.vm.ci.meta.JavaValue) LIRFrameState(org.graalvm.compiler.lir.LIRFrameState) FrameState(org.graalvm.compiler.nodes.FrameState) EscapeObjectState(org.graalvm.compiler.nodes.virtual.EscapeObjectState) BytecodeFrame(jdk.vm.ci.code.BytecodeFrame) VirtualObject(jdk.vm.ci.code.VirtualObject) ValueNode(org.graalvm.compiler.nodes.ValueNode) MaterializedObjectState(org.graalvm.compiler.virtual.nodes.MaterializedObjectState) JavaKind(jdk.vm.ci.meta.JavaKind)

Example 9 with VirtualObjectNode

use of org.graalvm.compiler.nodes.virtual.VirtualObjectNode in project graal by oracle.

the class CanonicalStringGraphPrinter method writeCanonicalGraphString.

protected static void writeCanonicalGraphString(StructuredGraph graph, boolean excludeVirtual, boolean checkConstants, PrintWriter writer) {
    StructuredGraph.ScheduleResult scheduleResult = GraphPrinter.getScheduleOrNull(graph);
    if (scheduleResult == null) {
        return;
    }
    try {
        NodeMap<Integer> canonicalId = graph.createNodeMap();
        int nextId = 0;
        List<String> constantsLines = null;
        if (checkConstants) {
            constantsLines = new ArrayList<>();
        }
        for (Block block : scheduleResult.getCFG().getBlocks()) {
            writer.print("Block ");
            writer.print(block);
            writer.print(" ");
            if (block == scheduleResult.getCFG().getStartBlock()) {
                writer.print("* ");
            }
            writer.print("-> ");
            for (Block successor : block.getSuccessors()) {
                writer.print(successor);
                writer.print(" ");
            }
            writer.println();
            for (Node node : scheduleResult.getBlockToNodesMap().get(block)) {
                if (node instanceof ValueNode && node.isAlive()) {
                    if (!excludeVirtual || !(node instanceof VirtualObjectNode || node instanceof ProxyNode || node instanceof FullInfopointNode)) {
                        if (node instanceof ConstantNode) {
                            if (constantsLines != null) {
                                String name = node.toString(Verbosity.Name);
                                String str = name + (excludeVirtual ? "" : "    (" + filteredUsageCount(node) + ")");
                                constantsLines.add(str);
                            }
                        } else {
                            int id;
                            if (canonicalId.get(node) != null) {
                                id = canonicalId.get(node);
                            } else {
                                id = nextId++;
                                canonicalId.set(node, id);
                            }
                            String name = node.getClass().getSimpleName();
                            writer.print("  ");
                            writer.print(id);
                            writer.print("|");
                            writer.print(name);
                            if (!excludeVirtual) {
                                writer.print("    (");
                                writer.print(filteredUsageCount(node));
                                writer.print(")");
                            }
                            writer.println();
                        }
                    }
                }
            }
        }
        if (constantsLines != null) {
            writer.print(constantsLines.size());
            writer.println(" constants:");
            Collections.sort(constantsLines);
            for (String s : constantsLines) {
                writer.println(s);
            }
        }
    } catch (Throwable t) {
        writer.println();
        t.printStackTrace(writer);
    }
}
Also used : VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) ProxyNode(org.graalvm.compiler.nodes.ProxyNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) Node(org.graalvm.compiler.graph.Node) FullInfopointNode(org.graalvm.compiler.nodes.FullInfopointNode) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) ProxyNode(org.graalvm.compiler.nodes.ProxyNode) FullInfopointNode(org.graalvm.compiler.nodes.FullInfopointNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) ValueNode(org.graalvm.compiler.nodes.ValueNode) Block(org.graalvm.compiler.nodes.cfg.Block)

Example 10 with VirtualObjectNode

use of org.graalvm.compiler.nodes.virtual.VirtualObjectNode in project graal by oracle.

the class GraphOrder method assertSchedulableGraph.

/**
 * This method schedules the graph and makes sure that, for every node, all inputs are available
 * at the position where it is scheduled. This is a very expensive assertion.
 */
public static boolean assertSchedulableGraph(final StructuredGraph graph) {
    assert graph.getGuardsStage() != GuardsStage.AFTER_FSA : "Cannot use the BlockIteratorClosure after FrameState Assignment, HIR Loop Data Structures are no longer valid.";
    try {
        final SchedulePhase schedulePhase = new SchedulePhase(SchedulingStrategy.LATEST_OUT_OF_LOOPS, true);
        final EconomicMap<LoopBeginNode, NodeBitMap> loopEntryStates = EconomicMap.create(Equivalence.IDENTITY);
        schedulePhase.apply(graph, false);
        final ScheduleResult schedule = graph.getLastSchedule();
        BlockIteratorClosure<NodeBitMap> closure = new BlockIteratorClosure<NodeBitMap>() {

            @Override
            protected List<NodeBitMap> processLoop(Loop<Block> loop, NodeBitMap initialState) {
                return ReentrantBlockIterator.processLoop(this, loop, initialState).exitStates;
            }

            @Override
            protected NodeBitMap processBlock(final Block block, final NodeBitMap currentState) {
                final List<Node> list = graph.getLastSchedule().getBlockToNodesMap().get(block);
                /*
                     * A stateAfter is not valid directly after its associated state split, but
                     * right before the next fixed node. Therefore a pending stateAfter is kept that
                     * will be checked at the correct position.
                     */
                FrameState pendingStateAfter = null;
                for (final Node node : list) {
                    if (node instanceof ValueNode) {
                        FrameState stateAfter = node instanceof StateSplit ? ((StateSplit) node).stateAfter() : null;
                        if (node instanceof FullInfopointNode) {
                            stateAfter = ((FullInfopointNode) node).getState();
                        }
                        if (pendingStateAfter != null && node instanceof FixedNode) {
                            pendingStateAfter.applyToNonVirtual(new NodeClosure<Node>() {

                                @Override
                                public void apply(Node usage, Node nonVirtualNode) {
                                    assert currentState.isMarked(nonVirtualNode) || nonVirtualNode instanceof VirtualObjectNode || nonVirtualNode instanceof ConstantNode : nonVirtualNode + " not available at virtualstate " + usage + " before " + node + " in block " + block + " \n" + list;
                                }
                            });
                            pendingStateAfter = null;
                        }
                        if (node instanceof AbstractMergeNode) {
                            // phis aren't scheduled, so they need to be added explicitly
                            currentState.markAll(((AbstractMergeNode) node).phis());
                            if (node instanceof LoopBeginNode) {
                                // remember the state at the loop entry, it's restored at exits
                                loopEntryStates.put((LoopBeginNode) node, currentState.copy());
                            }
                        } else if (node instanceof ProxyNode) {
                            assert false : "proxy nodes should not be in the schedule";
                        } else if (node instanceof LoopExitNode) {
                            if (graph.hasValueProxies()) {
                                for (ProxyNode proxy : ((LoopExitNode) node).proxies()) {
                                    for (Node input : proxy.inputs()) {
                                        if (input != proxy.proxyPoint()) {
                                            assert currentState.isMarked(input) : input + " not available at " + proxy + " in block " + block + "\n" + list;
                                        }
                                    }
                                }
                                // loop contents are only accessible via proxies at the exit
                                currentState.clearAll();
                                currentState.markAll(loopEntryStates.get(((LoopExitNode) node).loopBegin()));
                            }
                            // Loop proxies aren't scheduled, so they need to be added
                            // explicitly
                            currentState.markAll(((LoopExitNode) node).proxies());
                        } else {
                            for (Node input : node.inputs()) {
                                if (input != stateAfter) {
                                    if (input instanceof FrameState) {
                                        ((FrameState) input).applyToNonVirtual(new VirtualState.NodeClosure<Node>() {

                                            @Override
                                            public void apply(Node usage, Node nonVirtual) {
                                                assert currentState.isMarked(nonVirtual) : nonVirtual + " not available at " + node + " in block " + block + "\n" + list;
                                            }
                                        });
                                    } else {
                                        assert currentState.isMarked(input) || input instanceof VirtualObjectNode || input instanceof ConstantNode : input + " not available at " + node + " in block " + block + "\n" + list;
                                    }
                                }
                            }
                        }
                        if (node instanceof AbstractEndNode) {
                            AbstractMergeNode merge = ((AbstractEndNode) node).merge();
                            for (PhiNode phi : merge.phis()) {
                                ValueNode phiValue = phi.valueAt((AbstractEndNode) node);
                                assert phiValue == null || currentState.isMarked(phiValue) || phiValue instanceof ConstantNode : phiValue + " not available at phi " + phi + " / end " + node + " in block " + block;
                            }
                        }
                        if (stateAfter != null) {
                            assert pendingStateAfter == null;
                            pendingStateAfter = stateAfter;
                        }
                        currentState.mark(node);
                    }
                }
                if (pendingStateAfter != null) {
                    pendingStateAfter.applyToNonVirtual(new NodeClosure<Node>() {

                        @Override
                        public void apply(Node usage, Node nonVirtualNode) {
                            assert currentState.isMarked(nonVirtualNode) || nonVirtualNode instanceof VirtualObjectNode || nonVirtualNode instanceof ConstantNode : nonVirtualNode + " not available at virtualstate " + usage + " at end of block " + block + " \n" + list;
                        }
                    });
                }
                return currentState;
            }

            @Override
            protected NodeBitMap merge(Block merge, List<NodeBitMap> states) {
                NodeBitMap result = states.get(0);
                for (int i = 1; i < states.size(); i++) {
                    result.intersect(states.get(i));
                }
                return result;
            }

            @Override
            protected NodeBitMap getInitialState() {
                NodeBitMap ret = graph.createNodeBitMap();
                ret.markAll(graph.getNodes().filter(ConstantNode.class));
                return ret;
            }

            @Override
            protected NodeBitMap cloneState(NodeBitMap oldState) {
                return oldState.copy();
            }
        };
        ReentrantBlockIterator.apply(closure, schedule.getCFG().getStartBlock());
    } catch (Throwable t) {
        graph.getDebug().handle(t);
    }
    return true;
}
Also used : VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) SchedulePhase(org.graalvm.compiler.phases.schedule.SchedulePhase) ScheduleResult(org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) Node(org.graalvm.compiler.graph.Node) EndNode(org.graalvm.compiler.nodes.EndNode) FullInfopointNode(org.graalvm.compiler.nodes.FullInfopointNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) ProxyNode(org.graalvm.compiler.nodes.ProxyNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) FrameState(org.graalvm.compiler.nodes.FrameState) VirtualState(org.graalvm.compiler.nodes.VirtualState) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) ArrayList(java.util.ArrayList) List(java.util.List) Loop(org.graalvm.compiler.core.common.cfg.Loop) ProxyNode(org.graalvm.compiler.nodes.ProxyNode) BlockIteratorClosure(org.graalvm.compiler.phases.graph.ReentrantBlockIterator.BlockIteratorClosure) LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) NodeBitMap(org.graalvm.compiler.graph.NodeBitMap) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) FullInfopointNode(org.graalvm.compiler.nodes.FullInfopointNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) Block(org.graalvm.compiler.nodes.cfg.Block) StateSplit(org.graalvm.compiler.nodes.StateSplit)

Aggregations

VirtualObjectNode (org.graalvm.compiler.nodes.virtual.VirtualObjectNode)42 ValueNode (org.graalvm.compiler.nodes.ValueNode)38 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)8 ResolvedJavaType (jdk.vm.ci.meta.ResolvedJavaType)7 Node (org.graalvm.compiler.graph.Node)7 ProxyNode (org.graalvm.compiler.nodes.ProxyNode)7 VirtualObjectState (org.graalvm.compiler.virtual.nodes.VirtualObjectState)6 FixedNode (org.graalvm.compiler.nodes.FixedNode)5 PhiNode (org.graalvm.compiler.nodes.PhiNode)5 Block (org.graalvm.compiler.nodes.cfg.Block)5 ArrayList (java.util.ArrayList)4 FixedWithNextNode (org.graalvm.compiler.nodes.FixedWithNextNode)4 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)4 ValueProxyNode (org.graalvm.compiler.nodes.ValueProxyNode)4 VirtualArrayNode (org.graalvm.compiler.nodes.virtual.VirtualArrayNode)4 VirtualInstanceNode (org.graalvm.compiler.nodes.virtual.VirtualInstanceNode)4 JavaKind (jdk.vm.ci.meta.JavaKind)3 FrameState (org.graalvm.compiler.nodes.FrameState)3 LoopBeginNode (org.graalvm.compiler.nodes.LoopBeginNode)3 BitSet (java.util.BitSet)2