Skip to content

Commit 8c25a5c

Browse files
committed
[GR-51211] Preparations for multiple image heaps at runtime.
PullRequest: graal/16519
2 parents 89cbfc0 + 81655ed commit 8c25a5c

File tree

22 files changed

+409
-409
lines changed

22 files changed

+409
-409
lines changed

substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/DebugInfoBase.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@
3636

3737
import org.graalvm.collections.EconomicMap;
3838
import org.graalvm.collections.EconomicSet;
39-
import jdk.graal.compiler.debug.DebugContext;
4039

4140
import com.oracle.objectfile.debugentry.range.PrimaryRange;
4241
import com.oracle.objectfile.debugentry.range.Range;
@@ -49,6 +48,7 @@
4948
import com.oracle.objectfile.debuginfo.DebugInfoProvider.DebugTypeInfo.DebugTypeKind;
5049
import com.oracle.objectfile.elf.dwarf.DwarfDebugInfo;
5150

51+
import jdk.graal.compiler.debug.DebugContext;
5252
import jdk.vm.ci.meta.ResolvedJavaType;
5353

5454
/**
@@ -351,10 +351,10 @@ public void installDebugInfo(DebugInfoProvider debugInfoProvider) {
351351
String provenance = debugDataInfo.getProvenance();
352352
String typeName = debugDataInfo.getTypeName();
353353
String partitionName = debugDataInfo.getPartition();
354-
/* Address is heap-register relative pointer. */
355-
long address = debugDataInfo.getAddress();
354+
/* Offset is relative to heap-base register. */
355+
long offset = debugDataInfo.getOffset();
356356
long size = debugDataInfo.getSize();
357-
debugContext.log(DebugContext.INFO_LEVEL, "Data: address 0x%x size 0x%x type %s partition %s provenance %s ", address, size, typeName, partitionName, provenance);
357+
debugContext.log(DebugContext.INFO_LEVEL, "Data: offset 0x%x size 0x%x type %s partition %s provenance %s ", offset, size, typeName, partitionName, provenance);
358358
}
359359
}));
360360
// populate a file and dir list and associated index for each class entry

substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debuginfo/DebugInfoProvider.java

+1-3
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@
3131
import java.util.function.Consumer;
3232
import java.util.stream.Stream;
3333

34+
import jdk.graal.compiler.debug.DebugContext;
3435
import jdk.vm.ci.meta.JavaConstant;
3536
import jdk.vm.ci.meta.JavaKind;
3637
import jdk.vm.ci.meta.ResolvedJavaMethod;
3738
import jdk.vm.ci.meta.ResolvedJavaType;
38-
import jdk.graal.compiler.debug.DebugContext;
3939

4040
/**
4141
* Interfaces used to allow a native image to communicate details of types, code and data to the
@@ -356,8 +356,6 @@ interface DebugDataInfo {
356356

357357
long getOffset();
358358

359-
long getAddress();
360-
361359
long getSize();
362360
}
363361

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

+5-26
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
import com.oracle.svm.core.genscavenge.ChunkedImageHeapAllocator.Chunk;
3636
import com.oracle.svm.core.genscavenge.ChunkedImageHeapAllocator.UnalignedChunk;
3737
import com.oracle.svm.core.genscavenge.remset.RememberedSet;
38-
import com.oracle.svm.core.heap.Heap;
3938
import com.oracle.svm.core.hub.DynamicHub;
4039
import com.oracle.svm.core.image.ImageHeap;
4140
import com.oracle.svm.core.image.ImageHeapLayoutInfo;
@@ -83,10 +82,9 @@ public class ChunkedImageHeapLayouter implements ImageHeapLayouter {
8382
private final long hugeObjectThreshold;
8483
private ChunkedImageHeapAllocator allocator;
8584

85+
/** @param startOffset Offset relative to the heap base. */
8686
@SuppressWarnings("this-escape")
8787
public ChunkedImageHeapLayouter(ImageHeapInfo heapInfo, long startOffset) {
88-
assert startOffset == 0 || startOffset >= Heap.getHeap().getImageHeapOffsetInAddressSpace() : "must be relative to the heap base";
89-
9088
this.partitions = new ChunkedImageHeapPartition[PARTITION_COUNT];
9189
this.partitions[READ_ONLY_PRIMITIVE] = new ChunkedImageHeapPartition("readOnlyPrimitive", false, false);
9290
this.partitions[READ_ONLY_REFERENCE] = new ChunkedImageHeapPartition("readOnlyReference", false, false);
@@ -209,34 +207,15 @@ private ImageHeapLayoutInfo populateInfoObjects(int dynamicHubCount) {
209207
break;
210208
}
211209

212-
initializeHeapInfo(dynamicHubCount, offsetOfFirstWritableAlignedChunk, offsetOfFirstWritableUnalignedChunk);
213-
return createLayoutInfo(startOffset, offsetOfFirstWritableAlignedChunk);
214-
}
215-
216-
private void initializeHeapInfo(int dynamicHubCount, long offsetOfFirstWritableAlignedChunk, long offsetOfFirstWritableUnalignedChunk) {
217-
long writableAligned = offsetOfFirstWritableAlignedChunk;
218-
long writableUnaligned = offsetOfFirstWritableUnalignedChunk;
219-
220-
if (startOffset == 0) {
221-
// Adjust all offsets by the offset of the image heap in the address space.
222-
int imageHeapOffsetInAddressSpace = Heap.getHeap().getImageHeapOffsetInAddressSpace();
223-
writableAligned += imageHeapOffsetInAddressSpace;
224-
if (writableUnaligned >= 0) {
225-
writableUnaligned += imageHeapOffsetInAddressSpace;
226-
}
227-
}
228-
229210
heapInfo.initialize(getReadOnlyPrimitive().firstObject, getReadOnlyPrimitive().lastObject, getReadOnlyReference().firstObject, getReadOnlyReference().lastObject,
230211
getReadOnlyRelocatable().firstObject, getReadOnlyRelocatable().lastObject, getWritablePrimitive().firstObject, getWritablePrimitive().lastObject,
231212
getWritableReference().firstObject, getWritableReference().lastObject, getWritableHuge().firstObject, getWritableHuge().lastObject,
232-
getReadOnlyHuge().firstObject, getReadOnlyHuge().lastObject, writableAligned, writableUnaligned, dynamicHubCount);
233-
}
213+
getReadOnlyHuge().firstObject, getReadOnlyHuge().lastObject, offsetOfFirstWritableAlignedChunk, offsetOfFirstWritableUnalignedChunk, dynamicHubCount);
234214

235-
private ImageHeapLayoutInfo createLayoutInfo(long heapStartOffset, long writableBeginOffset) {
236215
long writableEnd = getWritableHuge().getStartOffset() + getWritableHuge().getSize();
237-
long writableSize = writableEnd - writableBeginOffset;
238-
long imageHeapSize = getReadOnlyHuge().getStartOffset() + getReadOnlyHuge().getSize() - heapStartOffset;
239-
return new ImageHeapLayoutInfo(writableBeginOffset, writableSize, getReadOnlyRelocatable().getStartOffset(), getReadOnlyRelocatable().getSize(), imageHeapSize);
216+
long writableSize = writableEnd - offsetOfFirstWritableAlignedChunk;
217+
long imageHeapSize = getReadOnlyHuge().getStartOffset() + getReadOnlyHuge().getSize() - startOffset;
218+
return new ImageHeapLayoutInfo(startOffset, offsetOfFirstWritableAlignedChunk, writableSize, getReadOnlyRelocatable().getStartOffset(), getReadOnlyRelocatable().getSize(), imageHeapSize);
240219
}
241220

242221
@Override

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

+7-3
Original file line numberDiff line numberDiff line change
@@ -912,8 +912,9 @@ private void blackenDirtyImageHeapRoots() {
912912

913913
Timer blackenImageHeapRootsTimer = timers.blackenImageHeapRoots.open();
914914
try {
915-
ImageHeapInfo info = HeapImpl.getImageHeapInfo();
916-
blackenDirtyImageHeapChunkRoots(info.getFirstWritableAlignedChunk(), info.getFirstWritableUnalignedChunk());
915+
for (ImageHeapInfo info = HeapImpl.getFirstImageHeapInfo(); info != null; info = info.next) {
916+
blackenDirtyImageHeapChunkRoots(info.getFirstWritableAlignedChunk(), info.getFirstWritableUnalignedChunk());
917+
}
917918

918919
if (AuxiliaryImageHeap.isPresent()) {
919920
ImageHeapInfo auxInfo = AuxiliaryImageHeap.singleton().getImageHeapInfo();
@@ -959,7 +960,10 @@ private void blackenImageHeapRoots() {
959960

960961
Timer blackenImageHeapRootsTimer = timers.blackenImageHeapRoots.open();
961962
try {
962-
blackenImageHeapRoots(HeapImpl.getImageHeapInfo());
963+
for (ImageHeapInfo info = HeapImpl.getFirstImageHeapInfo(); info != null; info = info.next) {
964+
blackenImageHeapRoots(info);
965+
}
966+
963967
if (AuxiliaryImageHeap.isPresent()) {
964968
ImageHeapInfo auxImageHeapInfo = AuxiliaryImageHeap.singleton().getImageHeapInfo();
965969
if (auxImageHeapInfo != null) {

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

+55-34
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ public final class HeapImpl extends Heap {
108108
private final ObjectHeaderImpl objectHeaderImpl = new ObjectHeaderImpl();
109109
private final GCImpl gcImpl;
110110
private final RuntimeCodeInfoGCSupportImpl runtimeCodeInfoGcSupport;
111-
private final ImageHeapInfo imageHeapInfo = new ImageHeapInfo();
111+
private final ImageHeapInfo firstImageHeapInfo = new ImageHeapInfo();
112112
private final HeapAccounting accounting = new HeapAccounting();
113113

114114
/** Head of the linked list of currently pending (ready to be enqueued) {@link Reference}s. */
@@ -143,8 +143,8 @@ public static HeapImpl getHeapImpl() {
143143
}
144144

145145
@Fold
146-
public static ImageHeapInfo getImageHeapInfo() {
147-
return getHeapImpl().imageHeapInfo;
146+
public static ImageHeapInfo getFirstImageHeapInfo() {
147+
return getHeapImpl().firstImageHeapInfo;
148148
}
149149

150150
@Fold
@@ -179,7 +179,12 @@ public boolean isInPrimaryImageHeap(Object obj) {
179179
@Override
180180
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
181181
public boolean isInPrimaryImageHeap(Pointer objPointer) {
182-
return imageHeapInfo.isInImageHeap(objPointer);
182+
for (ImageHeapInfo info = firstImageHeapInfo; info != null; info = info.next) {
183+
if (info.isInImageHeap(objPointer)) {
184+
return true;
185+
}
186+
}
187+
return false;
183188
}
184189

185190
@Override
@@ -283,7 +288,9 @@ void logChunks(Log log) {
283288

284289
void logImageHeapPartitionBoundaries(Log log) {
285290
log.string("Native image heap boundaries:").indent(true);
286-
imageHeapInfo.print(log);
291+
for (ImageHeapInfo info = firstImageHeapInfo; info != null; info = info.next) {
292+
info.print(log);
293+
}
287294
log.indent(false);
288295

289296
if (AuxiliaryImageHeap.isPresent()) {
@@ -326,22 +333,28 @@ static void logZapValues(Log log) {
326333
@Override
327334
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
328335
public int getClassCount() {
329-
return imageHeapInfo.dynamicHubCount;
336+
int count = firstImageHeapInfo.dynamicHubCount;
337+
for (ImageHeapInfo info = firstImageHeapInfo.next; info != null; info = info.next) {
338+
count += info.dynamicHubCount;
339+
}
340+
return count;
330341
}
331342

332343
@Override
333344
protected List<Class<?>> getAllClasses() {
334345
/* Two threads might race to set classList, but they compute the same result. */
335346
if (classList == null) {
336347
ArrayList<Class<?>> list = new ArrayList<>(1024);
337-
ImageHeapWalker.walkRegions(imageHeapInfo, new ClassListBuilderVisitor(list));
348+
for (ImageHeapInfo info = firstImageHeapInfo; info != null; info = info.next) {
349+
ImageHeapWalker.walkRegions(info, new ClassListBuilderVisitor(list));
350+
}
338351
list.trimToSize();
339352

340353
/* Ensure that other threads see consistent values once the list is published. */
341354
MembarNode.memoryBarrier(MembarNode.FenceKind.STORE_STORE);
342355
classList = list;
343356
}
344-
assert classList.size() == imageHeapInfo.dynamicHubCount;
357+
assert classList.size() == getClassCount();
345358
return classList;
346359
}
347360

@@ -429,11 +442,15 @@ public int getImageHeapOffsetInAddressSpace() {
429442
@Override
430443
public boolean walkImageHeapObjects(ObjectVisitor visitor) {
431444
VMOperation.guaranteeInProgressAtSafepoint("Must only be called at a safepoint");
432-
if (visitor != null) {
433-
return ImageHeapWalker.walkImageHeapObjects(imageHeapInfo, visitor) &&
434-
(!AuxiliaryImageHeap.isPresent() || AuxiliaryImageHeap.singleton().walkObjects(visitor));
445+
if (visitor == null) {
446+
return true;
435447
}
436-
return true;
448+
for (ImageHeapInfo info = firstImageHeapInfo; info != null; info = info.next) {
449+
if (!ImageHeapWalker.walkImageHeapObjects(info, visitor)) {
450+
return false;
451+
}
452+
}
453+
return !AuxiliaryImageHeap.isPresent() || AuxiliaryImageHeap.singleton().walkObjects(visitor);
437454
}
438455

439456
@Override
@@ -694,28 +711,32 @@ static Pointer getImageHeapStart() {
694711
}
695712

696713
private boolean printLocationInfo(Log log, Pointer ptr, boolean allowJavaHeapAccess, boolean allowUnsafeOperations) {
697-
if (imageHeapInfo.isInReadOnlyPrimitivePartition(ptr)) {
698-
log.string("points into the image heap (read-only primitives)");
699-
return true;
700-
} else if (imageHeapInfo.isInReadOnlyReferencePartition(ptr)) {
701-
log.string("points into the image heap (read-only references)");
702-
return true;
703-
} else if (imageHeapInfo.isInReadOnlyRelocatablePartition(ptr)) {
704-
log.string("points into the image heap (read-only relocatables)");
705-
return true;
706-
} else if (imageHeapInfo.isInWritablePrimitivePartition(ptr)) {
707-
log.string("points into the image heap (writable primitives)");
708-
return true;
709-
} else if (imageHeapInfo.isInWritableReferencePartition(ptr)) {
710-
log.string("points into the image heap (writable references)");
711-
return true;
712-
} else if (imageHeapInfo.isInWritableHugePartition(ptr)) {
713-
log.string("points into the image heap (writable huge)");
714-
return true;
715-
} else if (imageHeapInfo.isInReadOnlyHugePartition(ptr)) {
716-
log.string("points into the image heap (read-only huge)");
717-
return true;
718-
} else if (AuxiliaryImageHeap.isPresent() && AuxiliaryImageHeap.singleton().containsObject(ptr)) {
714+
for (ImageHeapInfo info = firstImageHeapInfo; info != null; info = info.next) {
715+
if (info.isInReadOnlyPrimitivePartition(ptr)) {
716+
log.string("points into the image heap (read-only primitives)");
717+
return true;
718+
} else if (info.isInReadOnlyReferencePartition(ptr)) {
719+
log.string("points into the image heap (read-only references)");
720+
return true;
721+
} else if (info.isInReadOnlyRelocatablePartition(ptr)) {
722+
log.string("points into the image heap (read-only relocatables)");
723+
return true;
724+
} else if (info.isInWritablePrimitivePartition(ptr)) {
725+
log.string("points into the image heap (writable primitives)");
726+
return true;
727+
} else if (info.isInWritableReferencePartition(ptr)) {
728+
log.string("points into the image heap (writable references)");
729+
return true;
730+
} else if (info.isInWritableHugePartition(ptr)) {
731+
log.string("points into the image heap (writable huge)");
732+
return true;
733+
} else if (info.isInReadOnlyHugePartition(ptr)) {
734+
log.string("points into the image heap (read-only huge)");
735+
return true;
736+
}
737+
}
738+
739+
if (AuxiliaryImageHeap.isPresent() && AuxiliaryImageHeap.singleton().containsObject(ptr)) {
719740
log.string("points into the auxiliary image heap");
720741
return true;
721742
} else if (printTlabInfo(log, ptr, CurrentIsolate.getCurrentThread())) {

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

+8-6
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,10 @@ public static boolean verify(Occasion occasion) {
6868

6969
private static boolean verifyImageHeap() {
7070
boolean success = true;
71-
ImageHeapInfo info = HeapImpl.getImageHeapInfo();
72-
success &= verifyAlignedChunks(null, info.getFirstWritableAlignedChunk());
73-
success &= verifyUnalignedChunks(null, info.getFirstWritableUnalignedChunk());
71+
for (ImageHeapInfo info = HeapImpl.getFirstImageHeapInfo(); info != null; info = info.next) {
72+
success &= verifyAlignedChunks(null, info.getFirstWritableAlignedChunk());
73+
success &= verifyUnalignedChunks(null, info.getFirstWritableUnalignedChunk());
74+
}
7475
return success;
7576
}
7677

@@ -145,9 +146,10 @@ private static boolean verifyRememberedSets() {
145146
* For the image heap, we can't verify that all cards are clean after a GC because the GC
146147
* itself may result in dirty cards.
147148
*/
148-
ImageHeapInfo info = HeapImpl.getImageHeapInfo();
149-
success &= rememberedSet.verify(info.getFirstWritableAlignedChunk());
150-
success &= rememberedSet.verify(info.getFirstWritableUnalignedChunk());
149+
for (ImageHeapInfo info = HeapImpl.getFirstImageHeapInfo(); info != null; info = info.next) {
150+
success &= rememberedSet.verify(info.getFirstWritableAlignedChunk());
151+
success &= rememberedSet.verify(info.getFirstWritableUnalignedChunk());
152+
}
151153

152154
OldGeneration oldGeneration = HeapImpl.getHeapImpl().getOldGeneration();
153155
Space toSpace = oldGeneration.getToSpace();

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

+7
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,14 @@ public final class ImageHeapInfo {
7979

8080
@UnknownPrimitiveField(availability = AfterHeapLayout.class) public int dynamicHubCount;
8181

82+
public final ImageHeapInfo next;
83+
8284
public ImageHeapInfo() {
85+
this(null);
86+
}
87+
88+
public ImageHeapInfo(ImageHeapInfo next) {
89+
this.next = next;
8390
}
8491

8592
@SuppressWarnings("hiding")

substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/graal/GenScavengeGCFeature.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -142,13 +142,13 @@ public void beforeAnalysis(BeforeAnalysisAccess access) {
142142

143143
@Override
144144
public void afterAnalysis(AfterAnalysisAccess access) {
145-
ImageHeapLayouter heapLayouter = new ChunkedImageHeapLayouter(HeapImpl.getImageHeapInfo(), 0);
145+
ImageHeapLayouter heapLayouter = new ChunkedImageHeapLayouter(HeapImpl.getFirstImageHeapInfo(), Heap.getHeap().getImageHeapOffsetInAddressSpace());
146146
ImageSingletons.add(ImageHeapLayouter.class, heapLayouter);
147147
}
148148

149149
@Override
150150
public void beforeCompilation(BeforeCompilationAccess access) {
151-
ImageHeapInfo imageHeapInfo = HeapImpl.getImageHeapInfo();
151+
ImageHeapInfo imageHeapInfo = HeapImpl.getFirstImageHeapInfo();
152152
access.registerAsImmutable(imageHeapInfo);
153153
}
154154

0 commit comments

Comments
 (0)