use of com.oracle.svm.core.meta.SharedType in project graal by oracle.
the class SubstrateObjectCloneNode method genLoadFieldNode.
@Override
protected LoadFieldNode genLoadFieldNode(Assumptions assumptions, ValueNode originalAlias, ResolvedJavaField field) {
if (field.getJavaKind() == JavaKind.Object && field.getType() instanceof SharedType) {
/*
* We have the static analysis to check interface types, e.g.., if a parameter of field
* has a declared interface type and is assigned something that does not implement the
* interface, the static analysis reports an error.
*/
TypeReference trusted = TypeReference.createTrustedWithoutAssumptions((SharedType) field.getType());
StampPair pair = StampPair.createSingle(StampFactory.object(trusted, false));
return LoadFieldNode.createOverrideStamp(pair, originalAlias, field);
} else {
return super.genLoadFieldNode(assumptions, originalAlias, field);
}
}
use of com.oracle.svm.core.meta.SharedType in project graal by oracle.
the class CollectingObjectReferenceVisitor method verifyVirtualObject.
private void verifyVirtualObject(CompilationResult compilation, VirtualObject expectedObject, ValueInfo[] actualObject, FrameInfoQueryResult actualFrame, BitSet visitedVirtualObjects) {
if (visitedVirtualObjects.get(expectedObject.getId())) {
return;
}
visitedVirtualObjects.set(expectedObject.getId());
ObjectLayout objectLayout = ConfigurationValues.getObjectLayout();
SharedType expectedType = (SharedType) expectedObject.getType();
if (expectedType.isArray()) {
JavaKind kind = expectedType.getComponentType().getJavaKind();
int expectedLength = 0;
for (int i = 0; i < expectedObject.getValues().length; i++) {
JavaValue expectedValue = expectedObject.getValues()[i];
UnsignedWord expectedOffset = WordFactory.unsigned(objectLayout.getArrayElementOffset(expectedType.getComponentType().getJavaKind(), expectedLength));
ValueInfo actualValue = findActualArrayElement(actualObject, expectedOffset);
verifyValue(compilation, expectedValue, actualValue, actualFrame, visitedVirtualObjects);
JavaKind valueKind = expectedObject.getSlotKind(i);
if (objectLayout.sizeInBytes(kind) == 4 && objectLayout.sizeInBytes(valueKind) == 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 add 2 to the length.
*/
expectedLength += 2;
} else {
expectedLength++;
}
}
int actualLength = actualObject[1].value.asInt();
assert expectedLength == actualLength;
} else {
SharedField[] expectedFields = (SharedField[]) expectedType.getInstanceFields(true);
int fieldIdx = 0;
int valueIdx = 0;
while (valueIdx < expectedObject.getValues().length) {
SharedField expectedField = expectedFields[fieldIdx];
fieldIdx += 1;
JavaValue expectedValue = expectedObject.getValues()[valueIdx];
JavaKind valueKind = expectedObject.getSlotKind(valueIdx);
valueIdx += 1;
JavaKind kind = expectedField.getStorageKind();
if (objectLayout.sizeInBytes(kind) == 4 && objectLayout.sizeInBytes(valueKind) == 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.
*/
fieldIdx++;
}
UnsignedWord expectedOffset = WordFactory.unsigned(expectedField.getLocation());
ValueInfo actualValue = findActualField(actualObject, expectedOffset);
verifyValue(compilation, expectedValue, actualValue, actualFrame, visitedVirtualObjects);
}
}
}
use of com.oracle.svm.core.meta.SharedType 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();
}
Aggregations