diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageHeapConstant.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageHeapConstant.java index 7f95b1f88e6d..13448acb5b1c 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageHeapConstant.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageHeapConstant.java @@ -96,7 +96,7 @@ abstract static class ConstantData { */ private boolean isInBaseLayer; - ConstantData(AnalysisType type, JavaConstant hostedObject, int identityHashCode) { + ConstantData(AnalysisType type, JavaConstant hostedObject, int identityHashCode, int id) { Objects.requireNonNull(type); this.type = type; this.hostedObject = CompressibleConstant.uncompress(hostedObject); @@ -117,7 +117,7 @@ abstract static class ConstantData { /* This value must never be used later on. */ this.identityHashCode = -1; } - this.id = currentId.getAndIncrement(); + this.id = id == -1 ? currentId.getAndIncrement() : id; } @Override @@ -206,6 +206,14 @@ public boolean isBackedByHostedObject() { return constantData.hostedObject != null; } + public static int getCurrentId() { + return currentId.get(); + } + + public static void setCurrentId(int id) { + currentId.set(id); + } + public static int getConstantID(ImageHeapConstant constant) { return constant.getConstantData().id; } diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageHeapInstance.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageHeapInstance.java index dc8298f85f39..ce2a2eac840f 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageHeapInstance.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageHeapInstance.java @@ -70,23 +70,23 @@ private static final class InstanceData extends ConstantData { */ private Object[] fieldValues; - private InstanceData(AnalysisType type, JavaConstant hostedObject, Object[] fieldValues, int identityHashCode) { - super(type, hostedObject, identityHashCode); + private InstanceData(AnalysisType type, JavaConstant hostedObject, Object[] fieldValues, int identityHashCode, int id) { + super(type, hostedObject, identityHashCode, id); this.fieldValues = fieldValues; assert !type.isArray() : type; } } ImageHeapInstance(AnalysisType type, JavaConstant hostedObject) { - this(type, hostedObject, -1); + this(type, hostedObject, -1, -1); } - ImageHeapInstance(AnalysisType type, JavaConstant hostedObject, int identityHashCode) { - super(new InstanceData(type, hostedObject, null, identityHashCode), false); + ImageHeapInstance(AnalysisType type, JavaConstant hostedObject, int identityHashCode, int id) { + super(new InstanceData(type, hostedObject, null, identityHashCode, id), false); } public ImageHeapInstance(AnalysisType type) { - super(new InstanceData(type, null, new Object[type.getInstanceFields(true).length], -1), false); + super(new InstanceData(type, null, new Object[type.getInstanceFields(true).length], -1, -1), false); } private ImageHeapInstance(ConstantData data, boolean compressed) { @@ -184,6 +184,6 @@ public ImageHeapConstant forObjectClone() { Objects.requireNonNull(fieldValues, "Cannot clone an instance before the field values are set."); Object[] newFieldValues = Arrays.copyOf(fieldValues, fieldValues.length); /* The new constant is never backed by a hosted object, regardless of the input object. */ - return new ImageHeapInstance(new InstanceData(constantData.type, null, newFieldValues, -1), compressed); + return new ImageHeapInstance(new InstanceData(constantData.type, null, newFieldValues, -1, -1), compressed); } } diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageHeapObjectArray.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageHeapObjectArray.java index e87e85a3508f..108555de0b9f 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageHeapObjectArray.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageHeapObjectArray.java @@ -59,8 +59,8 @@ private static final class ObjectArrayData extends ConstantData { final int length; - private ObjectArrayData(AnalysisType type, JavaConstant hostedObject, Object[] arrayElementValues, int length, int identityHashCode) { - super(type, hostedObject, identityHashCode); + private ObjectArrayData(AnalysisType type, JavaConstant hostedObject, Object[] arrayElementValues, int length, int identityHashCode, int id) { + super(type, hostedObject, identityHashCode, id); this.arrayElementValues = arrayElementValues; this.length = length; assert type.isArray() && !type.getComponentType().isPrimitive() : type; @@ -68,19 +68,19 @@ private ObjectArrayData(AnalysisType type, JavaConstant hostedObject, Object[] a } ImageHeapObjectArray(AnalysisType type, JavaConstant hostedObject, int length) { - this(type, hostedObject, length, -1); + this(type, hostedObject, length, -1, -1); } - ImageHeapObjectArray(AnalysisType type, JavaConstant hostedObject, int length, int identityHashCode) { - super(new ObjectArrayData(type, hostedObject, null, length, identityHashCode), false); + ImageHeapObjectArray(AnalysisType type, JavaConstant hostedObject, int length, int identityHashCode, int id) { + super(new ObjectArrayData(type, hostedObject, null, length, identityHashCode, id), false); } - ImageHeapObjectArray(AnalysisType type, JavaConstant hostedObject, Object[] arrayElementValues, int identityHashCode) { - super(new ObjectArrayData(type, hostedObject, arrayElementValues, arrayElementValues.length, identityHashCode), false); + ImageHeapObjectArray(AnalysisType type, JavaConstant hostedObject, Object[] arrayElementValues, int identityHashCode, int id) { + super(new ObjectArrayData(type, hostedObject, arrayElementValues, arrayElementValues.length, identityHashCode, id), false); } ImageHeapObjectArray(AnalysisType type, int length) { - super(new ObjectArrayData(type, null, new Object[length], length, -1), false); + super(new ObjectArrayData(type, null, new Object[length], length, -1, -1), false); } private ImageHeapObjectArray(ConstantData data, boolean compressed) { @@ -98,7 +98,7 @@ void setElementValues(Object[] elementValues) { } public static ImageHeapObjectArray createUnbackedImageHeapArray(AnalysisType type, Object[] elementValues) { - return new ImageHeapObjectArray(type, null, elementValues, -1); + return new ImageHeapObjectArray(type, null, elementValues, -1, -1); } /** @@ -168,6 +168,6 @@ public ImageHeapConstant forObjectClone() { Objects.requireNonNull(arrayElements, "Cannot clone an array before the element values are set."); Object[] newArrayElementValues = Arrays.copyOf(arrayElements, arrayElements.length); /* The new constant is never backed by a hosted object, regardless of the input object. */ - return new ImageHeapObjectArray(new ObjectArrayData(constantData.type, null, newArrayElementValues, arrayElements.length, -1), compressed); + return new ImageHeapObjectArray(new ObjectArrayData(constantData.type, null, newArrayElementValues, arrayElements.length, -1, -1), compressed); } } diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageHeapPrimitiveArray.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageHeapPrimitiveArray.java index 9dfe24c3bbe7..e664bb1c10e9 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageHeapPrimitiveArray.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageHeapPrimitiveArray.java @@ -41,8 +41,8 @@ private static final class PrimitiveArrayData extends ConstantData { private final Object array; private final int length; - private PrimitiveArrayData(AnalysisType type, JavaConstant hostedObject, Object array, int length, int identityHashCode) { - super(type, hostedObject, identityHashCode); + private PrimitiveArrayData(AnalysisType type, JavaConstant hostedObject, Object array, int length, int identityHashCode, int id) { + super(type, hostedObject, identityHashCode, id); this.array = array; this.length = length; assert type.isArray() && type.getComponentType().isPrimitive() : type; @@ -53,18 +53,18 @@ private PrimitiveArrayData(AnalysisType type, JavaConstant hostedObject, Object super(new PrimitiveArrayData(type, null, /* Without a hosted object, we need to create a backing primitive array. */ Array.newInstance(type.getComponentType().getStorageKind().toJavaClass(), length), - length, -1), false); + length, -1, -1), false); } ImageHeapPrimitiveArray(AnalysisType type, JavaConstant hostedObject, Object array, int length) { - this(type, hostedObject, array, length, -1); + this(type, hostedObject, array, length, -1, -1); } - ImageHeapPrimitiveArray(AnalysisType type, JavaConstant hostedObject, Object array, int length, int identityHashCode) { + ImageHeapPrimitiveArray(AnalysisType type, JavaConstant hostedObject, Object array, int length, int identityHashCode, int id) { super(new PrimitiveArrayData(type, hostedObject, /* We need a clone of the hosted array so that we have a stable snapshot. */ getClone(type.getComponentType().getJavaKind(), array), - length, identityHashCode), false); + length, identityHashCode, id), false); } private ImageHeapPrimitiveArray(ConstantData constantData, boolean compressed) { @@ -140,6 +140,6 @@ public ImageHeapConstant forObjectClone() { PrimitiveArrayData data = getConstantData(); Object newArray = getClone(data.type.getComponentType().getJavaKind(), data.array); /* The new constant is never backed by a hosted object, regardless of the input object. */ - return new ImageHeapPrimitiveArray(new PrimitiveArrayData(data.type, null, newArray, data.length, -1), compressed); + return new ImageHeapPrimitiveArray(new PrimitiveArrayData(data.type, null, newArray, data.length, -1, -1), compressed); } } diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageHeapRelocatableConstant.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageHeapRelocatableConstant.java index 860cceb951cc..cb3658d05ba2 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageHeapRelocatableConstant.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageHeapRelocatableConstant.java @@ -39,8 +39,8 @@ public final class ImageHeapRelocatableConstant extends ImageHeapConstant { public static final class RelocatableConstantData extends ConstantData { public final String key; - RelocatableConstantData(AnalysisType type, String key) { - super(type, null, -1); + RelocatableConstantData(AnalysisType type, String key, int id) { + super(type, null, -1, id); this.key = key; } } @@ -54,11 +54,15 @@ public RelocatableConstantData getConstantData() { return (RelocatableConstantData) constantData; } - public static ImageHeapRelocatableConstant create(AnalysisType type, String key) { - var data = new RelocatableConstantData(type, key); + public static ImageHeapRelocatableConstant create(AnalysisType type, String key, int id) { + var data = new RelocatableConstantData(type, key, id); return new ImageHeapRelocatableConstant(data, false); } + public static ImageHeapRelocatableConstant create(AnalysisType type, String key) { + return create(type, key, -1); + } + @Override public JavaConstant compress() { throw AnalysisError.shouldNotReachHere("Unsupported in ImageHeapRelocatableConstant"); diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageLayerLoader.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageLayerLoader.java index ab256b1e13d2..7494e0d1ec54 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageLayerLoader.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageLayerLoader.java @@ -81,6 +81,7 @@ import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.METHOD_HANDLE_INTRINSIC_TAG; import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.MODIFIERS_TAG; import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.NAME_TAG; +import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.NEXT_CONSTANT_ID_TAG; import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.NEXT_FIELD_ID_TAG; import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.NEXT_METHOD_ID_TAG; import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.NEXT_TYPE_ID_TAG; @@ -425,6 +426,9 @@ private void loadLayerAnalysis0() { int nextFieldId = get(jsonMap, NEXT_FIELD_ID_TAG); universe.setStartFieldId(nextFieldId); + int nextConstantId = get(jsonMap, NEXT_CONSTANT_ID_TAG); + ImageHeapConstant.setCurrentId(nextConstantId); + imageHeapSize = Long.parseLong(get(jsonMap, IMAGE_HEAP_SIZE_TAG)); storeIdToIdentifier(TYPES_TAG, typeIdToIdentifier); @@ -1115,7 +1119,7 @@ protected ImageHeapConstant getOrCreateConstant(EconomicMap cons } addBaseLayerObject(id, objectOffset, () -> { - ImageHeapInstance imageHeapInstance = new ImageHeapInstance(type, foundHostedObject == null ? parentReachableHostedObject : foundHostedObject, identityHashCode); + ImageHeapInstance imageHeapInstance = new ImageHeapInstance(type, foundHostedObject == null ? parentReachableHostedObject : foundHostedObject, identityHashCode, id); if (instanceData != null) { Object[] fieldValues = getReferencedValues(constantsMap, imageHeapInstance, instanceData, imageLayerSnapshotUtil.getRelinkedFields(type, metaAccess)); imageHeapInstance.setFieldValues(fieldValues); @@ -1126,7 +1130,7 @@ protected ImageHeapConstant getOrCreateConstant(EconomicMap cons case ARRAY_TAG -> { List> arrayData = get(baseLayerConstant, DATA_TAG); addBaseLayerObject(id, objectOffset, () -> { - ImageHeapObjectArray imageHeapObjectArray = new ImageHeapObjectArray(type, null, arrayData.size(), identityHashCode); + ImageHeapObjectArray imageHeapObjectArray = new ImageHeapObjectArray(type, null, arrayData.size(), identityHashCode, id); Object[] elementsValues = getReferencedValues(constantsMap, imageHeapObjectArray, arrayData, Set.of()); imageHeapObjectArray.setElementValues(elementsValues); return imageHeapObjectArray; @@ -1135,11 +1139,11 @@ protected ImageHeapConstant getOrCreateConstant(EconomicMap cons case PRIMITIVE_ARRAY_TAG -> { List primitiveData = get(baseLayerConstant, DATA_TAG); Object array = getArray(type.getComponentType().getJavaKind(), primitiveData); - addBaseLayerObject(id, objectOffset, () -> new ImageHeapPrimitiveArray(type, null, array, primitiveData.size(), identityHashCode)); + addBaseLayerObject(id, objectOffset, () -> new ImageHeapPrimitiveArray(type, null, array, primitiveData.size(), identityHashCode, id)); } case RELOCATED_CONSTANT_TAG -> { String key = get(baseLayerConstant, DATA_TAG); - addBaseLayerObject(id, objectOffset, () -> ImageHeapRelocatableConstant.create(type, key)); + addBaseLayerObject(id, objectOffset, () -> ImageHeapRelocatableConstant.create(type, key, id)); } default -> throw GraalError.shouldNotReachHere("Unknown constant type: " + constantType); } diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageLayerSnapshotUtil.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageLayerSnapshotUtil.java index a8ef074e6de2..70e6e39fbd37 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageLayerSnapshotUtil.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageLayerSnapshotUtil.java @@ -169,6 +169,7 @@ public class ImageLayerSnapshotUtil { public static final String NEXT_TYPE_ID_TAG = "next type id"; public static final String NEXT_METHOD_ID_TAG = "next method id"; public static final String NEXT_FIELD_ID_TAG = "next field id"; + public static final String NEXT_CONSTANT_ID_TAG = "next constant id"; public static final String IMAGE_HEAP_SIZE_TAG = "image heap size"; public static final String VALUE_TAG = "value"; public static final String ENUM_CLASS_TAG = "enum class"; diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageLayerWriter.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageLayerWriter.java index b23089b4361c..0844e76d51b7 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageLayerWriter.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageLayerWriter.java @@ -77,6 +77,7 @@ import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.METHOD_HANDLE_INTRINSIC_TAG; import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.MODIFIERS_TAG; import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.NAME_TAG; +import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.NEXT_CONSTANT_ID_TAG; import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.NEXT_FIELD_ID_TAG; import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.NEXT_METHOD_ID_TAG; import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.NEXT_TYPE_ID_TAG; @@ -281,6 +282,7 @@ public void persistAnalysisInfo() { jsonMap.put(NEXT_TYPE_ID_TAG, aUniverse.getNextTypeId()); jsonMap.put(NEXT_METHOD_ID_TAG, aUniverse.getNextMethodId()); jsonMap.put(NEXT_FIELD_ID_TAG, aUniverse.getNextFieldId()); + jsonMap.put(NEXT_CONSTANT_ID_TAG, ImageHeapConstant.getCurrentId()); for (AnalysisType type : aUniverse.getTypes().stream().filter(AnalysisType::isTrackedAcrossLayers).toList()) { checkTypeStability(type);