Search in sources :

Example 1 with VirtualObjectState

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

the class ObjectState method createEscapeObjectState.

public EscapeObjectState createEscapeObjectState(DebugContext debug, MetaAccessExtensionProvider metaAccessExtensionProvider, VirtualObjectNode virtual) {
    GET_ESCAPED_OBJECT_STATE.increment(debug);
    if (cachedState == null) {
        CREATE_ESCAPED_OBJECT_STATE.increment(debug);
        if (isVirtual()) {
            /*
                 * Clear out entries that are default values anyway.
                 *
                 * TODO: this should be propagated into ObjectState.entries, but that will take some
                 * more refactoring.
                 */
            ValueNode[] newEntries = entries.clone();
            for (int i = 0; i < newEntries.length; i++) {
                if (newEntries[i].asJavaConstant() == JavaConstant.defaultForKind(virtual.entryKind(metaAccessExtensionProvider, i).getStackKind())) {
                    newEntries[i] = null;
                }
            }
            cachedState = new VirtualObjectState(virtual, newEntries);
        } else {
            cachedState = new MaterializedObjectState(virtual, materializedValue);
        }
    }
    return cachedState;
}
Also used : VirtualObjectState(org.graalvm.compiler.nodes.virtual.VirtualObjectState) ValueNode(org.graalvm.compiler.nodes.ValueNode) MaterializedObjectState(org.graalvm.compiler.nodes.virtual.MaterializedObjectState)

Example 2 with VirtualObjectState

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

the class DebugInfoBuilder method toJavaValue.

protected JavaValue toJavaValue(ValueNode value) {
    try {
        if (value instanceof VirtualObjectNode) {
            VirtualObjectNode obj = (VirtualObjectNode) value;
            EscapeObjectState state = objectStates.get(obj);
            if (state == null && obj.entryCount() > 0) {
                // null states occur for objects with 0 fields
                throw new GraalError("no mapping found for virtual object %s", obj);
            }
            if (state instanceof MaterializedObjectState) {
                return toJavaValue(((MaterializedObjectState) state).materializedValue());
            } else {
                assert obj.entryCount() == 0 || state instanceof VirtualObjectState;
                VirtualObject vobject = virtualObjects.get(obj);
                if (vobject == null) {
                    boolean isAutoBox = obj instanceof VirtualBoxingNode;
                    vobject = GraalServices.createVirtualObject(obj.type(), virtualObjects.size(), isAutoBox);
                    virtualObjects.put(obj, vobject);
                    pendingVirtualObjects.add(obj);
                }
                STATE_VIRTUAL_OBJECTS.increment(debug);
                return vobject;
            }
        } else {
            // Remove proxies from constants so the constant can be directly embedded.
            ValueNode unproxied = GraphUtil.unproxify(value);
            if (unproxied instanceof ConstantNode) {
                STATE_CONSTANTS.increment(debug);
                return unproxied.asJavaConstant();
            } else if (value != null) {
                STATE_VARIABLES.increment(debug);
                Value operand = nodeValueMap.operand(value);
                if (operand instanceof ConstantValue && ((ConstantValue) operand).isJavaConstant()) {
                    return ((ConstantValue) operand).getJavaConstant();
                } else if (LIRValueUtil.isVariable(operand)) {
                    return LIRValueUtil.asVariable(operand);
                } else {
                    assert operand instanceof RegisterValue : operand + " for " + value;
                    return (JavaValue) operand;
                }
            } else {
                // return a dummy value because real value not needed
                STATE_ILLEGALS.increment(debug);
                return Value.ILLEGAL;
            }
        }
    } catch (GraalError e) {
        throw e.addContext("toValue: ", value);
    }
}
Also used : VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) VirtualObjectState(org.graalvm.compiler.nodes.virtual.VirtualObjectState) VirtualBoxingNode(org.graalvm.compiler.nodes.virtual.VirtualBoxingNode) JavaValue(jdk.vm.ci.meta.JavaValue) EscapeObjectState(org.graalvm.compiler.nodes.virtual.EscapeObjectState) RegisterValue(jdk.vm.ci.code.RegisterValue) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) GraalError(org.graalvm.compiler.debug.GraalError) VirtualObject(jdk.vm.ci.code.VirtualObject) ValueNode(org.graalvm.compiler.nodes.ValueNode) JavaValue(jdk.vm.ci.meta.JavaValue) ConstantValue(org.graalvm.compiler.lir.ConstantValue) RegisterValue(jdk.vm.ci.code.RegisterValue) Value(jdk.vm.ci.meta.Value) MaterializedObjectState(org.graalvm.compiler.nodes.virtual.MaterializedObjectState) ConstantValue(org.graalvm.compiler.lir.ConstantValue)

Example 3 with VirtualObjectState

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

the class DebugInfoBuilder method build.

public LIRFrameState build(NodeWithState node, FrameState topState, LabelRef exceptionEdge, JavaConstant deoptReasonAndAction, JavaConstant deoptSpeculation) {
    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);
    assert verifyFrameState(node, topState);
    BytecodeFrame frame = computeFrameForState(node, 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(metaAccessExtensionProvider, 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.isVirtualByteArray(metaAccessExtensionProvider)) : vobjNode + " " + i + " " + previousValue + " " + currentField.values().snapshot();
                        if (vobjNode.isVirtualByteArray(metaAccessExtensionProvider)) {
                            /*
                                 * Let Illegals pass through to help knowing the number of bytes to
                                 * write. For example, writing a short to index 2 of a byte array of
                                 * size 6 would look like, in debug info:
                                 *
                                 * {b0, b1, INT(...), ILLEGAL, b4, b5}
                                 *
                                 * Thus, from the VM, we can simply count the number of illegals to
                                 * restore the byte count.
                                 */
                            values[pos] = Value.ILLEGAL;
                            slotKinds[pos] = JavaKind.Illegal;
                            pos++;
                        } else if (previousValue == null || !previousValue.getStackKind().needsTwoSlots()) {
                            // Don't allow the IllegalConstant to leak into the debug info
                            JavaKind entryKind = vobjNode.entryKind(metaAccessExtensionProvider, 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();
    if (deoptReasonAndAction == null && deoptSpeculation == null) {
        return new LIRFrameState(frame, virtualObjectsArray, exceptionEdge);
    } else {
        return new ImplicitLIRFrameState(frame, virtualObjectsArray, exceptionEdge, deoptReasonAndAction, deoptSpeculation);
    }
}
Also used : VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) LIRFrameState(org.graalvm.compiler.lir.LIRFrameState) ImplicitLIRFrameState(org.graalvm.compiler.lir.ImplicitLIRFrameState) VirtualObjectState(org.graalvm.compiler.nodes.virtual.VirtualObjectState) JavaValue(jdk.vm.ci.meta.JavaValue) LIRFrameState(org.graalvm.compiler.lir.LIRFrameState) ImplicitLIRFrameState(org.graalvm.compiler.lir.ImplicitLIRFrameState) FrameState(org.graalvm.compiler.nodes.FrameState) EscapeObjectState(org.graalvm.compiler.nodes.virtual.EscapeObjectState) BytecodeFrame(jdk.vm.ci.code.BytecodeFrame) ImplicitLIRFrameState(org.graalvm.compiler.lir.ImplicitLIRFrameState) VirtualObject(jdk.vm.ci.code.VirtualObject) ValueNode(org.graalvm.compiler.nodes.ValueNode) MaterializedObjectState(org.graalvm.compiler.nodes.virtual.MaterializedObjectState) JavaKind(jdk.vm.ci.meta.JavaKind)

Example 4 with VirtualObjectState

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

the class CompileQueue method transplantEscapeAnalysisState.

/**
 * The nodes produced by escape analysis need some manual patching: escape analysis requires
 * that {@link ResolvedJavaType#getInstanceFields} is stable and uses the index of a field in
 * that array also to index its own data structures. But {@link AnalysisType} and
 * {@link HostedType} cannot return fields in the same order: Fields that are not seen as
 * reachable by the static analysis are removed from the hosted type; and the layout of objects,
 * i.e., the field order, is only decided after static analysis. Therefore, we need to fix up
 * all the nodes that implicitly use the field index.
 */
protected void transplantEscapeAnalysisState(StructuredGraph graph) {
    for (CommitAllocationNode node : graph.getNodes().filter(CommitAllocationNode.class)) {
        List<ValueNode> values = node.getValues();
        List<ValueNode> aValues = new ArrayList<>(values);
        values.clear();
        int aObjectStartIndex = 0;
        for (VirtualObjectNode virtualObject : node.getVirtualObjects()) {
            transplantVirtualObjectState(virtualObject, aValues, values, aObjectStartIndex);
            aObjectStartIndex += virtualObject.entryCount();
        }
        assert aValues.size() == aObjectStartIndex;
    }
    for (VirtualObjectState node : graph.getNodes().filter(VirtualObjectState.class)) {
        List<ValueNode> values = node.values();
        List<ValueNode> aValues = new ArrayList<>(values);
        values.clear();
        transplantVirtualObjectState(node.object(), aValues, values, 0);
    }
    for (VirtualInstanceNode node : graph.getNodes(VirtualInstanceNode.TYPE)) {
        AnalysisType aType = (AnalysisType) node.type();
        ResolvedJavaField[] aFields = node.getFields();
        assert Arrays.equals(aFields, aType.getInstanceFields(true));
        HostedField[] hFields = universe.lookup(aType).getInstanceFields(true);
        /*
             * We cannot directly write the final field `VirtualInstanceNode.fields`. So we rely on
             * the NodeClass mechanism, which is also used to transplant all other fields.
             */
        Fields nodeClassDataFields = node.getNodeClass().getData();
        for (int i = 0; i < nodeClassDataFields.getCount(); i++) {
            if (nodeClassDataFields.get(node, i) == aFields) {
                nodeClassDataFields.putObjectChecked(node, i, hFields);
            }
        }
    }
}
Also used : VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) AnalysisType(com.oracle.graal.pointsto.meta.AnalysisType) VirtualObjectState(org.graalvm.compiler.nodes.virtual.VirtualObjectState) HostedField(com.oracle.svm.hosted.meta.HostedField) ArrayList(java.util.ArrayList) DeoptEntryInfopoint(com.oracle.svm.core.deopt.DeoptEntryInfopoint) Infopoint(jdk.vm.ci.code.site.Infopoint) ResolvedJavaField(jdk.vm.ci.meta.ResolvedJavaField) Fields(org.graalvm.compiler.core.common.Fields) StackValueNode(com.oracle.svm.core.graal.stackvalue.StackValueNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) VirtualInstanceNode(org.graalvm.compiler.nodes.virtual.VirtualInstanceNode) CommitAllocationNode(org.graalvm.compiler.nodes.virtual.CommitAllocationNode)

Aggregations

ValueNode (org.graalvm.compiler.nodes.ValueNode)4 VirtualObjectState (org.graalvm.compiler.nodes.virtual.VirtualObjectState)4 MaterializedObjectState (org.graalvm.compiler.nodes.virtual.MaterializedObjectState)3 VirtualObjectNode (org.graalvm.compiler.nodes.virtual.VirtualObjectNode)3 VirtualObject (jdk.vm.ci.code.VirtualObject)2 JavaValue (jdk.vm.ci.meta.JavaValue)2 EscapeObjectState (org.graalvm.compiler.nodes.virtual.EscapeObjectState)2 AnalysisType (com.oracle.graal.pointsto.meta.AnalysisType)1 DeoptEntryInfopoint (com.oracle.svm.core.deopt.DeoptEntryInfopoint)1 StackValueNode (com.oracle.svm.core.graal.stackvalue.StackValueNode)1 HostedField (com.oracle.svm.hosted.meta.HostedField)1 ArrayList (java.util.ArrayList)1 BytecodeFrame (jdk.vm.ci.code.BytecodeFrame)1 RegisterValue (jdk.vm.ci.code.RegisterValue)1 Infopoint (jdk.vm.ci.code.site.Infopoint)1 JavaKind (jdk.vm.ci.meta.JavaKind)1 ResolvedJavaField (jdk.vm.ci.meta.ResolvedJavaField)1 Value (jdk.vm.ci.meta.Value)1 Fields (org.graalvm.compiler.core.common.Fields)1 GraalError (org.graalvm.compiler.debug.GraalError)1