Search in sources :

Example 1 with VirtualInstanceNode

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

the class StoreFieldNode method virtualize.

@Override
public void virtualize(VirtualizerTool tool) {
    ValueNode alias = tool.getAlias(object());
    if (alias instanceof VirtualObjectNode) {
        VirtualInstanceNode virtual = (VirtualInstanceNode) alias;
        int fieldIndex = virtual.fieldIndex(field());
        if (fieldIndex != -1) {
            tool.setVirtualEntry(virtual, fieldIndex, value());
            tool.delete();
        }
    }
}
Also used : VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) VirtualInstanceNode(org.graalvm.compiler.nodes.virtual.VirtualInstanceNode)

Example 2 with VirtualInstanceNode

use of org.graalvm.compiler.nodes.virtual.VirtualInstanceNode 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 3 with VirtualInstanceNode

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

the class VirtualizerToolImpl method setVirtualEntry.

@Override
public boolean setVirtualEntry(VirtualObjectNode virtual, int index, ValueNode value, JavaKind theAccessKind, long offset) {
    ObjectState obj = state.getObjectState(virtual);
    assert obj.isVirtual() : "not virtual: " + obj;
    ValueNode newValue;
    JavaKind entryKind = virtual.entryKind(index);
    JavaKind accessKind = theAccessKind != null ? theAccessKind : entryKind;
    if (value == null) {
        newValue = null;
    } else {
        newValue = closure.getAliasAndResolve(state, value);
    }
    getDebug().log(DebugContext.DETAILED_LEVEL, "Setting entry %d in virtual object %s %s results in %s", index, virtual.getObjectId(), virtual, state.getObjectState(virtual.getObjectId()));
    ValueNode oldValue = getEntry(virtual, index);
    boolean canVirtualize = entryKind == accessKind || (entryKind == accessKind.getStackKind() && virtual instanceof VirtualInstanceNode);
    if (!canVirtualize) {
        if (entryKind == JavaKind.Long && oldValue.getStackKind() == newValue.getStackKind() && oldValue.getStackKind().isPrimitive()) {
            /*
                 * Special case: If the entryKind is long, allow arbitrary kinds as long as a value
                 * of the same kind is already there. This can only happen if some other node
                 * initialized the entry with a value of a different kind. One example where this
                 * happens is the Truffle NewFrameNode.
                 */
            getDebug().log(DebugContext.DETAILED_LEVEL, "virtualizing %s with primitive of kind %s in long entry ", current, oldValue.getStackKind());
            canVirtualize = true;
        } else if (entryKind == JavaKind.Int && (accessKind == JavaKind.Long || accessKind == JavaKind.Double) && offset % 8 == 0) {
            /*
                 * Special case: Allow storing a single long or double value into two consecutive
                 * int slots.
                 */
            int nextIndex = virtual.entryIndexForOffset(getArrayOffsetProvider(), offset + 4, JavaKind.Int);
            if (nextIndex != -1) {
                canVirtualize = true;
                assert nextIndex == index + 1 : "expected to be sequential";
                getDebug().log(DebugContext.DETAILED_LEVEL, "virtualizing %s for double word stored in two ints", current);
            }
        }
    }
    if (canVirtualize) {
        getDebug().log(DebugContext.DETAILED_LEVEL, "virtualizing %s for entryKind %s and access kind %s", current, entryKind, accessKind);
        state.setEntry(virtual.getObjectId(), index, newValue);
        if (entryKind == JavaKind.Int) {
            if (accessKind.needsTwoSlots()) {
                // Storing double word value two int slots
                assert virtual.entryKind(index + 1) == JavaKind.Int;
                state.setEntry(virtual.getObjectId(), index + 1, getIllegalConstant());
            } else if (oldValue.getStackKind() == JavaKind.Double || oldValue.getStackKind() == JavaKind.Long) {
                // Splitting double word constant by storing over it with an int
                getDebug().log(DebugContext.DETAILED_LEVEL, "virtualizing %s producing second half of double word value %s", current, oldValue);
                ValueNode secondHalf = UnpackEndianHalfNode.create(oldValue, false, NodeView.DEFAULT);
                addNode(secondHalf);
                state.setEntry(virtual.getObjectId(), index + 1, secondHalf);
            }
        }
        if (oldValue.isConstant() && oldValue.asConstant().equals(JavaConstant.forIllegal())) {
            // Storing into second half of double, so replace previous value
            ValueNode previous = getEntry(virtual, index - 1);
            getDebug().log(DebugContext.DETAILED_LEVEL, "virtualizing %s producing first half of double word value %s", current, previous);
            ValueNode firstHalf = UnpackEndianHalfNode.create(previous, true, NodeView.DEFAULT);
            addNode(firstHalf);
            state.setEntry(virtual.getObjectId(), index - 1, firstHalf);
        }
        return true;
    }
    // Should only occur if there are mismatches between the entry and access kind
    assert entryKind != accessKind;
    return false;
}
Also used : ValueNode(org.graalvm.compiler.nodes.ValueNode) VirtualInstanceNode(org.graalvm.compiler.nodes.virtual.VirtualInstanceNode) JavaKind(jdk.vm.ci.meta.JavaKind)

Example 4 with VirtualInstanceNode

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

the class DefaultJavaLoweringProvider method lowerCommitAllocationNode.

@SuppressWarnings("try")
protected void lowerCommitAllocationNode(CommitAllocationNode commit, LoweringTool tool) {
    StructuredGraph graph = commit.graph();
    if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) {
        List<AbstractNewObjectNode> recursiveLowerings = new ArrayList<>();
        ValueNode[] allocations = new ValueNode[commit.getVirtualObjects().size()];
        BitSet omittedValues = new BitSet();
        int valuePos = 0;
        for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) {
            VirtualObjectNode virtual = commit.getVirtualObjects().get(objIndex);
            int entryCount = virtual.entryCount();
            AbstractNewObjectNode newObject;
            try (DebugCloseable nsp = virtual.withNodeSourcePosition()) {
                if (virtual instanceof VirtualInstanceNode) {
                    newObject = graph.add(createNewInstanceFromVirtual(virtual));
                } else {
                    newObject = graph.add(createNewArrayFromVirtual(virtual, ConstantNode.forInt(entryCount, graph)));
                }
            }
            recursiveLowerings.add(newObject);
            graph.addBeforeFixed(commit, newObject);
            allocations[objIndex] = newObject;
            for (int i = 0; i < entryCount; i++) {
                ValueNode value = commit.getValues().get(valuePos);
                if (value instanceof VirtualObjectNode) {
                    value = allocations[commit.getVirtualObjects().indexOf(value)];
                }
                if (value == null) {
                    omittedValues.set(valuePos);
                } else if (!(value.isConstant() && value.asConstant().isDefaultForKind())) {
                    // Constant.illegal is always the defaultForKind, so it is skipped
                    JavaKind valueKind = value.getStackKind();
                    JavaKind entryKind = virtual.entryKind(i);
                    // Truffle requires some leniency in terms of what can be put where:
                    assert valueKind.getStackKind() == entryKind.getStackKind() || (valueKind == JavaKind.Long || valueKind == JavaKind.Double || (valueKind == JavaKind.Int && virtual instanceof VirtualArrayNode));
                    AddressNode address = null;
                    BarrierType barrierType = null;
                    if (virtual instanceof VirtualInstanceNode) {
                        ResolvedJavaField field = ((VirtualInstanceNode) virtual).field(i);
                        long offset = fieldOffset(field);
                        if (offset >= 0) {
                            address = createOffsetAddress(graph, newObject, offset);
                            barrierType = fieldInitializationBarrier(entryKind);
                        }
                    } else {
                        address = createOffsetAddress(graph, newObject, arrayBaseOffset(entryKind) + i * arrayScalingFactor(entryKind));
                        barrierType = arrayInitializationBarrier(entryKind);
                    }
                    if (address != null) {
                        WriteNode write = new WriteNode(address, LocationIdentity.init(), implicitStoreConvert(graph, entryKind, value), barrierType);
                        graph.addAfterFixed(newObject, graph.add(write));
                    }
                }
                valuePos++;
            }
        }
        valuePos = 0;
        for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) {
            VirtualObjectNode virtual = commit.getVirtualObjects().get(objIndex);
            int entryCount = virtual.entryCount();
            ValueNode newObject = allocations[objIndex];
            for (int i = 0; i < entryCount; i++) {
                if (omittedValues.get(valuePos)) {
                    ValueNode value = commit.getValues().get(valuePos);
                    assert value instanceof VirtualObjectNode;
                    ValueNode allocValue = allocations[commit.getVirtualObjects().indexOf(value)];
                    if (!(allocValue.isConstant() && allocValue.asConstant().isDefaultForKind())) {
                        assert virtual.entryKind(i) == JavaKind.Object && allocValue.getStackKind() == JavaKind.Object;
                        AddressNode address;
                        BarrierType barrierType;
                        if (virtual instanceof VirtualInstanceNode) {
                            VirtualInstanceNode virtualInstance = (VirtualInstanceNode) virtual;
                            address = createFieldAddress(graph, newObject, virtualInstance.field(i));
                            barrierType = BarrierType.IMPRECISE;
                        } else {
                            address = createArrayAddress(graph, newObject, virtual.entryKind(i), ConstantNode.forInt(i, graph));
                            barrierType = BarrierType.PRECISE;
                        }
                        if (address != null) {
                            WriteNode write = new WriteNode(address, LocationIdentity.init(), implicitStoreConvert(graph, JavaKind.Object, allocValue), barrierType);
                            graph.addBeforeFixed(commit, graph.add(write));
                        }
                    }
                }
                valuePos++;
            }
        }
        finishAllocatedObjects(tool, commit, allocations);
        graph.removeFixed(commit);
        for (AbstractNewObjectNode recursiveLowering : recursiveLowerings) {
            recursiveLowering.lower(tool);
        }
    }
}
Also used : VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) VirtualArrayNode(org.graalvm.compiler.nodes.virtual.VirtualArrayNode) ArrayList(java.util.ArrayList) BitSet(java.util.BitSet) BarrierType(org.graalvm.compiler.nodes.memory.HeapAccess.BarrierType) ResolvedJavaField(jdk.vm.ci.meta.ResolvedJavaField) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) AbstractNewObjectNode(org.graalvm.compiler.nodes.java.AbstractNewObjectNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) OffsetAddressNode(org.graalvm.compiler.nodes.memory.address.OffsetAddressNode) AddressNode(org.graalvm.compiler.nodes.memory.address.AddressNode) VirtualInstanceNode(org.graalvm.compiler.nodes.virtual.VirtualInstanceNode) DebugCloseable(org.graalvm.compiler.debug.DebugCloseable) WriteNode(org.graalvm.compiler.nodes.memory.WriteNode) AtomicReadAndWriteNode(org.graalvm.compiler.nodes.java.AtomicReadAndWriteNode) JavaWriteNode(org.graalvm.compiler.nodes.extended.JavaWriteNode) LoweredAtomicReadAndWriteNode(org.graalvm.compiler.nodes.java.LoweredAtomicReadAndWriteNode) JavaKind(jdk.vm.ci.meta.JavaKind)

Example 5 with VirtualInstanceNode

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

the class PartialEvaluator method postPartialEvaluation.

private static void postPartialEvaluation(final StructuredGraph graph) {
    NeverPartOfCompilationNode.verifyNotFoundIn(graph);
    for (AllowMaterializeNode materializeNode : graph.getNodes(AllowMaterializeNode.TYPE).snapshot()) {
        materializeNode.replaceAtUsages(materializeNode.getFrame());
        graph.removeFixed(materializeNode);
    }
    TruffleCompilerRuntime rt = TruffleCompilerRuntime.getRuntime();
    for (VirtualObjectNode virtualObjectNode : graph.getNodes(VirtualObjectNode.TYPE)) {
        if (virtualObjectNode instanceof VirtualInstanceNode) {
            VirtualInstanceNode virtualInstanceNode = (VirtualInstanceNode) virtualObjectNode;
            ResolvedJavaType type = virtualInstanceNode.type();
            if (rt.isValueType(type)) {
                virtualInstanceNode.setIdentity(false);
            }
        }
    }
    if (!TruffleCompilerOptions.getValue(TruffleInlineAcrossTruffleBoundary)) {
        // Do not inline across Truffle boundaries.
        for (MethodCallTargetNode mct : graph.getNodes(MethodCallTargetNode.TYPE)) {
            InlineInfo inlineInfo = rt.getInlineInfo(mct.targetMethod(), false);
            if (!inlineInfo.allowsInlining()) {
                mct.invoke().setUseForInlining(false);
            }
        }
    }
}
Also used : VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) TruffleCompilerRuntime(org.graalvm.compiler.truffle.common.TruffleCompilerRuntime) AllowMaterializeNode(org.graalvm.compiler.truffle.compiler.nodes.frame.AllowMaterializeNode) VirtualInstanceNode(org.graalvm.compiler.nodes.virtual.VirtualInstanceNode) InlineInfo.createStandardInlineInfo(org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin.InlineInfo.createStandardInlineInfo) InlineInfo(org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin.InlineInfo) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType)

Aggregations

VirtualInstanceNode (org.graalvm.compiler.nodes.virtual.VirtualInstanceNode)6 ValueNode (org.graalvm.compiler.nodes.ValueNode)5 VirtualObjectNode (org.graalvm.compiler.nodes.virtual.VirtualObjectNode)4 ResolvedJavaField (jdk.vm.ci.meta.ResolvedJavaField)3 JavaKind (jdk.vm.ci.meta.JavaKind)2 ResolvedJavaType (jdk.vm.ci.meta.ResolvedJavaType)2 ArrayList (java.util.ArrayList)1 BitSet (java.util.BitSet)1 DebugCloseable (org.graalvm.compiler.debug.DebugCloseable)1 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)1 JavaWriteNode (org.graalvm.compiler.nodes.extended.JavaWriteNode)1 InlineInfo (org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin.InlineInfo)1 InlineInfo.createStandardInlineInfo (org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin.InlineInfo.createStandardInlineInfo)1 AbstractNewObjectNode (org.graalvm.compiler.nodes.java.AbstractNewObjectNode)1 AtomicReadAndWriteNode (org.graalvm.compiler.nodes.java.AtomicReadAndWriteNode)1 LoadFieldNode (org.graalvm.compiler.nodes.java.LoadFieldNode)1 LoweredAtomicReadAndWriteNode (org.graalvm.compiler.nodes.java.LoweredAtomicReadAndWriteNode)1 MethodCallTargetNode (org.graalvm.compiler.nodes.java.MethodCallTargetNode)1 BarrierType (org.graalvm.compiler.nodes.memory.HeapAccess.BarrierType)1 WriteNode (org.graalvm.compiler.nodes.memory.WriteNode)1