Search in sources :

Example 11 with BarrierType

use of org.graalvm.compiler.nodes.memory.OnHeapMemoryAccess.BarrierType 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);
            try (DebugCloseable nsp = graph.withNodeSourcePosition(virtual)) {
                int entryCount = virtual.entryCount();
                AbstractNewObjectNode newObject;
                if (virtual instanceof VirtualInstanceNode) {
                    newObject = graph.add(new NewInstanceNode(virtual.type(), true));
                } else {
                    assert virtual instanceof VirtualArrayNode;
                    newObject = graph.add(new NewArrayNode(((VirtualArrayNode) virtual).componentType(), ConstantNode.forInt(entryCount, graph), true));
                }
                // The final STORE_STORE barrier will be emitted by finishAllocatedObjects
                newObject.clearEmitMemoryBarrier();
                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 storageKind = virtual.entryKind(tool.getMetaAccessExtensionProvider(), i);
                        // Truffle requires some leniency in terms of what can be put where:
                        assert valueKind.getStackKind() == storageKind.getStackKind() || (valueKind == JavaKind.Long || valueKind == JavaKind.Double || (valueKind == JavaKind.Int && virtual instanceof VirtualArrayNode) || (valueKind == JavaKind.Float && 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 = barrierSet.fieldStoreBarrierType(field, getStorageKind(field));
                            }
                        } else {
                            assert virtual instanceof VirtualArrayNode;
                            address = createOffsetAddress(graph, newObject, metaAccess.getArrayBaseOffset(storageKind) + i * metaAccess.getArrayIndexScale(storageKind));
                            barrierType = barrierSet.arrayStoreBarrierType(storageKind);
                        }
                        if (address != null) {
                            WriteNode write = new WriteNode(address, LocationIdentity.init(), arrayImplicitStoreConvert(graph, storageKind, value, commit, virtual, valuePos), 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);
            try (DebugCloseable nsp = graph.withNodeSourcePosition(virtual)) {
                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(metaAccessExtensionProvider, i) == JavaKind.Object && allocValue.getStackKind() == JavaKind.Object;
                            AddressNode address;
                            BarrierType barrierType;
                            if (virtual instanceof VirtualInstanceNode) {
                                VirtualInstanceNode virtualInstance = (VirtualInstanceNode) virtual;
                                ResolvedJavaField field = virtualInstance.field(i);
                                address = createFieldAddress(graph, newObject, field);
                                barrierType = barrierSet.fieldStoreBarrierType(field, getStorageKind(field));
                            } else {
                                assert virtual instanceof VirtualArrayNode;
                                address = createArrayAddress(graph, newObject, virtual.entryKind(metaAccessExtensionProvider, i), ConstantNode.forInt(i, graph));
                                barrierType = barrierSet.arrayStoreBarrierType(virtual.entryKind(metaAccessExtensionProvider, i));
                            }
                            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, commit, allocations);
        graph.removeFixed(commit);
        for (AbstractNewObjectNode recursiveLowering : recursiveLowerings) {
            recursiveLowering.lower(tool);
        }
    }
}
Also used : VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) NewInstanceNode(org.graalvm.compiler.nodes.java.NewInstanceNode) NewArrayNode(org.graalvm.compiler.nodes.java.NewArrayNode) VirtualArrayNode(org.graalvm.compiler.nodes.virtual.VirtualArrayNode) ArrayList(java.util.ArrayList) BitSet(java.util.BitSet) BarrierType(org.graalvm.compiler.nodes.memory.OnHeapMemoryAccess.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) GetObjectAddressNode(org.graalvm.compiler.nodes.GetObjectAddressNode) IndexAddressNode(org.graalvm.compiler.nodes.memory.address.IndexAddressNode) ComputeObjectAddressNode(org.graalvm.compiler.nodes.ComputeObjectAddressNode) 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) OrderedWriteNode(org.graalvm.compiler.nodes.memory.OrderedWriteNode) 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 12 with BarrierType

use of org.graalvm.compiler.nodes.memory.OnHeapMemoryAccess.BarrierType in project graal by oracle.

the class DefaultJavaLoweringProvider method lowerCompareAndExchangeNode.

protected void lowerCompareAndExchangeNode(UnsafeCompareAndExchangeNode cas) {
    StructuredGraph graph = cas.graph();
    JavaKind valueKind = cas.getValueKind();
    ValueNode expectedValue = implicitStoreConvert(graph, valueKind, cas.expected());
    ValueNode newValue = implicitStoreConvert(graph, valueKind, cas.newValue());
    AddressNode address = graph.unique(new OffsetAddressNode(cas.object(), cas.offset()));
    BarrierType barrierType = barrierSet.guessStoreBarrierType(cas.object(), newValue);
    ValueCompareAndSwapNode atomicNode = graph.add(new ValueCompareAndSwapNode(address, expectedValue, newValue, cas.getKilledLocationIdentity(), barrierType, cas.getMemoryOrder()));
    ValueNode coercedNode = implicitLoadConvert(graph, valueKind, atomicNode, true);
    atomicNode.setStateAfter(cas.stateAfter());
    cas.replaceAtUsages(coercedNode);
    graph.replaceFixedWithFixed(cas, atomicNode);
}
Also used : StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) OffsetAddressNode(org.graalvm.compiler.nodes.memory.address.OffsetAddressNode) ValueCompareAndSwapNode(org.graalvm.compiler.nodes.java.ValueCompareAndSwapNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) GetObjectAddressNode(org.graalvm.compiler.nodes.GetObjectAddressNode) IndexAddressNode(org.graalvm.compiler.nodes.memory.address.IndexAddressNode) ComputeObjectAddressNode(org.graalvm.compiler.nodes.ComputeObjectAddressNode) OffsetAddressNode(org.graalvm.compiler.nodes.memory.address.OffsetAddressNode) AddressNode(org.graalvm.compiler.nodes.memory.address.AddressNode) BarrierType(org.graalvm.compiler.nodes.memory.OnHeapMemoryAccess.BarrierType) JavaKind(jdk.vm.ci.meta.JavaKind)

Example 13 with BarrierType

use of org.graalvm.compiler.nodes.memory.OnHeapMemoryAccess.BarrierType in project graal by oracle.

the class DefaultJavaLoweringProvider method lowerStoreIndexedNode.

public void lowerStoreIndexedNode(StoreIndexedNode storeIndexed, LoweringTool tool, int arrayBaseOffset) {
    StructuredGraph graph = storeIndexed.graph();
    ValueNode value = storeIndexed.value();
    ValueNode array = storeIndexed.array();
    array = this.createNullCheckedValue(array, storeIndexed, tool);
    GuardingNode boundsCheck = getBoundsCheck(storeIndexed, array, tool);
    JavaKind storageKind = storeIndexed.elementKind();
    LogicNode condition = null;
    if (storeIndexed.getStoreCheck() == null && storageKind == JavaKind.Object && !StampTool.isPointerAlwaysNull(value)) {
        /* Array store check. */
        TypeReference arrayType = StampTool.typeReferenceOrNull(array);
        if (arrayType != null && arrayType.isExact()) {
            ResolvedJavaType elementType = arrayType.getType().getComponentType();
            if (!elementType.isJavaLangObject()) {
                TypeReference typeReference = TypeReference.createTrusted(storeIndexed.graph().getAssumptions(), elementType);
                LogicNode typeTest = graph.addOrUniqueWithInputs(InstanceOfNode.create(typeReference, value));
                condition = LogicNode.or(graph.unique(IsNullNode.create(value)), typeTest, BranchProbabilityNode.NOT_LIKELY_PROFILE);
            }
        } else {
            /*
                 * The guard on the read hub should be the null check of the array that was
                 * introduced earlier.
                 */
            ValueNode arrayClass = createReadHub(graph, array, tool);
            boolean isKnownObjectArray = arrayType != null && !arrayType.getType().getComponentType().isPrimitive();
            ValueNode componentHub = createReadArrayComponentHub(graph, arrayClass, isKnownObjectArray, storeIndexed);
            LogicNode typeTest = graph.unique(InstanceOfDynamicNode.create(graph.getAssumptions(), tool.getConstantReflection(), componentHub, value, false));
            condition = LogicNode.or(graph.unique(IsNullNode.create(value)), typeTest, BranchProbabilityNode.NOT_LIKELY_PROFILE);
        }
        if (condition != null && condition.isTautology()) {
            // Skip unnecessary guards
            condition = null;
        }
    }
    BarrierType barrierType = barrierSet.arrayStoreBarrierType(storageKind);
    ValueNode positiveIndex = createPositiveIndex(graph, storeIndexed.index(), boundsCheck);
    AddressNode address = createArrayAddress(graph, array, arrayBaseOffset, storageKind, positiveIndex);
    WriteNode memoryWrite = graph.add(new WriteNode(address, NamedLocationIdentity.getArrayLocation(storageKind), implicitStoreConvert(graph, storageKind, value), barrierType));
    memoryWrite.setGuard(boundsCheck);
    if (condition != null) {
        tool.createGuard(storeIndexed, condition, DeoptimizationReason.ArrayStoreException, DeoptimizationAction.InvalidateReprofile);
    }
    memoryWrite.setStateAfter(storeIndexed.stateAfter());
    graph.replaceFixedWithFixed(storeIndexed, memoryWrite);
}
Also used : StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) ValueNode(org.graalvm.compiler.nodes.ValueNode) GetObjectAddressNode(org.graalvm.compiler.nodes.GetObjectAddressNode) IndexAddressNode(org.graalvm.compiler.nodes.memory.address.IndexAddressNode) ComputeObjectAddressNode(org.graalvm.compiler.nodes.ComputeObjectAddressNode) OffsetAddressNode(org.graalvm.compiler.nodes.memory.address.OffsetAddressNode) AddressNode(org.graalvm.compiler.nodes.memory.address.AddressNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) TypeReference(org.graalvm.compiler.core.common.type.TypeReference) OrderedWriteNode(org.graalvm.compiler.nodes.memory.OrderedWriteNode) 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) GuardingNode(org.graalvm.compiler.nodes.extended.GuardingNode) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) BarrierType(org.graalvm.compiler.nodes.memory.OnHeapMemoryAccess.BarrierType) JavaKind(jdk.vm.ci.meta.JavaKind)

Aggregations

BarrierType (org.graalvm.compiler.nodes.memory.OnHeapMemoryAccess.BarrierType)13 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)9 ValueNode (org.graalvm.compiler.nodes.ValueNode)9 AddressNode (org.graalvm.compiler.nodes.memory.address.AddressNode)9 OffsetAddressNode (org.graalvm.compiler.nodes.memory.address.OffsetAddressNode)9 ComputeObjectAddressNode (org.graalvm.compiler.nodes.ComputeObjectAddressNode)8 GetObjectAddressNode (org.graalvm.compiler.nodes.GetObjectAddressNode)8 IndexAddressNode (org.graalvm.compiler.nodes.memory.address.IndexAddressNode)8 JavaKind (jdk.vm.ci.meta.JavaKind)7 JavaWriteNode (org.graalvm.compiler.nodes.extended.JavaWriteNode)4 LoweredAtomicReadAndWriteNode (org.graalvm.compiler.nodes.java.LoweredAtomicReadAndWriteNode)4 ResolvedJavaField (jdk.vm.ci.meta.ResolvedJavaField)3 AtomicReadAndWriteNode (org.graalvm.compiler.nodes.java.AtomicReadAndWriteNode)3 OrderedWriteNode (org.graalvm.compiler.nodes.memory.OrderedWriteNode)3 WriteNode (org.graalvm.compiler.nodes.memory.WriteNode)3 ResolvedJavaType (jdk.vm.ci.meta.ResolvedJavaType)2 LIRKind (org.graalvm.compiler.core.common.LIRKind)2 GraalError (org.graalvm.compiler.debug.GraalError)2 JavaReadNode (org.graalvm.compiler.nodes.extended.JavaReadNode)2 ArrayList (java.util.ArrayList)1