Skip to content

Commit 8637bb7

Browse files
committed
Add future heap constant logic to crosslayerconstant registry.
1 parent 2537416 commit 8637bb7

34 files changed

+1136
-180
lines changed

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/context/object/ConstantContextSensitiveObject.java

+2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import java.util.List;
2929

3030
import com.oracle.graal.pointsto.PointsToAnalysis;
31+
import com.oracle.graal.pointsto.heap.ImageHeapRelocatableConstant;
3132
import com.oracle.graal.pointsto.meta.AnalysisType;
3233

3334
import jdk.vm.ci.meta.JavaConstant;
@@ -75,6 +76,7 @@ public ConstantContextSensitiveObject(PointsToAnalysis bb, AnalysisType type) {
7576
public ConstantContextSensitiveObject(PointsToAnalysis bb, AnalysisType type, JavaConstant constant) {
7677
super(bb.getUniverse(), type, AnalysisObjectKind.ConstantContextSensitive);
7778
assert bb.trackConcreteAnalysisObjects(type) : type;
79+
assert !(constant instanceof ImageHeapRelocatableConstant) : "relocatable constants have an unknown state and should not be represented by a constant type state: " + constant;
7880
this.constant = constant;
7981
bb.profileConstantObject(type);
8082
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*
2+
* Copyright (c) 2024, 2024, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package com.oracle.graal.pointsto.heap;
26+
27+
import com.oracle.graal.pointsto.meta.AnalysisType;
28+
import com.oracle.graal.pointsto.util.AnalysisError;
29+
30+
import jdk.vm.ci.meta.JavaConstant;
31+
32+
/**
33+
* Used for layered images only. Represents a reference to an object which will be defined in a
34+
* later layer. References to these constants will be patched at execution startup time to point to
35+
* the corresponding object created in a subsequent layer.
36+
*/
37+
public final class ImageHeapRelocatableConstant extends ImageHeapConstant {
38+
39+
public static final class RelocatableConstantData extends ConstantData {
40+
public final String key;
41+
42+
RelocatableConstantData(AnalysisType type, String key) {
43+
super(type, null, -1);
44+
this.key = key;
45+
}
46+
}
47+
48+
private ImageHeapRelocatableConstant(ConstantData constantData, boolean compressed) {
49+
super(constantData, compressed);
50+
}
51+
52+
@Override
53+
public RelocatableConstantData getConstantData() {
54+
return (RelocatableConstantData) constantData;
55+
}
56+
57+
public static ImageHeapRelocatableConstant create(AnalysisType type, String key) {
58+
var data = new RelocatableConstantData(type, key);
59+
return new ImageHeapRelocatableConstant(data, false);
60+
}
61+
62+
@Override
63+
public JavaConstant compress() {
64+
throw AnalysisError.shouldNotReachHere("Unsupported in ImageHeapRelocatableConstant");
65+
}
66+
67+
@Override
68+
public JavaConstant uncompress() {
69+
throw AnalysisError.shouldNotReachHere("Unsupported in ImageHeapRelocatableConstant");
70+
}
71+
72+
@Override
73+
public ImageHeapConstant forObjectClone() {
74+
throw AnalysisError.shouldNotReachHere("Unsupported in ImageHeapRelocatableConstant");
75+
}
76+
}

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageHeapScanner.java

+9
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,10 @@ private void onInstanceFieldRead(AnalysisField field, AnalysisType type) {
159159
for (AnalysisType subtype : type.getSubTypes()) {
160160
for (ImageHeapConstant imageHeapConstant : imageHeap.getReachableObjects(subtype)) {
161161
FieldScan reason = new FieldScan(field, imageHeapConstant);
162+
if (imageHeapConstant instanceof ImageHeapRelocatableConstant) {
163+
// This constant has no contents to be scanned.
164+
continue;
165+
}
162166
ImageHeapInstance imageHeapInstance = (ImageHeapInstance) imageHeapConstant;
163167
updateInstanceField(field, imageHeapInstance, reason, null);
164168
}
@@ -603,6 +607,11 @@ protected void onObjectReachable(ImageHeapConstant imageHeapConstant, ScanReason
603607
updateInstanceField(field, imageHeapInstance, new FieldScan(field, imageHeapInstance, reason), onAnalysisModified);
604608
}
605609
}
610+
} else if (imageHeapConstant instanceof ImageHeapRelocatableConstant) {
611+
/*
612+
* Currently we expect any type registration needed for ImageHeapRelocatableConstants to
613+
* be manually implemented by the user.
614+
*/
606615
}
607616
}
608617

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageLayerLoader.java

+5
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@
9191
import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.POSITION_TAG;
9292
import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.PRIMITIVE_ARRAY_TAG;
9393
import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.RETURN_TYPE_TAG;
94+
import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.RELOCATED_CONSTANT_TAG;
9495
import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.SIMULATED_TAG;
9596
import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.SOURCE_FILE_NAME_TAG;
9697
import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.STATIC_OBJECT_FIELDS_TAG;
@@ -1098,6 +1099,10 @@ protected ImageHeapConstant getOrCreateConstant(EconomicMap<String, Object> cons
10981099
Object array = getArray(type.getComponentType().getJavaKind(), primitiveData);
10991100
addBaseLayerObject(id, objectOffset, () -> new ImageHeapPrimitiveArray(type, null, array, primitiveData.size(), identityHashCode));
11001101
}
1102+
case RELOCATED_CONSTANT_TAG -> {
1103+
String key = get(baseLayerConstant, DATA_TAG);
1104+
addBaseLayerObject(id, objectOffset, () -> ImageHeapRelocatableConstant.create(type, key));
1105+
}
11011106
default -> throw GraalError.shouldNotReachHere("Unknown constant type: " + constantType);
11021107
}
11031108

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageLayerSnapshotUtil.java

+1
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ public class ImageLayerSnapshotUtil {
140140
public static final String INSTANCE_TAG = "instance";
141141
public static final String ARRAY_TAG = "array";
142142
public static final String PRIMITIVE_ARRAY_TAG = "primitive array";
143+
public static final String RELOCATED_CONSTANT_TAG = "relocation constant";
143144
public static final String FIELD_ACCESSED_TAG = "accessed";
144145
public static final String FIELD_READ_TAG = "read";
145146
public static final String FIELD_WRITTEN_TAG = "written";

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageLayerWriter.java

+5
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@
8585
import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.POSITION_TAG;
8686
import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.PRIMITIVE_ARRAY_TAG;
8787
import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.RETURN_TYPE_TAG;
88+
import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.RELOCATED_CONSTANT_TAG;
8889
import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.SIMULATED_TAG;
8990
import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.SOURCE_FILE_NAME_TAG;
9091
import static com.oracle.graal.pointsto.heap.ImageLayerSnapshotUtil.STRENGTHENED_GRAPH_TAG;
@@ -551,6 +552,10 @@ protected void persistConstant(int parentId, int index, ImageHeapConstant imageH
551552
constantMap.put(CONSTANT_TYPE_TAG, PRIMITIVE_ARRAY_TAG);
552553
constantMap.put(DATA_TAG, getString(imageHeapPrimitiveArray.getType().getComponentType().getJavaKind(), imageHeapPrimitiveArray.getArray()));
553554
}
555+
case ImageHeapRelocatableConstant relocatableConstant -> {
556+
constantMap.put(CONSTANT_TYPE_TAG, RELOCATED_CONSTANT_TAG);
557+
constantMap.put(DATA_TAG, relocatableConstant.getConstantData().key);
558+
}
554559
default -> throw AnalysisError.shouldNotReachHere("Unexpected constant type " + imageHeapConstant);
555560
}
556561

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/typestate/ConstantTypeState.java

+2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import com.oracle.graal.pointsto.BigBang;
3232
import com.oracle.graal.pointsto.PointsToAnalysis;
3333
import com.oracle.graal.pointsto.flow.context.object.AnalysisObject;
34+
import com.oracle.graal.pointsto.heap.ImageHeapRelocatableConstant;
3435
import com.oracle.graal.pointsto.meta.AnalysisType;
3536
import com.oracle.graal.pointsto.util.AnalysisError;
3637

@@ -49,6 +50,7 @@ public class ConstantTypeState extends SingleTypeState {
4950
public ConstantTypeState(PointsToAnalysis bb, AnalysisType type, JavaConstant constant) {
5051
super(bb, false, type);
5152
assert !bb.analysisPolicy().isContextSensitiveAnalysis() : "The ConstantTypeState is indented to be used with a context insensitive analysis.";
53+
assert !(constant instanceof ImageHeapRelocatableConstant) : "relocatable constants have an unknown state and should not be represented by a constant type state: " + constant;
5254
this.constant = constant;
5355
}
5456

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/typestate/DefaultAnalysisPolicy.java

+9-1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import com.oracle.graal.pointsto.flow.TypeFlow;
4444
import com.oracle.graal.pointsto.flow.context.AnalysisContext;
4545
import com.oracle.graal.pointsto.flow.context.object.AnalysisObject;
46+
import com.oracle.graal.pointsto.heap.ImageHeapRelocatableConstant;
4647
import com.oracle.graal.pointsto.meta.AnalysisField;
4748
import com.oracle.graal.pointsto.meta.AnalysisMethod;
4849
import com.oracle.graal.pointsto.meta.AnalysisType;
@@ -129,7 +130,14 @@ public AnalysisObject createConstantObject(PointsToAnalysis bb, JavaConstant con
129130
}
130131

131132
@Override
132-
public ConstantTypeState constantTypeState(PointsToAnalysis bb, JavaConstant constant, AnalysisType exactType) {
133+
public TypeState constantTypeState(PointsToAnalysis bb, JavaConstant constant, AnalysisType exactType) {
134+
if (constant instanceof ImageHeapRelocatableConstant relocatableConstant) {
135+
/*
136+
* ImageHeapRelocatableConstants are placeholder values which will be later replaced
137+
* with an unknown non-null object.
138+
*/
139+
return TypeState.forType(bb, relocatableConstant.getType(), false);
140+
}
133141
return new ConstantTypeState(bb, exactType, constant);
134142
}
135143

substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/ChunkedImageHeapLayouter.java

+20-6
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,13 @@ public class ChunkedImageHeapLayouter implements ImageHeapLayouter {
5959
* A relocated reference is read-only once relocated, e.g., at runtime.
6060
*/
6161
private static final int READ_ONLY_RELOCATABLE = READ_ONLY_REGULAR + 1;
62+
/**
63+
* A partition holding objects which must be patched at execution startup by our initialization
64+
* code. This is currently only used within layered images.
65+
*/
66+
private static final int WRITABLE_PATCHED = READ_ONLY_RELOCATABLE + 1;
6267
/** A partition holding writable objects. */
63-
private static final int WRITABLE_REGULAR = READ_ONLY_RELOCATABLE + 1;
68+
private static final int WRITABLE_REGULAR = WRITABLE_PATCHED + 1;
6469
/** A partition holding very large writable objects with or without references. */
6570
private static final int WRITABLE_HUGE = WRITABLE_REGULAR + 1;
6671
/**
@@ -83,6 +88,7 @@ public ChunkedImageHeapLayouter(ImageHeapInfo heapInfo, long startOffset) {
8388
this.partitions = new ChunkedImageHeapPartition[PARTITION_COUNT];
8489
this.partitions[READ_ONLY_REGULAR] = new ChunkedImageHeapPartition("readOnly", false, false, alignment, alignment);
8590
this.partitions[READ_ONLY_RELOCATABLE] = new ChunkedImageHeapPartition("readOnlyRelocatable", false, false, alignment, alignment);
91+
this.partitions[WRITABLE_PATCHED] = new ChunkedImageHeapPartition("writablePatched", true, false, alignment, alignment);
8692
this.partitions[WRITABLE_REGULAR] = new ChunkedImageHeapPartition("writable", true, false, alignment, alignment);
8793
this.partitions[WRITABLE_HUGE] = new ChunkedImageHeapPartition("writableHuge", true, true, alignment, alignment);
8894
this.partitions[READ_ONLY_HUGE] = new ChunkedImageHeapPartition("readOnlyHuge", false, true, alignment, SubstrateOptions.getPageSize());
@@ -104,14 +110,16 @@ public ChunkedImageHeapPartition[] getPartitions() {
104110
}
105111

106112
@Override
107-
public void assignObjectToPartition(ImageHeapObject info, boolean immutable, boolean references, boolean relocatable) {
108-
ChunkedImageHeapPartition partition = choosePartition(info, immutable, relocatable);
113+
public void assignObjectToPartition(ImageHeapObject info, boolean immutable, boolean references, boolean relocatable, boolean patched) {
114+
ChunkedImageHeapPartition partition = choosePartition(info, immutable, relocatable, patched);
109115
info.setHeapPartition(partition);
110116
partition.assign(info);
111117
}
112118

113-
private ChunkedImageHeapPartition choosePartition(ImageHeapObject info, boolean immutable, boolean hasRelocatables) {
114-
if (immutable) {
119+
private ChunkedImageHeapPartition choosePartition(ImageHeapObject info, boolean immutable, boolean hasRelocatables, boolean patched) {
120+
if (patched) {
121+
return getWritablePatched();
122+
} else if (immutable) {
115123
if (hasRelocatables) {
116124
VMError.guarantee(info.getSize() < hugeObjectThreshold, "Objects with relocatable pointers cannot be huge objects");
117125
return getReadOnlyRelocatable();
@@ -177,14 +185,16 @@ private ImageHeapLayoutInfo populateInfoObjects(int dynamicHubCount, int pageSiz
177185
}
178186

179187
heapInfo.initialize(getReadOnlyRegular().firstObject, getReadOnlyRegular().lastObject, getReadOnlyRelocatable().firstObject, getReadOnlyRelocatable().lastObject,
188+
getWritablePatched().firstObject, getWritablePatched().lastObject,
180189
getWritableRegular().firstObject, getWritableRegular().lastObject, getWritableHuge().firstObject, getWritableHuge().lastObject,
181190
getReadOnlyHuge().firstObject, getReadOnlyHuge().lastObject, offsetOfFirstWritableAlignedChunk, offsetOfFirstWritableUnalignedChunk, offsetOfLastWritableUnalignedChunk,
182191
dynamicHubCount);
183192

184193
long writableEnd = getWritableHuge().getStartOffset() + getWritableHuge().getSize();
185194
long writableSize = writableEnd - offsetOfFirstWritableAlignedChunk;
186195
long imageHeapSize = getReadOnlyHuge().getStartOffset() + getReadOnlyHuge().getSize() - startOffset;
187-
return new ImageHeapLayoutInfo(startOffset, offsetOfFirstWritableAlignedChunk, writableSize, getReadOnlyRelocatable().getStartOffset(), getReadOnlyRelocatable().getSize(), imageHeapSize);
196+
return new ImageHeapLayoutInfo(startOffset, imageHeapSize, offsetOfFirstWritableAlignedChunk, writableSize, getReadOnlyRelocatable().getStartOffset(), getReadOnlyRelocatable().getSize(),
197+
getWritablePatched().getStartOffset(), getWritablePatched().getSize());
188198
}
189199

190200
@Override
@@ -231,6 +241,10 @@ private ChunkedImageHeapPartition getReadOnlyRelocatable() {
231241
return partitions[READ_ONLY_RELOCATABLE];
232242
}
233243

244+
private ChunkedImageHeapPartition getWritablePatched() {
245+
return partitions[WRITABLE_PATCHED];
246+
}
247+
234248
private ChunkedImageHeapPartition getWritableRegular() {
235249
return partitions[WRITABLE_REGULAR];
236250
}

substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/HeapImpl.java

+3
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,9 @@ private boolean printLocationInfo(Log log, Pointer ptr, boolean allowJavaHeapAcc
754754
} else if (info.isInReadOnlyRelocatablePartition(ptr)) {
755755
log.string("points into the image heap (read-only relocatables)");
756756
return true;
757+
} else if (info.isInWritablePatchedPartition(ptr)) {
758+
log.string("points into the image heap (writable patched)");
759+
return true;
757760
} else if (info.isInWritableRegularPartition(ptr)) {
758761
log.string("points into the image heap (writable)");
759762
return true;

0 commit comments

Comments
 (0)