Search in sources :

Example 1 with VirtualArrayNode

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

the class ArrayLengthNode method virtualize.

@Override
public void virtualize(VirtualizerTool tool) {
    ValueNode alias = tool.getAlias(array());
    if (alias instanceof VirtualArrayNode) {
        VirtualArrayNode virtualArray = (VirtualArrayNode) alias;
        tool.replaceWithValue(ConstantNode.forInt(virtualArray.entryCount(), graph()));
    }
}
Also used : VirtualArrayNode(org.graalvm.compiler.nodes.virtual.VirtualArrayNode) ValueNode(org.graalvm.compiler.nodes.ValueNode)

Example 2 with VirtualArrayNode

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

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

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

the class GraphUtil method virtualizeArrayCopy.

/**
 * Virtualize an array copy.
 *
 * @param tool the virtualization tool
 * @param source the source array
 * @param sourceLength the length of the source array
 * @param newLength the length of the new array
 * @param from the start index in the source array
 * @param newComponentType the component type of the new array
 * @param elementKind the kind of the new array elements
 * @param graph the node graph
 * @param virtualArrayProvider a functional provider that returns a new virtual array given the
 *            component type and length
 */
public static void virtualizeArrayCopy(VirtualizerTool tool, ValueNode source, ValueNode sourceLength, ValueNode newLength, ValueNode from, ResolvedJavaType newComponentType, JavaKind elementKind, StructuredGraph graph, BiFunction<ResolvedJavaType, Integer, VirtualArrayNode> virtualArrayProvider) {
    ValueNode sourceAlias = tool.getAlias(source);
    ValueNode replacedSourceLength = tool.getAlias(sourceLength);
    ValueNode replacedNewLength = tool.getAlias(newLength);
    ValueNode replacedFrom = tool.getAlias(from);
    if (!replacedNewLength.isConstant() || !replacedFrom.isConstant() || !replacedSourceLength.isConstant()) {
        return;
    }
    assert newComponentType != null : "An array copy can be virtualized only if the real type of the resulting array is known statically.";
    int fromInt = replacedFrom.asJavaConstant().asInt();
    int newLengthInt = replacedNewLength.asJavaConstant().asInt();
    int sourceLengthInt = replacedSourceLength.asJavaConstant().asInt();
    if (sourceAlias instanceof VirtualObjectNode) {
        VirtualObjectNode sourceVirtual = (VirtualObjectNode) sourceAlias;
        assert sourceLengthInt == sourceVirtual.entryCount();
    }
    if (fromInt < 0 || newLengthInt < 0 || fromInt > sourceLengthInt) {
        /* Illegal values for either from index, the new length or the source length. */
        return;
    }
    if (newLengthInt >= tool.getMaximumEntryCount()) {
        /* The new array size is higher than maximum allowed size of virtualized objects. */
        return;
    }
    ValueNode[] newEntryState = new ValueNode[newLengthInt];
    int readLength = Math.min(newLengthInt, sourceLengthInt - fromInt);
    if (sourceAlias instanceof VirtualObjectNode) {
        /* The source array is virtualized, just copy over the values. */
        VirtualObjectNode sourceVirtual = (VirtualObjectNode) sourceAlias;
        for (int i = 0; i < readLength; i++) {
            newEntryState[i] = tool.getEntry(sourceVirtual, fromInt + i);
        }
    } else {
        /* The source array is not virtualized, emit index loads. */
        for (int i = 0; i < readLength; i++) {
            LoadIndexedNode load = new LoadIndexedNode(null, sourceAlias, ConstantNode.forInt(i + fromInt, graph), elementKind);
            tool.addNode(load);
            newEntryState[i] = load;
        }
    }
    if (readLength < newLengthInt) {
        /* Pad the copy with the default value of its elment kind. */
        ValueNode defaultValue = ConstantNode.defaultForKind(elementKind, graph);
        for (int i = readLength; i < newLengthInt; i++) {
            newEntryState[i] = defaultValue;
        }
    }
    /* Perform the replacement. */
    VirtualArrayNode newVirtualArray = virtualArrayProvider.apply(newComponentType, newLengthInt);
    tool.createVirtualObject(newVirtualArray, newEntryState, Collections.<MonitorIdNode>emptyList(), false);
    tool.replaceWithVirtual(newVirtualArray);
}
Also used : VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) LoadIndexedNode(org.graalvm.compiler.nodes.java.LoadIndexedNode) VirtualArrayNode(org.graalvm.compiler.nodes.virtual.VirtualArrayNode) ValueNode(org.graalvm.compiler.nodes.ValueNode)

Example 5 with VirtualArrayNode

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

the class LoadIndexedNode method virtualize.

@Override
public void virtualize(VirtualizerTool tool) {
    ValueNode alias = tool.getAlias(array());
    if (alias instanceof VirtualObjectNode) {
        VirtualArrayNode virtual = (VirtualArrayNode) alias;
        ValueNode indexValue = tool.getAlias(index());
        int idx = indexValue.isConstant() ? indexValue.asJavaConstant().asInt() : -1;
        if (idx >= 0 && idx < virtual.entryCount()) {
            ValueNode entry = tool.getEntry(virtual, idx);
            if (stamp.isCompatible(entry.stamp(NodeView.DEFAULT))) {
                tool.replaceWith(entry);
            } else {
                assert stamp(NodeView.DEFAULT).getStackKind() == JavaKind.Int && (entry.stamp(NodeView.DEFAULT).getStackKind() == JavaKind.Long || entry.getStackKind() == JavaKind.Double || entry.getStackKind() == JavaKind.Illegal) : "Can only allow different stack kind two slot marker writes on one stot fields.";
            }
        }
    }
}
Also used : VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) VirtualArrayNode(org.graalvm.compiler.nodes.virtual.VirtualArrayNode) ValueNode(org.graalvm.compiler.nodes.ValueNode)

Aggregations

ValueNode (org.graalvm.compiler.nodes.ValueNode)6 VirtualArrayNode (org.graalvm.compiler.nodes.virtual.VirtualArrayNode)6 VirtualObjectNode (org.graalvm.compiler.nodes.virtual.VirtualObjectNode)5 ResolvedJavaType (jdk.vm.ci.meta.ResolvedJavaType)2 LoadIndexedNode (org.graalvm.compiler.nodes.java.LoadIndexedNode)2 ArrayList (java.util.ArrayList)1 BitSet (java.util.BitSet)1 JavaKind (jdk.vm.ci.meta.JavaKind)1 ResolvedJavaField (jdk.vm.ci.meta.ResolvedJavaField)1 DebugCloseable (org.graalvm.compiler.debug.DebugCloseable)1 DebugContext (org.graalvm.compiler.debug.DebugContext)1 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)1 JavaWriteNode (org.graalvm.compiler.nodes.extended.JavaWriteNode)1 AbstractNewObjectNode (org.graalvm.compiler.nodes.java.AbstractNewObjectNode)1 AtomicReadAndWriteNode (org.graalvm.compiler.nodes.java.AtomicReadAndWriteNode)1 LoweredAtomicReadAndWriteNode (org.graalvm.compiler.nodes.java.LoweredAtomicReadAndWriteNode)1 AbstractMemoryCheckpoint (org.graalvm.compiler.nodes.memory.AbstractMemoryCheckpoint)1 BarrierType (org.graalvm.compiler.nodes.memory.HeapAccess.BarrierType)1 MemoryCheckpoint (org.graalvm.compiler.nodes.memory.MemoryCheckpoint)1 WriteNode (org.graalvm.compiler.nodes.memory.WriteNode)1