Skip to content

Commit e6f932f

Browse files
committed
Remove unnecessary image heap partition alignment and filler object code.
1 parent 68b79a2 commit e6f932f

File tree

8 files changed

+28
-152
lines changed

8 files changed

+28
-152
lines changed

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

Lines changed: 6 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,13 @@
2828
import java.util.List;
2929

3030
import com.oracle.svm.core.config.ConfigurationValues;
31-
import com.oracle.svm.core.image.ImageHeap;
3231
import com.oracle.svm.core.image.ImageHeapObject;
33-
import com.oracle.svm.core.image.ImageHeapPartition;
3432
import com.oracle.svm.core.util.UnsignedUtils;
3533
import com.oracle.svm.core.util.VMError;
3634

37-
import jdk.graal.compiler.core.common.NumUtil;
3835
import jdk.graal.compiler.word.Word;
3936

4037
class ChunkedImageHeapAllocator {
41-
/** A pseudo-partition for filler objects, see {@link FillerObjectDummyPartition}. */
42-
private static final ImageHeapPartition FILLERS_DUMMY_PARTITION = new FillerObjectDummyPartition();
43-
4438
abstract static class Chunk {
4539
private final long begin;
4640
private final long endOffset;
@@ -116,35 +110,6 @@ public long allocate(ImageHeapObject obj, boolean writable) {
116110
return objStart;
117111
}
118112

119-
public boolean tryAlignTop(int multiple) {
120-
long padding = computePadding(getTop(), multiple);
121-
if (padding != 0 && padding < minimumObjectSize) {
122-
/*
123-
* Cannot fit a filler object into the remaining padding space, so need to go up to
124-
* the next alignment multiple.
125-
*/
126-
padding = padding + multiple;
127-
}
128-
if (padding > getUnallocatedBytes()) {
129-
return false;
130-
}
131-
allocateFiller(padding);
132-
assert getTop() % multiple == 0;
133-
return true;
134-
}
135-
136-
private void allocateFiller(long size) {
137-
if (size != 0) {
138-
ImageHeapObject filler = imageHeap.addFillerObject(NumUtil.safeToInt(size));
139-
if (filler == null) {
140-
throw VMError.shouldNotReachHere("Failed to leave enough space for a filler object: " + size + " byte remaining");
141-
}
142-
filler.setHeapPartition(FILLERS_DUMMY_PARTITION);
143-
long location = allocate(filler, false);
144-
filler.setOffsetInPartition(location);
145-
}
146-
}
147-
148113
public List<ImageHeapObject> getObjects() {
149114
return objects;
150115
}
@@ -163,7 +128,6 @@ public long getUnallocatedBytes() {
163128
}
164129
}
165130

166-
private final ImageHeap imageHeap;
167131
private final int alignedChunkSize;
168132
private final int alignedChunkAlignment;
169133
private final int alignedChunkObjectsOffset;
@@ -176,8 +140,7 @@ public long getUnallocatedBytes() {
176140

177141
final int minimumObjectSize;
178142

179-
ChunkedImageHeapAllocator(ImageHeap imageHeap, long position) {
180-
this.imageHeap = imageHeap;
143+
ChunkedImageHeapAllocator(long position) {
181144
this.alignedChunkSize = UnsignedUtils.safeToInt(HeapParameters.getAlignedHeapChunkSize());
182145
this.alignedChunkAlignment = UnsignedUtils.safeToInt(HeapParameters.getAlignedHeapChunkAlignment());
183146
this.alignedChunkObjectsOffset = UnsignedUtils.safeToInt(AlignedHeapChunk.getObjectsStartOffset());
@@ -192,11 +155,6 @@ public long getPosition() {
192155
return (currentAlignedChunk != null) ? currentAlignedChunk.getTop() : position;
193156
}
194157

195-
public void alignBetweenChunks(int multiple) {
196-
assert currentAlignedChunk == null;
197-
allocateRaw(computePadding(position, multiple));
198-
}
199-
200158
public long allocateUnalignedChunkForObject(ImageHeapObject obj, boolean writable) {
201159
assert currentAlignedChunk == null;
202160
long objSize = obj.getSize();
@@ -220,6 +178,11 @@ public void startNewAlignedChunk() {
220178
alignedChunks.add(currentAlignedChunk);
221179
}
222180

181+
private void alignBetweenChunks(int multiple) {
182+
assert currentAlignedChunk == null;
183+
allocateRaw(computePadding(position, multiple));
184+
}
185+
223186
public long getRemainingBytesInAlignedChunk() {
224187
return currentAlignedChunk.getUnallocatedBytes();
225188
}
@@ -228,15 +191,6 @@ public long allocateObjectInAlignedChunk(ImageHeapObject obj, boolean writable)
228191
return currentAlignedChunk.allocate(obj, writable);
229192
}
230193

231-
public void alignInAlignedChunk(int multiple) {
232-
if (!currentAlignedChunk.tryAlignTop(multiple)) {
233-
startNewAlignedChunk();
234-
if (!currentAlignedChunk.tryAlignTop(multiple)) {
235-
throw VMError.shouldNotReachHere("Cannot align to " + multiple + " bytes within an aligned chunk's object area");
236-
}
237-
}
238-
}
239-
240194
public void finishAlignedChunk() {
241195
currentAlignedChunk = null;
242196
}
@@ -261,40 +215,3 @@ private static long computePadding(long offset, int alignment) {
261215
return (remainder == 0) ? 0 : (alignment - remainder);
262216
}
263217
}
264-
265-
/**
266-
* A pseudo-partition for filler objects, which does not really exist at runtime, in any statistics,
267-
* or otherwise. Necessary because like all other {@link ImageHeapObject}s, filler objects must be
268-
* assigned to a partition, the start offset of which is used to compute their absolute locations.
269-
* <p>
270-
* For filler objects in the middle of a partition (between genuine objects of that partition), it
271-
* would be acceptable to assign them to their enclosing partition. However, filler objects that are
272-
* inserted between partitions for alignment purposes are problematic because if they were assigned
273-
* to either partition, they would either be out of the partition's boundaries, or they would change
274-
* those boundaries, which would make them useless because that's exactly why they are needed there.
275-
*/
276-
final class FillerObjectDummyPartition implements ImageHeapPartition {
277-
/**
278-
* Zero so that the partition-relative offsets of filler objects are always their absolute
279-
* locations.
280-
*/
281-
@Override
282-
public long getStartOffset() {
283-
return 0;
284-
}
285-
286-
@Override
287-
public String getName() {
288-
throw VMError.shouldNotReachHereAtRuntime(); // ExcludeFromJacocoGeneratedReport
289-
}
290-
291-
@Override
292-
public long getSize() {
293-
throw VMError.shouldNotReachHereAtRuntime(); // ExcludeFromJacocoGeneratedReport
294-
}
295-
296-
@Override
297-
public boolean isFiller() {
298-
return true;
299-
}
300-
}

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

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@
3838
import com.oracle.svm.core.genscavenge.remset.RememberedSet;
3939
import com.oracle.svm.core.hub.DynamicHub;
4040
import com.oracle.svm.core.image.ImageHeap;
41-
import com.oracle.svm.core.image.ImageHeapLayouter;
4241
import com.oracle.svm.core.image.ImageHeapLayoutInfo;
42+
import com.oracle.svm.core.image.ImageHeapLayouter;
4343
import com.oracle.svm.core.image.ImageHeapObject;
4444
import com.oracle.svm.core.option.SubstrateOptionsParser;
4545
import com.oracle.svm.core.util.UserError;
@@ -88,14 +88,13 @@ public class ChunkedImageHeapLayouter implements ImageHeapLayouter {
8888
/** @param startOffset Offset relative to the heap base. */
8989
@SuppressWarnings("this-escape")
9090
public ChunkedImageHeapLayouter(ImageHeapInfo heapInfo, long startOffset) {
91-
int alignment = ConfigurationValues.getObjectLayout().getAlignment();
9291
this.partitions = new ChunkedImageHeapPartition[PARTITION_COUNT];
93-
this.partitions[READ_ONLY_REGULAR] = new ChunkedImageHeapPartition("readOnly", false, false, alignment, alignment);
94-
this.partitions[READ_ONLY_RELOCATABLE] = new ChunkedImageHeapPartition("readOnlyRelocatable", false, false, alignment, alignment);
95-
this.partitions[WRITABLE_PATCHED] = new ChunkedImageHeapPartition("writablePatched", true, false, alignment, alignment);
96-
this.partitions[WRITABLE_REGULAR] = new ChunkedImageHeapPartition("writable", true, false, alignment, alignment);
97-
this.partitions[WRITABLE_HUGE] = new ChunkedImageHeapPartition("writableHuge", true, true, alignment, alignment);
98-
this.partitions[READ_ONLY_HUGE] = new ChunkedImageHeapPartition("readOnlyHuge", false, true, alignment, alignment);
92+
this.partitions[READ_ONLY_REGULAR] = new ChunkedImageHeapPartition("readOnly", false, false);
93+
this.partitions[READ_ONLY_RELOCATABLE] = new ChunkedImageHeapPartition("readOnlyRelocatable", false, false);
94+
this.partitions[WRITABLE_PATCHED] = new ChunkedImageHeapPartition("writablePatched", true, false);
95+
this.partitions[WRITABLE_REGULAR] = new ChunkedImageHeapPartition("writable", true, false);
96+
this.partitions[WRITABLE_HUGE] = new ChunkedImageHeapPartition("writableHuge", true, true);
97+
this.partitions[READ_ONLY_HUGE] = new ChunkedImageHeapPartition("readOnlyHuge", false, true);
9998

10099
this.heapInfo = heapInfo;
101100
this.startOffset = startOffset;
@@ -165,16 +164,20 @@ public ImageHeapLayoutInfo layout(ImageHeap imageHeap, int pageSize, ImageHeapLa
165164

166165
ImageHeapLayoutInfo layoutInfo = doLayout(imageHeap, pageSize, control);
167166

167+
/*
168+
* In case there is a need for more alignment between partitions or between objects in a
169+
* chunk, see the version history of this file (and package) for a earlier implementation.
170+
*/
168171
for (ChunkedImageHeapPartition partition : getPartitions()) {
169-
assert partition.getStartOffset() % partition.getStartAlignment() == 0 : partition;
170-
assert (partition.getStartOffset() + partition.getSize()) % partition.getEndAlignment() == 0 : partition;
172+
assert partition.getStartOffset() % objectAlignment == 0 : partition;
173+
assert (partition.getStartOffset() + partition.getSize()) % objectAlignment == 0 : partition;
171174
}
172175
assert layoutInfo.getImageHeapSize() % pageSize == 0 : "Image heap size is not a multiple of page size";
173176
return layoutInfo;
174177
}
175178

176179
private ImageHeapLayoutInfo doLayout(ImageHeap imageHeap, int pageSize, ImageHeapLayouterControl control) {
177-
allocator = new ChunkedImageHeapAllocator(imageHeap, startOffset);
180+
allocator = new ChunkedImageHeapAllocator(startOffset);
178181
for (ChunkedImageHeapPartition partition : getPartitions()) {
179182
control.poll();
180183
partition.layout(allocator, control);

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

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,6 @@ public class ChunkedImageHeapPartition implements ImageHeapPartition {
4646
private final String name;
4747
private final boolean writable;
4848
private final boolean hugeObjects;
49-
private final int startAlignment;
50-
private final int endAlignment;
5149
private final int minimumObjectSize;
5250
private final List<ImageHeapObject> objects = new ArrayList<>();
5351

@@ -57,12 +55,10 @@ public class ChunkedImageHeapPartition implements ImageHeapPartition {
5755
long startOffset = -1;
5856
long endOffset = -1;
5957

60-
ChunkedImageHeapPartition(String name, boolean writable, boolean hugeObjects, int startAlignment, int endAlignment) {
58+
ChunkedImageHeapPartition(String name, boolean writable, boolean hugeObjects) {
6159
this.name = name;
6260
this.writable = writable;
6361
this.hugeObjects = hugeObjects;
64-
this.startAlignment = startAlignment;
65-
this.endAlignment = endAlignment;
6662

6763
/* Cache to prevent frequent lookups of the object layout from ImageSingletons. */
6864
this.minimumObjectSize = ConfigurationValues.getObjectLayout().getMinImageHeapObjectSize();
@@ -94,26 +90,20 @@ private void layoutInUnalignedChunks(ChunkedImageHeapAllocator allocator, ImageH
9490
}
9591

9692
allocator.finishAlignedChunk();
97-
allocator.alignBetweenChunks(getStartAlignment());
9893
startOffset = allocator.getPosition();
9994

10095
for (ImageHeapObject info : objects) { // No need to sort by size
10196
appendAllocatedObject(info, allocator.allocateUnalignedChunkForObject(info, isWritable()));
10297
control.poll();
10398
}
10499

105-
allocator.alignBetweenChunks(getEndAlignment());
106100
endOffset = allocator.getPosition();
107101
}
108102

109103
private void layoutInAlignedChunks(ChunkedImageHeapAllocator allocator, ImageHeapLayouterControl control) {
110104
allocator.maybeStartAlignedChunk();
111-
allocator.alignInAlignedChunk(getStartAlignment());
112105
startOffset = allocator.getPosition();
113-
114106
allocateObjectsInAlignedChunks(allocator, control);
115-
116-
allocator.alignInAlignedChunk(getEndAlignment());
117107
endOffset = allocator.getPosition();
118108
}
119109

@@ -187,14 +177,6 @@ boolean usesUnalignedObjects() {
187177
return hugeObjects;
188178
}
189179

190-
final int getStartAlignment() {
191-
return startAlignment;
192-
}
193-
194-
final int getEndAlignment() {
195-
return endAlignment;
196-
}
197-
198180
@Override
199181
public long getStartOffset() {
200182
assert startOffset >= 0 : "Start offset not yet set";
@@ -211,11 +193,6 @@ public long getSize() {
211193
return getEndOffset() - getStartOffset();
212194
}
213195

214-
@Override
215-
public boolean isFiller() {
216-
return false;
217-
}
218-
219196
@Override
220197
public String toString() {
221198
return name;

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

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -331,15 +331,12 @@ public static boolean isConsumedHeapChunkZapped(UnsignedWord header) {
331331
public long encodeHubPointerForImageHeap(ImageHeapObject obj, long hubOffsetFromHeapBase) {
332332
long header = hubOffsetFromHeapBase << numReservedExtraHubBits;
333333
assert (header & reservedHubBitsMask) == 0 : "Object header bits must be zero initially";
334-
if (obj.getPartition() instanceof ChunkedImageHeapPartition partition) {
335-
if (partition.isWritable() && HeapImpl.usesImageHeapCardMarking()) {
336-
header |= REMSET_OR_MARKED1_BIT.rawValue();
337-
}
338-
if (partition.usesUnalignedObjects()) {
339-
header |= UNALIGNED_BIT.rawValue();
340-
}
341-
} else {
342-
assert obj.getPartition() instanceof FillerObjectDummyPartition;
334+
ChunkedImageHeapPartition partition = (ChunkedImageHeapPartition) obj.getPartition();
335+
if (partition.isWritable() && HeapImpl.usesImageHeapCardMarking()) {
336+
header |= REMSET_OR_MARKED1_BIT.rawValue();
337+
}
338+
if (partition.usesUnalignedObjects()) {
339+
header |= UNALIGNED_BIT.rawValue();
343340
}
344341
if (isIdentityHashFieldOptional()) {
345342
header |= (IDHASH_STATE_IN_FIELD.rawValue() << IDHASH_STATE_SHIFT);

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/image/ImageHeapPartition.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,4 @@ public interface ImageHeapPartition {
3939
* Returns the size of the partition (i.e., the sum of all allocated objects + some overhead).
4040
*/
4141
long getSize();
42-
43-
/* Returns true if this partition is only used as a filler. */
44-
boolean isFiller();
4542
}

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageDebugInfoProvider.java

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ public Stream<DebugCodeInfo> codeInfoProvider() {
150150

151151
@Override
152152
public Stream<DebugDataInfo> dataInfoProvider() {
153-
return heap.getObjects().stream().filter(this::acceptObjectInfo).map(this::createDebugDataInfo);
153+
return heap.getObjects().stream().map(this::createDebugDataInfo);
154154
}
155155

156156
private abstract class NativeImageDebugFileInfo implements DebugFileInfo {
@@ -2658,11 +2658,6 @@ public long getSize() {
26582658
}
26592659
}
26602660

2661-
private boolean acceptObjectInfo(ObjectInfo objectInfo) {
2662-
/* This condition rejects filler partition objects. */
2663-
return !objectInfo.getPartition().isFiller();
2664-
}
2665-
26662661
private DebugDataInfo createDebugDataInfo(ObjectInfo objectInfo) {
26672662
return new NativeImageDebugDataInfo(objectInfo);
26682663
}

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageHeap.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1148,9 +1148,4 @@ public String getName() {
11481148
public long getSize() {
11491149
throw VMError.shouldNotReachHereAtRuntime(); // ExcludeFromJacocoGeneratedReport
11501150
}
1151-
1152-
@Override
1153-
public boolean isFiller() {
1154-
return false;
1155-
}
11561151
}

web-image/src/com.oracle.svm.hosted.webimage/src/com/oracle/svm/hosted/webimage/wasmgc/image/WasmGCPartition.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,4 @@ public void add(ImageHeapObject obj) {
100100
objects.add(obj);
101101
obj.setHeapPartition(this);
102102
}
103-
104-
@Override
105-
public boolean isFiller() {
106-
return false;
107-
}
108103
}

0 commit comments

Comments
 (0)