Search in sources :

Example 1 with BytecodeFrame

use of jdk.vm.ci.code.BytecodeFrame in project graal by oracle.

the class LIRInstructionClass method toString.

String toString(LIRInstruction obj) {
    StringBuilder result = new StringBuilder();
    appendValues(result, obj, "", " = ", "(", ")", new String[] { "" }, defs);
    result.append(String.valueOf(getOpcode(obj)).toUpperCase());
    appendValues(result, obj, " ", "", "(", ")", new String[] { "", "~" }, uses, alives);
    appendValues(result, obj, " ", "", "{", "}", new String[] { "" }, temps);
    for (int i = 0; i < data.getCount(); i++) {
        if (i == opcodeIndex) {
            continue;
        }
        result.append(" ").append(data.getName(i)).append(": ").append(getFieldString(obj, i, data));
    }
    for (int i = 0; i < states.getCount(); i++) {
        LIRFrameState state = (LIRFrameState) states.getObject(obj, i);
        if (state != null) {
            result.append(" ").append(states.getName(i)).append(" [bci:");
            String sep = "";
            for (BytecodeFrame cur = state.topFrame; cur != null; cur = cur.caller()) {
                result.append(sep).append(cur.getBCI());
                sep = ", ";
            }
            result.append("]");
        }
    }
    return result.toString();
}
Also used : BytecodeFrame(jdk.vm.ci.code.BytecodeFrame)

Example 2 with BytecodeFrame

use of jdk.vm.ci.code.BytecodeFrame in project graal by oracle.

the class DebugInfoBuilder method computeFrameForState.

protected BytecodeFrame computeFrameForState(FrameState state) {
    try {
        assert state.bci != BytecodeFrame.INVALID_FRAMESTATE_BCI;
        assert state.bci != BytecodeFrame.UNKNOWN_BCI;
        assert state.bci != BytecodeFrame.BEFORE_BCI || state.locksSize() == 0;
        assert state.bci != BytecodeFrame.AFTER_BCI || state.locksSize() == 0;
        assert state.bci != BytecodeFrame.AFTER_EXCEPTION_BCI || state.locksSize() == 0;
        assert !(state.getMethod().isSynchronized() && state.bci != BytecodeFrame.BEFORE_BCI && state.bci != BytecodeFrame.AFTER_BCI && state.bci != BytecodeFrame.AFTER_EXCEPTION_BCI) || state.locksSize() > 0;
        assert state.verify();
        int numLocals = state.localsSize();
        int numStack = state.stackSize();
        int numLocks = state.locksSize();
        int numValues = numLocals + numStack + numLocks;
        int numKinds = numLocals + numStack;
        JavaValue[] values = numValues == 0 ? NO_JAVA_VALUES : new JavaValue[numValues];
        JavaKind[] slotKinds = numKinds == 0 ? NO_JAVA_KINDS : new JavaKind[numKinds];
        computeLocals(state, numLocals, values, slotKinds);
        computeStack(state, numLocals, numStack, values, slotKinds);
        computeLocks(state, values);
        BytecodeFrame caller = null;
        if (state.outerFrameState() != null) {
            caller = computeFrameForState(state.outerFrameState());
        }
        if (!state.canProduceBytecodeFrame()) {
            // This typically means a snippet or intrinsic frame state made it to the backend
            StackTraceElement ste = state.getCode().asStackTraceElement(state.bci);
            throw new GraalError("Frame state for %s cannot be converted to a BytecodeFrame since the frame state's code is " + "not the same as the frame state method's code", ste);
        }
        return new BytecodeFrame(caller, state.getMethod(), state.bci, state.rethrowException(), state.duringCall(), values, slotKinds, numLocals, numStack, numLocks);
    } catch (GraalError e) {
        throw e.addContext("FrameState: ", state);
    }
}
Also used : BytecodeFrame(jdk.vm.ci.code.BytecodeFrame) GraalError(org.graalvm.compiler.debug.GraalError) JavaValue(jdk.vm.ci.meta.JavaValue) JavaKind(jdk.vm.ci.meta.JavaKind)

Example 3 with BytecodeFrame

use of jdk.vm.ci.code.BytecodeFrame in project graal by oracle.

the class DebugInfoBuilder method build.

public LIRFrameState build(FrameState topState, LabelRef exceptionEdge) {
    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);
    BytecodeFrame frame = computeFrameForState(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(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 + " " + i + " " + previousValue + " " + currentField.values().snapshot();
                        if (previousValue == null || !previousValue.getStackKind().needsTwoSlots()) {
                            // Don't allow the IllegalConstant to leak into the debug info
                            JavaKind entryKind = vobjNode.entryKind(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();
    return newLIRFrameState(exceptionEdge, frame, virtualObjectsArray);
}
Also used : VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) VirtualObjectState(org.graalvm.compiler.virtual.nodes.VirtualObjectState) JavaValue(jdk.vm.ci.meta.JavaValue) LIRFrameState(org.graalvm.compiler.lir.LIRFrameState) FrameState(org.graalvm.compiler.nodes.FrameState) EscapeObjectState(org.graalvm.compiler.nodes.virtual.EscapeObjectState) BytecodeFrame(jdk.vm.ci.code.BytecodeFrame) VirtualObject(jdk.vm.ci.code.VirtualObject) ValueNode(org.graalvm.compiler.nodes.ValueNode) MaterializedObjectState(org.graalvm.compiler.virtual.nodes.MaterializedObjectState) JavaKind(jdk.vm.ci.meta.JavaKind)

Example 4 with BytecodeFrame

use of jdk.vm.ci.code.BytecodeFrame in project graal by oracle.

the class HotSpotMonitorValueTest method addMethod.

@Override
protected InstalledCode addMethod(DebugContext debug, ResolvedJavaMethod method, CompilationResult compResult) {
    for (Infopoint i : compResult.getInfopoints()) {
        if (i instanceof Call) {
            Call call = (Call) i;
            if (call.target instanceof ResolvedJavaMethod) {
                ResolvedJavaMethod target = (ResolvedJavaMethod) call.target;
                if (target.equals(lookupObjectWait())) {
                    BytecodeFrame frame = call.debugInfo.frame();
                    BytecodeFrame caller = frame.caller();
                    assertNotNull(caller);
                    assertNull(caller.caller());
                    assertDeepEquals(2, frame.numLocks);
                    assertDeepEquals(2, caller.numLocks);
                    StackLockValue lock1 = (StackLockValue) frame.getLockValue(0);
                    StackLockValue lock2 = (StackLockValue) frame.getLockValue(1);
                    StackLockValue lock3 = (StackLockValue) caller.getLockValue(0);
                    StackLockValue lock4 = (StackLockValue) caller.getLockValue(1);
                    List<StackLockValue> locks = Arrays.asList(lock1, lock2, lock3, lock4);
                    for (StackLockValue lock : locks) {
                        for (StackLockValue other : locks) {
                            if (other != lock) {
                                // Every lock must have a different stack slot
                                assertThat(lock.getSlot(), not(other.getSlot()));
                            }
                        }
                    }
                    assertDeepEquals(lock3.getOwner(), lock4.getOwner());
                    assertThat(lock1.getOwner(), not(lock2.getOwner()));
                    return super.addMethod(debug, method, compResult);
                }
            }
        }
    }
    throw new AssertionError("Could not find debug info for call to Object.wait(long)");
}
Also used : Call(jdk.vm.ci.code.site.Call) BytecodeFrame(jdk.vm.ci.code.BytecodeFrame) StackLockValue(jdk.vm.ci.code.StackLockValue) Infopoint(jdk.vm.ci.code.site.Infopoint) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod)

Example 5 with BytecodeFrame

use of jdk.vm.ci.code.BytecodeFrame in project graal by oracle.

the class Instance method doState.

private void doState(DebugContext debug, FrameMap frameMap, LIRInstruction op, LIRFrameState state) {
    SubstrateReferenceMap refMap = (SubstrateReferenceMap) state.debugInfo().getReferenceMap();
    /*
         * We want to verify explicit deoptimization entry points, and implicit deoptimization entry
         * points at call sites. Unfortunately, just checking isDeoptEntry gives us false positives
         * for some runtime calls that re-use a state (which is not marked as "during call").
         */
    boolean isDeoptEntry = ((HostedMethod) state.topFrame.getMethod()).compilationInfo.isDeoptEntry(state.topFrame.getBCI(), state.topFrame.duringCall, state.topFrame.rethrowException);
    if (op instanceof DeoptEntryOp || (state.topFrame.duringCall && isDeoptEntry)) {
        BytecodeFrame frame = state.topFrame;
        Map<Integer, Object> allUsedRegisters = refMap.getDebugAllUsedRegisters();
        Map<Integer, Object> allUsedStackSlots = refMap.getDebugAllUsedStackSlots();
        if (allUsedRegisters != null && !allUsedRegisters.isEmpty()) {
            throw shouldNotReachHere("Deoptimization target must not use any registers");
        }
        if (allUsedStackSlots != null) {
            Map<Integer, Object> cleanedStackSlots = new HashMap<>(allUsedStackSlots);
            do {
                /*
                     * Remove stack slot information for all slots which already have a
                     * representative in the bytecode frame.
                     */
                for (JavaValue value : frame.values) {
                    if (value instanceof StackSlot) {
                        StackSlot stackSlot = (StackSlot) value;
                        int offset = stackSlot.getOffset(frameMap.totalFrameSize());
                        debug.log("remove slot %d: %s", offset, stackSlot);
                        cleanedStackSlots.remove(offset);
                    } else if (ValueUtil.isConstantJavaValue(value) || ValueUtil.isIllegalJavaValue(value)) {
                    /* Nothing to do. */
                    } else {
                        throw shouldNotReachHere("unknown value in deopt target: " + value);
                    }
                }
                frame = frame.caller();
            } while (frame != null);
            int firstBci = state.topFrame.getMethod().isSynchronized() ? BytecodeFrame.BEFORE_BCI : 0;
            if (state.topFrame.getBCI() == firstBci && state.topFrame.caller() == null && state.topFrame.duringCall == false && state.topFrame.rethrowException == false) {
                /*
                     * Some stack slots, e.g., the return address and manually allocated stack
                     * memory, are alive the whole method. So all stack slots that are registered
                     * for the method entry are allowed to be registered in all subsequent states.
                     */
                assert op instanceof DeoptEntryOp;
                assert allowedStackSlots == null;
                allowedStackSlots = new HashMap<>(cleanedStackSlots);
            } else {
                if (allowedStackSlots == null) {
                    allowedStackSlots = new HashMap<>();
                }
                for (Integer key : allowedStackSlots.keySet()) {
                    cleanedStackSlots.remove(key);
                }
                if (!cleanedStackSlots.isEmpty()) {
                    throw shouldNotReachHere("unknown values in stack slots: method " + state.topFrame.getMethod().toString() + ", op " + op.id() + " " + op + ": " + cleanedStackSlots);
                }
            }
        }
    }
}
Also used : BytecodeFrame(jdk.vm.ci.code.BytecodeFrame) HashMap(java.util.HashMap) JavaValue(jdk.vm.ci.meta.JavaValue) DeoptEntryOp(com.oracle.svm.core.graal.lir.DeoptEntryOp) StackSlot(jdk.vm.ci.code.StackSlot) SubstrateReferenceMap(com.oracle.svm.core.heap.SubstrateReferenceMap)

Aggregations

BytecodeFrame (jdk.vm.ci.code.BytecodeFrame)10 JavaValue (jdk.vm.ci.meta.JavaValue)3 HashMap (java.util.HashMap)2 DebugInfo (jdk.vm.ci.code.DebugInfo)2 VirtualObject (jdk.vm.ci.code.VirtualObject)2 Call (jdk.vm.ci.code.site.Call)2 Infopoint (jdk.vm.ci.code.site.Infopoint)2 JavaKind (jdk.vm.ci.meta.JavaKind)2 LIRFrameState (org.graalvm.compiler.lir.LIRFrameState)2 ValueInfo (com.oracle.svm.core.code.FrameInfoQueryResult.ValueInfo)1 DeoptEntryInfopoint (com.oracle.svm.core.deopt.DeoptEntryInfopoint)1 DeoptEntryOp (com.oracle.svm.core.graal.lir.DeoptEntryOp)1 SubstrateReferenceMap (com.oracle.svm.core.heap.SubstrateReferenceMap)1 ArrayList (java.util.ArrayList)1 Map (java.util.Map)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 BytecodePosition (jdk.vm.ci.code.BytecodePosition)1 ReferenceMap (jdk.vm.ci.code.ReferenceMap)1 Register (jdk.vm.ci.code.Register)1 StackLockValue (jdk.vm.ci.code.StackLockValue)1