use of com.oracle.svm.core.code.FrameInfoQueryResult.ValueInfo in project graal by oracle.
the class FrameInfoVerifier method makeVirtualObject.
private void makeVirtualObject(FrameData data, VirtualObject virtualObject) {
int id = virtualObject.getId();
if (data.virtualObjects[id] != null) {
return;
}
/* Install a non-null value to support recursive VirtualObjects. */
data.virtualObjects[id] = MARKER;
/* Objects must contain only compressed references when compression is enabled */
boolean compressedRefs = ReferenceAccess.singleton().haveCompressedReferences();
List<ValueInfo> valueList = new ArrayList<>(virtualObject.getValues().length + 4);
SharedType type = (SharedType) virtualObject.getType();
/* The first element is the hub of the virtual object. */
valueList.add(makeValueInfo(data, JavaKind.Object, SubstrateObjectConstant.forObject(type.getHub())));
ObjectLayout objectLayout = ConfigurationValues.getObjectLayout();
assert type.isArray() == LayoutEncoding.isArray(type.getHub().getLayoutEncoding()) : "deoptimization code uses layout encoding to determine if type is an array";
if (type.isArray()) {
/* We do not know the final length yet, so add a placeholder. */
valueList.add(null);
int length = 0;
JavaKind kind = ((SharedType) type.getComponentType()).getStorageKind();
for (int i = 0; i < virtualObject.getValues().length; i++) {
JavaValue value = virtualObject.getValues()[i];
JavaKind valueKind = virtualObject.getSlotKind(i);
if (objectLayout.sizeInBytes(kind, compressedRefs) == 4 && objectLayout.sizeInBytes(valueKind, compressedRefs) == 8) {
/*
* Truffle uses arrays in a non-standard way: it declares an int[] array and
* uses it to also store long and double values. These values span two array
* elements - so we have to write this element with the actual value kind and
* add 2 to the length.
*/
valueList.add(makeValueInfo(data, valueKind, value));
length += 2;
} else {
assert objectLayout.sizeInBytes(valueKind.getStackKind(), compressedRefs) <= objectLayout.sizeInBytes(kind.getStackKind(), compressedRefs);
valueList.add(makeValueInfo(data, kind, value));
length++;
}
assert objectLayout.getArrayElementOffset(type.getComponentType().getJavaKind(), length) == objectLayout.getArrayBaseOffset(type.getComponentType().getJavaKind()) + computeOffset(valueList.subList(2, valueList.size()), compressedRefs);
}
assert valueList.get(1) == null;
valueList.set(1, makeValueInfo(data, JavaKind.Int, JavaConstant.forInt(length)));
} else {
/*
* We must add filling constants for padding, so that values are contiguous. The
* deoptimization code does not have access to field information.
*/
SharedField[] fields = (SharedField[]) type.getInstanceFields(true);
long curOffset = objectLayout.getFirstFieldOffset();
int fieldIdx = 0;
int valueIdx = 0;
while (valueIdx < virtualObject.getValues().length) {
SharedField field = fields[fieldIdx];
fieldIdx += 1;
JavaValue value = virtualObject.getValues()[valueIdx];
JavaKind valueKind = virtualObject.getSlotKind(valueIdx);
valueIdx += 1;
JavaKind kind = field.getStorageKind();
if (objectLayout.sizeInBytes(kind, compressedRefs) == 4 && objectLayout.sizeInBytes(valueKind, compressedRefs) == 8) {
/*
* Truffle uses fields in a non-standard way: it declares a couple of
* (consecutive) int fields, and uses them to also store long and double values.
* These values span two fields - so we have to ignore a field.
*/
kind = valueKind;
assert fields[fieldIdx].getJavaKind() == field.getJavaKind();
fieldIdx++;
}
if (field.getLocation() >= 0) {
assert curOffset <= field.getLocation();
while (curOffset + 7 < field.getLocation()) {
valueList.add(makeValueInfo(data, JavaKind.Long, JavaConstant.LONG_0));
curOffset += 8;
}
if (curOffset + 3 < field.getLocation()) {
valueList.add(makeValueInfo(data, JavaKind.Int, JavaConstant.INT_0));
curOffset += 4;
}
if (curOffset + 1 < field.getLocation()) {
valueList.add(makeValueInfo(data, JavaKind.Short, JavaConstant.forShort((short) 0)));
curOffset += 2;
}
if (curOffset < field.getLocation()) {
valueList.add(makeValueInfo(data, JavaKind.Byte, JavaConstant.forByte((byte) 0)));
curOffset += 1;
}
assert curOffset == field.getLocation();
assert curOffset == computeOffset(valueList, compressedRefs);
valueList.add(makeValueInfo(data, kind, value));
curOffset += objectLayout.sizeInBytes(kind, compressedRefs);
}
}
}
data.virtualObjects[id] = valueList.toArray(new ValueInfo[valueList.size()]);
ImageSingletons.lookup(Counters.class).virtualObjectsCount.inc();
}
use of com.oracle.svm.core.code.FrameInfoQueryResult.ValueInfo in project graal by oracle.
the class FrameInfoVerifier method encodeFrameData.
private void encodeFrameData(FrameData data, UnsafeArrayTypeWriter encodingBuffer) {
for (FrameInfoQueryResult cur = data.frame; cur != null; cur = cur.caller) {
assert cur.encodedBci != FrameInfoDecoder.NO_CALLER_BCI : "used as the end marker during decoding";
final boolean needLocalValues = cur.needLocalValues;
if (!needLocalValues) {
cur.encodedBci = FrameInfoDecoder.NO_LOCAL_INFO_BCI;
}
encodingBuffer.putSV(cur.encodedBci);
assert cur == data.frame || !cur.isDeoptEntry : "Deoptimization entry information for caller frames is not persisted";
if (needLocalValues) {
encodingBuffer.putUV(cur.numLocks);
encodingBuffer.putUV(cur.numLocals);
encodingBuffer.putUV(cur.numStack);
int deoptMethodIndex;
if (cur.deoptMethod != null) {
deoptMethodIndex = -1 - objectConstants.getIndex(SubstrateObjectConstant.forObject(cur.deoptMethod));
assert deoptMethodIndex < 0;
assert cur.deoptMethodOffset == cur.deoptMethod.getDeoptOffsetInImage();
} else {
deoptMethodIndex = cur.deoptMethodOffset;
assert deoptMethodIndex >= 0;
}
encodingBuffer.putSV(deoptMethodIndex);
encodeValues(cur.valueInfos, encodingBuffer);
if (cur == data.frame) {
// Write virtual objects only for first frame.
encodingBuffer.putUV(cur.virtualObjects.length);
for (ValueInfo[] virtualObject : cur.virtualObjects) {
encodeValues(virtualObject, encodingBuffer);
}
}
}
final boolean encodeDebugNames = needLocalValues && FrameInfoDecoder.encodeDebugNames();
if (encodeDebugNames || FrameInfoDecoder.encodeSourceReferences()) {
final int classIndex = sourceClassNames.getIndex(cur.sourceClassName);
final int methodIndex = sourceMethodNames.getIndex(cur.sourceMethodName);
final int fileIndex = sourceFileNames.getIndex(cur.sourceFileName);
cur.sourceClassNameIndex = classIndex;
cur.sourceMethodNameIndex = methodIndex;
cur.sourceFileNameIndex = fileIndex;
encodingBuffer.putSV(classIndex);
encodingBuffer.putSV(methodIndex);
encodingBuffer.putSV(fileIndex);
encodingBuffer.putSV(cur.sourceLineNumber);
}
if (encodeDebugNames) {
for (ValueInfo valueInfo : cur.valueInfos) {
valueInfo.nameIndex = names.getIndex(valueInfo.name);
encodingBuffer.putUV(valueInfo.nameIndex);
}
}
}
encodingBuffer.putSV(FrameInfoDecoder.NO_CALLER_BCI);
}
use of com.oracle.svm.core.code.FrameInfoQueryResult.ValueInfo in project graal by oracle.
the class Deoptimizer method materializeObject.
/**
* Materializes a virtual object.
*
* @param virtualObjectId the id of the virtual object to materialize
* @return the materialized object
*/
private Object materializeObject(int virtualObjectId, FrameInfoQueryResult sourceFrame) {
if (materializedObjects == null) {
materializedObjects = new Object[sourceFrame.getVirtualObjects().length];
}
assert materializedObjects.length == sourceFrame.getVirtualObjects().length;
Object obj = materializedObjects[virtualObjectId];
if (obj != null) {
return obj;
}
DeoptimizationCounters.counters().virtualObjectsCount.inc();
ValueInfo[] encodings = sourceFrame.getVirtualObjects()[virtualObjectId];
DynamicHub hub = KnownIntrinsics.convertUnknownValue(SubstrateObjectConstant.asObject(readValue(encodings[0], sourceFrame)), DynamicHub.class);
ObjectLayout objectLayout = ConfigurationValues.getObjectLayout();
int curIdx;
UnsignedWord curOffset;
if (LayoutEncoding.isArray(hub.getLayoutEncoding())) {
/* For arrays, the second encoded value is the array length. */
int length = readValue(encodings[1], sourceFrame).asInt();
obj = Array.newInstance(hub.getComponentHub().asClass(), length);
curOffset = LayoutEncoding.getArrayBaseOffset(hub.getLayoutEncoding());
curIdx = 2;
} else {
try {
obj = UnsafeAccess.UNSAFE.allocateInstance(hub.asClass());
} catch (InstantiationException ex) {
throw VMError.shouldNotReachHere(ex);
}
curOffset = WordFactory.unsigned(objectLayout.getFirstFieldOffset());
curIdx = 1;
}
materializedObjects[virtualObjectId] = obj;
if (testGCinDeoptimizer) {
Heap.getHeap().getGC().collect("from Deoptimizer.materializeObject because of testGCinDeoptimizer");
}
/* Objects must contain only compressed references when compression is enabled */
boolean useCompressedReferences = ReferenceAccess.singleton().haveCompressedReferences();
while (curIdx < encodings.length) {
ValueInfo value = encodings[curIdx];
JavaKind kind = value.getKind();
JavaConstant con = readValue(value, sourceFrame);
writeValueInMaterializedObj(obj, curOffset, con);
curOffset = curOffset.add(objectLayout.sizeInBytes(kind, useCompressedReferences));
curIdx++;
}
return obj;
}
Aggregations