use of com.oracle.svm.core.code.FrameInfoQueryResult.ValueInfo in project graal by oracle.
the class Deoptimizer method constructTargetFrame.
/**
* Constructs the frame entries for the deopimization target method.
*
* @param targetInfo The bytecode frame (+ some other info) of the target.
* @param sourceFrame The bytecode frame of the source.
*/
private VirtualFrame constructTargetFrame(CodeInfoQueryResult targetInfo, FrameInfoQueryResult sourceFrame) {
FrameInfoQueryResult targetFrame = targetInfo.getFrameInfo();
long targetFrameSize = targetInfo.getTotalFrameSize() - FrameAccess.returnAddressSize();
VirtualFrame result = new VirtualFrame(targetFrame);
/* The first word of the new content is the return address into the target method. */
result.returnAddress = new DeoptimizedFrame.ReturnAddress(targetContentSize, targetInfo.getIP().rawValue());
targetContentSize += FrameAccess.returnAddressSize();
/* The source and target bytecode frame must match (as they stem from the same BCI). */
assert sourceFrame.getNumLocals() == targetFrame.getNumLocals();
assert sourceFrame.getNumStack() == targetFrame.getNumStack();
assert sourceFrame.getNumLocks() == targetFrame.getNumLocks();
assert targetFrame.getVirtualObjects().length == 0;
assert sourceFrame.getValueInfos().length >= targetFrame.getValueInfos().length;
int numValues = targetFrame.getValueInfos().length;
/*
* Create stack entries for all values of the source frame.
*/
int newEndOfParams = endOfParams;
for (int idx = 0; idx < numValues; idx++) {
ValueInfo targetValue = targetFrame.getValueInfos()[idx];
if (targetValue.getKind() == JavaKind.Illegal) {
/*
* The target value is optimized out, e.g. at a position after the lifetime of a
* local variable. Actually we don't care what's the source value in this case, but
* most likely it's also "illegal".
*/
} else {
JavaConstant con = readValue(sourceFrame.getValueInfos()[idx], sourceFrame);
assert con.getJavaKind() != JavaKind.Illegal;
if (con.getJavaKind().isObject() && SubstrateObjectConstant.isCompressed(con) != targetValue.isCompressedReference()) {
// rewrap in constant with the appropriate compression for the target value
Object obj = SubstrateObjectConstant.asObject(con);
con = SubstrateObjectConstant.forObject(obj, targetValue.isCompressedReference());
}
relockVirtualObject(sourceFrame, idx, con);
switch(targetValue.getType()) {
case StackSlot:
/*
* The target value is on the stack
*/
DeoptimizationCounters.counters().stackValueCount.inc();
int targetOffset = TypeConversion.asS4(targetValue.getData());
assert targetOffset != targetFrameSize : "stack slot would overwrite return address";
int totalOffset = targetContentSize + targetOffset;
assert totalOffset >= endOfParams : "stack location overwrites param area";
if (targetOffset < targetFrameSize) {
/*
* This is the most common case: a regular slot in the stack frame,
* which e.g. holds a variable.
*/
assert totalOffset >= targetContentSize;
result.values[idx] = DeoptimizedFrame.ConstantEntry.factory(totalOffset, con);
} else if (sourceFrame.getCaller() != null) {
/*
* Handle stack parameters for inlined calls: write the value to the
* outgoing parameter area of the caller frame.
*/
assert totalOffset >= targetContentSize;
result.values[idx] = DeoptimizedFrame.ConstantEntry.factory(totalOffset, con);
int endOffset = totalOffset + ConfigurationValues.getObjectLayout().sizeInBytes(con.getJavaKind(), targetValue.isCompressedReference());
if (endOffset > newEndOfParams) {
newEndOfParams = endOffset;
}
}
break;
case DefaultConstant:
case Constant:
/*
* The target value was constant propagated. Check that source and target
* performed the same constant propagation
*/
assert verifyConstant(targetFrame, targetValue, con);
DeoptimizationCounters.counters().constantValueCount.inc();
break;
default:
/*
* There must not be any other target value types because deoptimization
* target methods are only optimized in a limited way. Especially there must
* not be Register values because registers cannot be alive across method
* calls; and there must not be virtual objects because no escape analysis
* is performed.
*/
throw VMError.shouldNotReachHere("unknown deopt target value " + targetValue);
}
}
}
targetContentSize += targetFrameSize;
endOfParams = newEndOfParams;
return result;
}
use of com.oracle.svm.core.code.FrameInfoQueryResult.ValueInfo in project graal by oracle.
the class Deoptimizer method relockVirtualObject.
/**
* Locks re-materialized virtual objects in the deoptimization target.
*/
private void relockVirtualObject(FrameInfoQueryResult sourceFrame, int valueInfoIndex, JavaConstant valueConstant) {
ValueInfo valueInfo = sourceFrame.getValueInfos()[valueInfoIndex];
if (SubstrateOptions.MultiThreaded.getValue() && valueInfoIndex >= sourceFrame.getNumLocals() + sourceFrame.getNumStack() && valueInfo.getType() == ValueType.VirtualObject) {
Object lockee = KnownIntrinsics.convertUnknownValue(SubstrateObjectConstant.asObject(valueConstant), Object.class);
int lockeeIndex = TypeConversion.asS4(valueInfo.getData());
assert lockee == materializedObjects[lockeeIndex];
MonitorSupport.monitorEnter(lockee);
if (relockedObjects == null) {
relockedObjects = new Object[sourceFrame.getVirtualObjects().length];
}
assert relockedObjects[lockeeIndex] == null || relockedObjects[lockeeIndex] == lockee;
relockedObjects[lockeeIndex] = lockee;
}
}
use of com.oracle.svm.core.code.FrameInfoQueryResult.ValueInfo in project graal by oracle.
the class FrameInfoVerifier method verifyValues.
private static void verifyValues(ValueInfo[] expectedValues, ValueInfo[] actualValues) {
assert expectedValues.length == actualValues.length;
for (int i = 0; i < expectedValues.length; i++) {
ValueInfo expectedValue = expectedValues[i];
ValueInfo actualValue = actualValues[i];
assert expectedValue.type == actualValue.type;
assert expectedValue.kind.equals(actualValue.kind);
assert expectedValue.isCompressedReference == actualValue.isCompressedReference;
assert expectedValue.data == actualValue.data;
verifyConstant(expectedValue.value, actualValue.value);
assert Objects.equals(expectedValue.name, actualValue.name);
assert expectedValue.nameIndex == actualValue.nameIndex;
}
}
use of com.oracle.svm.core.code.FrameInfoQueryResult.ValueInfo in project graal by oracle.
the class FrameInfoVerifier method addFrame.
private FrameInfoQueryResult addFrame(FrameData data, BytecodeFrame frame, boolean isDeoptEntry, boolean needLocalValues) {
FrameInfoQueryResult result = new FrameInfoQueryResult();
if (frame.caller() != null) {
assert !isDeoptEntry : "Deoptimization entry point information for caller frames is not encoded";
result.caller = addFrame(data, frame.caller(), false, needLocalValues);
}
result.virtualObjects = data.virtualObjects;
result.encodedBci = encodeBci(frame.getBCI(), frame.duringCall, frame.rethrowException);
result.isDeoptEntry = isDeoptEntry;
result.needLocalValues = needLocalValues;
SharedMethod method = (SharedMethod) frame.getMethod();
if (customization.shouldStoreMethod()) {
result.deoptMethod = method;
objectConstants.addObject(SubstrateObjectConstant.forObject(method));
}
result.deoptMethodOffset = method.getDeoptOffsetInImage();
result.numLocals = frame.numLocals;
result.numStack = frame.numStack;
result.numLocks = frame.numLocks;
ValueInfo[] valueInfos = null;
if (needLocalValues) {
JavaValue[] values = frame.values;
int numValues = 0;
for (int i = values.length; --i >= 0; ) {
if (!ValueUtil.isIllegalJavaValue(values[i])) {
// Found the last non-illegal value, i.e., the last value we have to encode.
numValues = i + 1;
break;
}
}
valueInfos = new ValueInfo[numValues];
for (int i = 0; i < numValues; i++) {
valueInfos[i] = makeValueInfo(data, getFrameValueKind(frame, i), values[i]);
}
}
result.valueInfos = valueInfos;
ImageSingletons.lookup(Counters.class).frameCount.inc();
return result;
}
use of com.oracle.svm.core.code.FrameInfoQueryResult.ValueInfo in project graal by oracle.
the class CollectingObjectReferenceVisitor method verifyFrame.
private void verifyFrame(CompilationResult compilation, BytecodeFrame expectedFrame, FrameInfoQueryResult actualFrame, BitSet visitedVirtualObjects) {
assert (expectedFrame == null) == (actualFrame == null);
if (expectedFrame == null || !actualFrame.needLocalValues) {
return;
}
verifyFrame(compilation, expectedFrame.caller(), actualFrame.getCaller(), visitedVirtualObjects);
for (int i = 0; i < expectedFrame.values.length; i++) {
JavaValue expectedValue = expectedFrame.values[i];
if (i >= actualFrame.getValueInfos().length) {
assert ValueUtil.isIllegalJavaValue(expectedValue);
continue;
}
ValueInfo actualValue = actualFrame.getValueInfos()[i];
JavaKind expectedKind = FrameInfoEncoder.getFrameValueKind(expectedFrame, i);
assert expectedKind == actualValue.getKind();
verifyValue(compilation, expectedValue, actualValue, actualFrame, visitedVirtualObjects);
}
}
Aggregations