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();
}
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);
}
}
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);
}
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)");
}
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);
}
}
}
}
}
Aggregations