Search in sources :

Example 1 with AllocatedObjectNode

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

the class EscapeAnalysisTest method testFullyUnrolledLoop.

@Test
public void testFullyUnrolledLoop() {
    prepareGraph("testFullyUnrolledLoopSnippet", false);
    new LoopFullUnrollPhase(new CanonicalizerPhase(), new DefaultLoopPolicies()).apply(graph, context);
    new PartialEscapePhase(false, new CanonicalizerPhase(), graph.getOptions()).apply(graph, context);
    Assert.assertEquals(1, returnNodes.size());
    Assert.assertTrue(returnNodes.get(0).result() instanceof AllocatedObjectNode);
    CommitAllocationNode commit = ((AllocatedObjectNode) returnNodes.get(0).result()).getCommit();
    Assert.assertEquals(2, commit.getValues().size());
    Assert.assertEquals(1, commit.getVirtualObjects().size());
    Assert.assertTrue("non-cyclic data structure expected", commit.getVirtualObjects().get(0) != commit.getValues().get(0));
}
Also used : LoopFullUnrollPhase(org.graalvm.compiler.loop.phases.LoopFullUnrollPhase) PartialEscapePhase(org.graalvm.compiler.virtual.phases.ea.PartialEscapePhase) AllocatedObjectNode(org.graalvm.compiler.nodes.virtual.AllocatedObjectNode) DefaultLoopPolicies(org.graalvm.compiler.loop.DefaultLoopPolicies) CanonicalizerPhase(org.graalvm.compiler.phases.common.CanonicalizerPhase) CommitAllocationNode(org.graalvm.compiler.nodes.virtual.CommitAllocationNode) Test(org.junit.Test)

Example 2 with AllocatedObjectNode

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

the class DefaultJavaLoweringProvider method finishAllocatedObjects.

public void finishAllocatedObjects(LoweringTool tool, CommitAllocationNode commit, ValueNode[] allocations) {
    StructuredGraph graph = commit.graph();
    for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) {
        FixedValueAnchorNode anchor = graph.add(new FixedValueAnchorNode(allocations[objIndex]));
        allocations[objIndex] = anchor;
        graph.addBeforeFixed(commit, anchor);
    }
    /*
         * Note that the FrameState that is assigned to these MonitorEnterNodes isn't the correct
         * state. It will be the state from before the allocation occurred instead of a valid state
         * after the locking is performed. In practice this should be fine since these are newly
         * allocated objects. The bytecodes themselves permit allocating an object, doing a
         * monitorenter and then dropping all references to the object which would produce the same
         * state, though that would normally produce an IllegalMonitorStateException. In HotSpot
         * some form of fast path locking should always occur so the FrameState should never
         * actually be used.
         */
    ArrayList<MonitorEnterNode> enters = null;
    for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) {
        List<MonitorIdNode> locks = commit.getLocks(objIndex);
        if (locks.size() > 1) {
            // Ensure that the lock operations are performed in lock depth order
            ArrayList<MonitorIdNode> newList = new ArrayList<>(locks);
            newList.sort((a, b) -> Integer.compare(a.getLockDepth(), b.getLockDepth()));
            locks = newList;
        }
        int lastDepth = -1;
        for (MonitorIdNode monitorId : locks) {
            assert lastDepth < monitorId.getLockDepth();
            lastDepth = monitorId.getLockDepth();
            MonitorEnterNode enter = graph.add(new MonitorEnterNode(allocations[objIndex], monitorId));
            graph.addBeforeFixed(commit, enter);
            if (enters == null) {
                enters = new ArrayList<>();
            }
            enters.add(enter);
        }
    }
    for (Node usage : commit.usages().snapshot()) {
        if (usage instanceof AllocatedObjectNode) {
            AllocatedObjectNode addObject = (AllocatedObjectNode) usage;
            int index = commit.getVirtualObjects().indexOf(addObject.getVirtualObject());
            addObject.replaceAtUsagesAndDelete(allocations[index]);
        } else {
            assert enters != null;
            commit.replaceAtUsages(InputType.Memory, enters.get(enters.size() - 1));
        }
    }
    if (enters != null) {
        for (MonitorEnterNode enter : enters) {
            enter.lower(tool);
        }
    }
    assert commit.hasNoUsages();
    insertAllocationBarrier(commit, graph);
}
Also used : FixedValueAnchorNode(org.graalvm.compiler.nodes.extended.FixedValueAnchorNode) MonitorIdNode(org.graalvm.compiler.nodes.java.MonitorIdNode) AllocatedObjectNode(org.graalvm.compiler.nodes.virtual.AllocatedObjectNode) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) RawMonitorEnterNode(org.graalvm.compiler.nodes.java.RawMonitorEnterNode) MonitorEnterNode(org.graalvm.compiler.nodes.java.MonitorEnterNode) RawLoadNode(org.graalvm.compiler.nodes.extended.RawLoadNode) MonitorIdNode(org.graalvm.compiler.nodes.java.MonitorIdNode) ZeroExtendNode(org.graalvm.compiler.nodes.calc.ZeroExtendNode) RawMonitorEnterNode(org.graalvm.compiler.nodes.java.RawMonitorEnterNode) GuardingNode(org.graalvm.compiler.nodes.extended.GuardingNode) LeftShiftNode(org.graalvm.compiler.nodes.calc.LeftShiftNode) WriteNode(org.graalvm.compiler.nodes.memory.WriteNode) UnsafeMemoryStoreNode(org.graalvm.compiler.nodes.extended.UnsafeMemoryStoreNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) IntegerConvertNode(org.graalvm.compiler.nodes.calc.IntegerConvertNode) IntegerEqualsNode(org.graalvm.compiler.nodes.calc.IntegerEqualsNode) AtomicReadAndWriteNode(org.graalvm.compiler.nodes.java.AtomicReadAndWriteNode) JavaWriteNode(org.graalvm.compiler.nodes.extended.JavaWriteNode) AbstractNewObjectNode(org.graalvm.compiler.nodes.java.AbstractNewObjectNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) IntegerBelowNode(org.graalvm.compiler.nodes.calc.IntegerBelowNode) VirtualInstanceNode(org.graalvm.compiler.nodes.virtual.VirtualInstanceNode) VerifyHeapNode(org.graalvm.compiler.nodes.debug.VerifyHeapNode) ForeignCallNode(org.graalvm.compiler.nodes.extended.ForeignCallNode) NewInstanceNode(org.graalvm.compiler.nodes.java.NewInstanceNode) OffsetAddressNode(org.graalvm.compiler.nodes.memory.address.OffsetAddressNode) NarrowNode(org.graalvm.compiler.nodes.calc.NarrowNode) SignExtendNode(org.graalvm.compiler.nodes.calc.SignExtendNode) JavaReadNode(org.graalvm.compiler.nodes.extended.JavaReadNode) LoadIndexedNode(org.graalvm.compiler.nodes.java.LoadIndexedNode) BoxNode(org.graalvm.compiler.nodes.extended.BoxNode) BinaryMathIntrinsicNode(org.graalvm.compiler.replacements.nodes.BinaryMathIntrinsicNode) VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) RawStoreNode(org.graalvm.compiler.nodes.extended.RawStoreNode) PiNode(org.graalvm.compiler.nodes.PiNode) FinalFieldBarrierNode(org.graalvm.compiler.nodes.java.FinalFieldBarrierNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) IsNullNode(org.graalvm.compiler.nodes.calc.IsNullNode) NewArrayNode(org.graalvm.compiler.nodes.java.NewArrayNode) VirtualArrayNode(org.graalvm.compiler.nodes.virtual.VirtualArrayNode) LogicCompareAndSwapNode(org.graalvm.compiler.nodes.java.LogicCompareAndSwapNode) UnsafeCompareAndSwapNode(org.graalvm.compiler.nodes.java.UnsafeCompareAndSwapNode) LoadFieldNode(org.graalvm.compiler.nodes.java.LoadFieldNode) LoweredAtomicReadAndWriteNode(org.graalvm.compiler.nodes.java.LoweredAtomicReadAndWriteNode) AllocatedObjectNode(org.graalvm.compiler.nodes.virtual.AllocatedObjectNode) ReadNode(org.graalvm.compiler.nodes.memory.ReadNode) InstanceOfDynamicNode(org.graalvm.compiler.nodes.java.InstanceOfDynamicNode) AddNode(org.graalvm.compiler.nodes.calc.AddNode) LoadHubNode(org.graalvm.compiler.nodes.extended.LoadHubNode) InstanceOfNode(org.graalvm.compiler.nodes.java.InstanceOfNode) RightShiftNode(org.graalvm.compiler.nodes.calc.RightShiftNode) AccessIndexedNode(org.graalvm.compiler.nodes.java.AccessIndexedNode) ConditionalNode(org.graalvm.compiler.nodes.calc.ConditionalNode) GuardedUnsafeLoadNode(org.graalvm.compiler.nodes.extended.GuardedUnsafeLoadNode) UnsafeMemoryLoadNode(org.graalvm.compiler.nodes.extended.UnsafeMemoryLoadNode) UnpackEndianHalfNode(org.graalvm.compiler.nodes.calc.UnpackEndianHalfNode) UnaryMathIntrinsicNode(org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode) StoreIndexedNode(org.graalvm.compiler.nodes.java.StoreIndexedNode) SubNode(org.graalvm.compiler.nodes.calc.SubNode) CommitAllocationNode(org.graalvm.compiler.nodes.virtual.CommitAllocationNode) AddressNode(org.graalvm.compiler.nodes.memory.address.AddressNode) FixedValueAnchorNode(org.graalvm.compiler.nodes.extended.FixedValueAnchorNode) ArrayLengthNode(org.graalvm.compiler.nodes.java.ArrayLengthNode) MembarNode(org.graalvm.compiler.nodes.extended.MembarNode) MonitorEnterNode(org.graalvm.compiler.nodes.java.MonitorEnterNode) StoreFieldNode(org.graalvm.compiler.nodes.java.StoreFieldNode) Node(org.graalvm.compiler.graph.Node) UnboxNode(org.graalvm.compiler.nodes.extended.UnboxNode) ArrayList(java.util.ArrayList)

Example 3 with AllocatedObjectNode

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

the class PartialEscapeBlockState method materializeBefore.

/**
 * Materializes the given virtual object and produces the necessary effects in the effects list.
 * This transitively also materializes all other virtual objects that are reachable from the
 * entries.
 */
public void materializeBefore(FixedNode fixed, VirtualObjectNode virtual, GraphEffectList materializeEffects) {
    PartialEscapeClosure.COUNTER_MATERIALIZATIONS.increment(fixed.getDebug());
    List<AllocatedObjectNode> objects = new ArrayList<>(2);
    List<ValueNode> values = new ArrayList<>(8);
    List<List<MonitorIdNode>> locks = new ArrayList<>();
    List<ValueNode> otherAllocations = new ArrayList<>(2);
    List<Boolean> ensureVirtual = new ArrayList<>(2);
    materializeWithCommit(fixed, virtual, objects, locks, values, ensureVirtual, otherAllocations);
    materializeEffects.addVirtualizationDelta(-(objects.size() + otherAllocations.size()));
    materializeEffects.add("materializeBefore", new Effect() {

        @Override
        public void apply(StructuredGraph graph, ArrayList<Node> obsoleteNodes) {
            for (ValueNode alloc : otherAllocations) {
                ValueNode otherAllocation = graph.addOrUniqueWithInputs(alloc);
                if (otherAllocation instanceof FixedWithNextNode) {
                    graph.addBeforeFixed(fixed, (FixedWithNextNode) otherAllocation);
                } else {
                    assert otherAllocation instanceof FloatingNode;
                }
            }
            if (!objects.isEmpty()) {
                CommitAllocationNode commit;
                if (fixed.predecessor() instanceof CommitAllocationNode) {
                    commit = (CommitAllocationNode) fixed.predecessor();
                } else {
                    commit = graph.add(new CommitAllocationNode());
                    graph.addBeforeFixed(fixed, commit);
                }
                for (AllocatedObjectNode obj : objects) {
                    graph.addWithoutUnique(obj);
                    commit.getVirtualObjects().add(obj.getVirtualObject());
                    obj.setCommit(commit);
                }
                for (ValueNode value : values) {
                    commit.getValues().add(graph.addOrUniqueWithInputs(value));
                }
                for (List<MonitorIdNode> monitorIds : locks) {
                    commit.addLocks(monitorIds);
                }
                commit.getEnsureVirtual().addAll(ensureVirtual);
                assert commit.usages().filter(AllocatedObjectNode.class).count() == commit.getUsageCount();
                List<AllocatedObjectNode> materializedValues = commit.usages().filter(AllocatedObjectNode.class).snapshot();
                for (int i = 0; i < commit.getValues().size(); i++) {
                    if (materializedValues.contains(commit.getValues().get(i))) {
                        commit.getValues().set(i, ((AllocatedObjectNode) commit.getValues().get(i)).getVirtualObject());
                    }
                }
            }
        }
    });
}
Also used : FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) AllocatedObjectNode(org.graalvm.compiler.nodes.virtual.AllocatedObjectNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) FloatingNode(org.graalvm.compiler.nodes.calc.FloatingNode) VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) AllocatedObjectNode(org.graalvm.compiler.nodes.virtual.AllocatedObjectNode) CommitAllocationNode(org.graalvm.compiler.nodes.virtual.CommitAllocationNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) MonitorIdNode(org.graalvm.compiler.nodes.java.MonitorIdNode) Node(org.graalvm.compiler.graph.Node) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) ArrayList(java.util.ArrayList) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) ValueNode(org.graalvm.compiler.nodes.ValueNode) FloatingNode(org.graalvm.compiler.nodes.calc.FloatingNode) ArrayList(java.util.ArrayList) List(java.util.List) Effect(org.graalvm.compiler.virtual.phases.ea.EffectList.Effect) CommitAllocationNode(org.graalvm.compiler.nodes.virtual.CommitAllocationNode)

Example 4 with AllocatedObjectNode

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

the class PartialEscapeBlockState method materializeWithCommit.

private void materializeWithCommit(FixedNode fixed, VirtualObjectNode virtual, List<AllocatedObjectNode> objects, List<List<MonitorIdNode>> locks, List<ValueNode> values, List<Boolean> ensureVirtual, List<ValueNode> otherAllocations) {
    ObjectState obj = getObjectState(virtual);
    ValueNode[] entries = obj.getEntries();
    ValueNode representation = virtual.getMaterializedRepresentation(fixed, entries, obj.getLocks());
    escape(virtual.getObjectId(), representation);
    obj = getObjectState(virtual);
    PartialEscapeClosure.updateStatesForMaterialized(this, virtual, obj.getMaterializedValue());
    if (representation instanceof AllocatedObjectNode) {
        objects.add((AllocatedObjectNode) representation);
        locks.add(LockState.asList(obj.getLocks()));
        ensureVirtual.add(obj.getEnsureVirtualized());
        int pos = values.size();
        while (values.size() < pos + entries.length) {
            values.add(null);
        }
        for (int i = 0; i < entries.length; i++) {
            if (entries[i] instanceof VirtualObjectNode) {
                VirtualObjectNode entryVirtual = (VirtualObjectNode) entries[i];
                ObjectState entryObj = getObjectState(entryVirtual);
                if (entryObj.isVirtual()) {
                    materializeWithCommit(fixed, entryVirtual, objects, locks, values, ensureVirtual, otherAllocations);
                    entryObj = getObjectState(entryVirtual);
                }
                values.set(pos + i, entryObj.getMaterializedValue());
            } else {
                values.set(pos + i, entries[i]);
            }
        }
        objectMaterialized(virtual, (AllocatedObjectNode) representation, values.subList(pos, pos + entries.length));
    } else {
        VirtualUtil.trace(options, debug, "materialized %s as %s", virtual, representation);
        otherAllocations.add(representation);
        assert obj.getLocks() == null;
    }
}
Also used : VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) AllocatedObjectNode(org.graalvm.compiler.nodes.virtual.AllocatedObjectNode) ValueNode(org.graalvm.compiler.nodes.ValueNode)

Aggregations

AllocatedObjectNode (org.graalvm.compiler.nodes.virtual.AllocatedObjectNode)4 ValueNode (org.graalvm.compiler.nodes.ValueNode)3 CommitAllocationNode (org.graalvm.compiler.nodes.virtual.CommitAllocationNode)3 VirtualObjectNode (org.graalvm.compiler.nodes.virtual.VirtualObjectNode)3 ArrayList (java.util.ArrayList)2 Node (org.graalvm.compiler.graph.Node)2 FixedNode (org.graalvm.compiler.nodes.FixedNode)2 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)2 MonitorIdNode (org.graalvm.compiler.nodes.java.MonitorIdNode)2 List (java.util.List)1 DefaultLoopPolicies (org.graalvm.compiler.loop.DefaultLoopPolicies)1 LoopFullUnrollPhase (org.graalvm.compiler.loop.phases.LoopFullUnrollPhase)1 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)1 FixedWithNextNode (org.graalvm.compiler.nodes.FixedWithNextNode)1 LogicNode (org.graalvm.compiler.nodes.LogicNode)1 PiNode (org.graalvm.compiler.nodes.PiNode)1 AddNode (org.graalvm.compiler.nodes.calc.AddNode)1 ConditionalNode (org.graalvm.compiler.nodes.calc.ConditionalNode)1 FloatingNode (org.graalvm.compiler.nodes.calc.FloatingNode)1 IntegerBelowNode (org.graalvm.compiler.nodes.calc.IntegerBelowNode)1