From 5632fc073e303a6d1791ebc8ff99ef09bbdc0ed7 Mon Sep 17 00:00:00 2001 From: Peter Hofer Date: Fri, 6 Aug 2021 11:54:31 +0200 Subject: [PATCH 1/3] Use image heap remembered set during complete collections. --- .../oracle/svm/core/genscavenge/GCImpl.java | 20 ++++++++++-- .../svm/core/genscavenge/YoungGeneration.java | 10 +++++- .../remset/AlignedChunkRememberedSet.java | 6 ++-- .../core/genscavenge/remset/CardTable.java | 17 ++++++---- .../remset/CardTableBasedRememberedSet.java | 32 +++++++++++++------ .../genscavenge/remset/NoRememberedSet.java | 6 ++-- .../genscavenge/remset/RememberedSet.java | 24 +++++++------- .../remset/UnalignedChunkRememberedSet.java | 6 ++-- 8 files changed, 83 insertions(+), 38 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GCImpl.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GCImpl.java index 7ebf025194b9..756ac4aad5ef 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GCImpl.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GCImpl.java @@ -824,20 +824,34 @@ private void blackenDirtyImageHeapRoots() { } private void blackenDirtyImageHeapChunkRoots(AlignedHeader firstAligned, UnalignedHeader firstUnaligned) { + /* + * We clean and remark cards of the image heap only during complete collections when we also + * collect the old generation and can easily remark references into it. It also only makes a + * difference after references to the runtime heap were nulled, which is assumed to be rare. + */ + boolean clean = completeCollection; + AlignedHeader aligned = firstAligned; while (aligned.isNonNull()) { - RememberedSet.get().walkDirtyObjects(aligned, greyToBlackObjectVisitor); + RememberedSet.get().walkDirtyObjects(aligned, greyToBlackObjectVisitor, clean); aligned = HeapChunk.getNext(aligned); } UnalignedHeader unaligned = firstUnaligned; while (unaligned.isNonNull()) { - RememberedSet.get().walkDirtyObjects(unaligned, greyToBlackObjectVisitor); + RememberedSet.get().walkDirtyObjects(unaligned, greyToBlackObjectVisitor, clean); unaligned = HeapChunk.getNext(unaligned); } } private void blackenImageHeapRoots() { + if (HeapImpl.usesImageHeapCardMarking()) { + // Avoid scanning the entire image heap even for complete collections: its remembered + // set contains references into both the runtime heap's old and young generations. + blackenDirtyImageHeapRoots(); + return; + } + Timer blackenImageHeapRootsTimer = timers.blackenImageHeapRoots.open(); try { HeapImpl.getHeapImpl().walkNativeImageHeapRegions(blackenImageHeapRootsVisitor); @@ -864,7 +878,7 @@ private void blackenDirtyCardRoots() { * Promote any referenced young objects. */ Space oldGenToSpace = HeapImpl.getHeapImpl().getOldGeneration().getToSpace(); - RememberedSet.get().walkDirtyObjects(oldGenToSpace, greyToBlackObjectVisitor); + RememberedSet.get().walkDirtyObjects(oldGenToSpace, greyToBlackObjectVisitor, true); } finally { blackenDirtyCardRootsTimer.close(); } diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/YoungGeneration.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/YoungGeneration.java index ab79f80f3ad4..26446b351f21 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/YoungGeneration.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/YoungGeneration.java @@ -244,9 +244,17 @@ private UnsignedWord computeSurvivorObjectBytes() { return usedObjectBytes; } + @AlwaysInline("GC performance") @SuppressWarnings("static-method") public boolean contains(Object object) { - return HeapChunk.getSpace(HeapChunk.getEnclosingHeapChunk(object)).isYoungSpace(); + if (!HeapImpl.usesImageHeapCardMarking()) { + return HeapChunk.getSpace(HeapChunk.getEnclosingHeapChunk(object)).isYoungSpace(); + } + // Only objects in the young generation have no remembered set + UnsignedWord header = ObjectHeaderImpl.readHeaderFromObject(object); + boolean young = !ObjectHeaderImpl.hasRememberedSet(header); + assert young == HeapChunk.getSpace(HeapChunk.getEnclosingHeapChunk(object)).isYoungSpace(); + return young; } @AlwaysInline("GC performance") diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/remset/AlignedChunkRememberedSet.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/remset/AlignedChunkRememberedSet.java index f6a8f2be9dc0..9b20da888c89 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/remset/AlignedChunkRememberedSet.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/remset/AlignedChunkRememberedSet.java @@ -125,7 +125,7 @@ public static void dirtyCardForObject(Object object, boolean verifyOnly) { } } - public static void walkDirtyObjects(AlignedHeader chunk, GreyToBlackObjectVisitor visitor) { + public static void walkDirtyObjects(AlignedHeader chunk, GreyToBlackObjectVisitor visitor, boolean clean) { Pointer cardTableStart = getCardTableStart(chunk); Pointer fotStart = getFirstObjectTableStart(chunk); Pointer objectsStart = AlignedHeapChunk.getObjectsStart(chunk); @@ -135,7 +135,9 @@ public static void walkDirtyObjects(AlignedHeader chunk, GreyToBlackObjectVisito for (UnsignedWord index = WordFactory.zero(); index.belowThan(indexLimit); index = index.add(1)) { if (CardTable.isDirty(cardTableStart, index)) { - CardTable.setClean(cardTableStart, index); + if (clean) { + CardTable.setClean(cardTableStart, index); + } Pointer ptr = FirstObjectTable.getFirstObjectImprecise(fotStart, objectsStart, objectsLimit, index); Pointer cardLimit = CardTable.indexToMemoryPointer(objectsStart, index.add(1)); diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/remset/CardTable.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/remset/CardTable.java index c73596fce886..63ed94347e07 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/remset/CardTable.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/remset/CardTable.java @@ -35,7 +35,6 @@ import com.oracle.svm.core.UnmanagedMemoryUtil; import com.oracle.svm.core.genscavenge.HeapChunk; import com.oracle.svm.core.genscavenge.HeapImpl; -import com.oracle.svm.core.genscavenge.Space; import com.oracle.svm.core.genscavenge.graal.BarrierSnippets; import com.oracle.svm.core.heap.ObjectReferenceVisitor; import com.oracle.svm.core.heap.ReferenceAccess; @@ -167,14 +166,18 @@ private static boolean verifyReference(Object parentObject, Pointer cardTableSta if (referencedObject.isNonNull() && !HeapImpl.getHeapImpl().isInImageHeap(referencedObject)) { Object obj = referencedObject.toObject(); HeapChunk.Header objChunk = HeapChunk.getEnclosingHeapChunk(obj); - Space chunkSpace = HeapChunk.getSpace(objChunk); - // Fail if we find a reference to the young generation. - if (chunkSpace.isYoungSpace()) { + // Fail if we find a reference from the image heap to the runtime heap, or from the + // old generation (which is the only one with remembered sets) to the young generation. + boolean fromImageHeap = HeapImpl.usesImageHeapCardMarking() && HeapImpl.getHeapImpl().isInImageHeap(parentObject); + if (fromImageHeap || HeapChunk.getSpace(objChunk).isYoungSpace()) { UnsignedWord cardTableIndex = memoryOffsetToIndex(Word.objectToUntrackedPointer(parentObject).subtract(objectsStart)); Pointer cardTableAddress = cardTableStart.add(indexToTableOffset(cardTableIndex)); - Log.log().string("Object ").hex(Word.objectToUntrackedPointer(parentObject)).string(" (").string(parentObject.getClass().getName()).string(") has an object reference at ") - .hex(reference).string(" that points to ").hex(referencedObject).string(" (").string(obj.getClass().getName()) - .string("), which is in the young generation. However, the card table at ").hex(cardTableAddress).string(" is clean.").newline(); + Log.log().string("Object ").hex(Word.objectToUntrackedPointer(parentObject)).string(" (").string(parentObject.getClass().getName()).character(')') + .string(fromImageHeap ? ", which is in the image heap, " : " ") + .string("has an object reference at ") + .hex(reference).string(" that points to ").hex(referencedObject).string(" (").string(obj.getClass().getName()).string("), ") + .string("which is in the ").string(fromImageHeap ? "runtime heap" : "young generation").string(". ") + .string("However, the card table at ").hex(cardTableAddress).string(" is clean.").newline(); return false; } } diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/remset/CardTableBasedRememberedSet.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/remset/CardTableBasedRememberedSet.java index 84903f7b70e0..b0696edf0fd3 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/remset/CardTableBasedRememberedSet.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/remset/CardTableBasedRememberedSet.java @@ -131,8 +131,22 @@ public void dirtyCardForUnalignedObject(Object object, boolean verifyOnly) { @Override @AlwaysInline("GC performance") public void dirtyCardIfNecessary(Object holderObject, Object object) { - if (HeapPolicy.getMaxSurvivorSpaces() == 0 || holderObject == null || object == null || GCImpl.getGCImpl().isCompleteCollection() || - !HeapImpl.getHeapImpl().getYoungGeneration().contains(object)) { + if (holderObject == null || object == null) { + return; + } + // We dirty the cards of ... + if (HeapPolicy.getMaxSurvivorSpaces() != 0 && !GCImpl.getGCImpl().isCompleteCollection() && HeapImpl.getHeapImpl().getYoungGeneration().contains(object)) { + /* + * ...references from the old generation to the young generation, unless there cannot be + * any such references if we do not use survivor spaces, or if we do but are doing a + * complete collection: in both cases, all objects are promoted to the old generation. + * (We avoid an extra old generation check and might remark a few image heap cards, too) + */ + } else if (HeapImpl.usesImageHeapCardMarking() && GCImpl.getGCImpl().isCompleteCollection() && HeapImpl.getHeapImpl().isInImageHeap(holderObject)) { + // ...references from the image heap to the runtime heap, but we clean and remark those + // only during complete collections. + assert !HeapImpl.getHeapImpl().isInImageHeap(object) : "should never be called for references to image heap objects"; + } else { return; } @@ -148,26 +162,26 @@ public void dirtyCardIfNecessary(Object holderObject, Object object) { } @Override - public void walkDirtyObjects(AlignedHeader chunk, GreyToBlackObjectVisitor visitor) { - AlignedChunkRememberedSet.walkDirtyObjects(chunk, visitor); + public void walkDirtyObjects(AlignedHeader chunk, GreyToBlackObjectVisitor visitor, boolean clean) { + AlignedChunkRememberedSet.walkDirtyObjects(chunk, visitor, clean); } @Override - public void walkDirtyObjects(UnalignedHeader chunk, GreyToBlackObjectVisitor visitor) { - UnalignedChunkRememberedSet.walkDirtyObjects(chunk, visitor); + public void walkDirtyObjects(UnalignedHeader chunk, GreyToBlackObjectVisitor visitor, boolean clean) { + UnalignedChunkRememberedSet.walkDirtyObjects(chunk, visitor, clean); } @Override - public void walkDirtyObjects(Space space, GreyToBlackObjectVisitor visitor) { + public void walkDirtyObjects(Space space, GreyToBlackObjectVisitor visitor, boolean clean) { AlignedHeader aChunk = space.getFirstAlignedHeapChunk(); while (aChunk.isNonNull()) { - walkDirtyObjects(aChunk, visitor); + walkDirtyObjects(aChunk, visitor, clean); aChunk = HeapChunk.getNext(aChunk); } UnalignedHeader uChunk = space.getFirstUnalignedHeapChunk(); while (uChunk.isNonNull()) { - walkDirtyObjects(uChunk, visitor); + walkDirtyObjects(uChunk, visitor, clean); uChunk = HeapChunk.getNext(uChunk); } } diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/remset/NoRememberedSet.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/remset/NoRememberedSet.java index e61a10190bfd..7693eda72ae0 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/remset/NoRememberedSet.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/remset/NoRememberedSet.java @@ -132,17 +132,17 @@ public void dirtyCardIfNecessary(Object holderObject, Object object) { } @Override - public void walkDirtyObjects(AlignedHeader chunk, GreyToBlackObjectVisitor visitor) { + public void walkDirtyObjects(AlignedHeader chunk, GreyToBlackObjectVisitor visitor, boolean clean) { throw VMError.shouldNotReachHere(); } @Override - public void walkDirtyObjects(UnalignedHeader chunk, GreyToBlackObjectVisitor visitor) { + public void walkDirtyObjects(UnalignedHeader chunk, GreyToBlackObjectVisitor visitor, boolean clean) { throw VMError.shouldNotReachHere(); } @Override - public void walkDirtyObjects(Space space, GreyToBlackObjectVisitor visitor) { + public void walkDirtyObjects(Space space, GreyToBlackObjectVisitor visitor, boolean clean) { throw VMError.shouldNotReachHere(); } diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/remset/RememberedSet.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/remset/RememberedSet.java index b69553846b19..8b0a4d09b293 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/remset/RememberedSet.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/remset/RememberedSet.java @@ -44,9 +44,9 @@ import jdk.vm.ci.meta.MetaAccessProvider; /** - * A remembered set keeps track where the image heap or old generation has references to the young - * generation. When collecting the young generation, the remembered set is used to avoid having to - * scan through the whole image heap and old generation. + * A remembered set keeps track of references between generations (from the old generation to the + * young generation, or from the image heap to the runtime heap). During collections, the remembered + * set is used to avoid scanning the entire image heap and old generation. */ public interface RememberedSet { @Fold @@ -107,22 +107,24 @@ static RememberedSet get() { /** * Marks an object as dirty. May only be called for objects for which remembered set tracking is - * enabled. This tells the GC that the object may contain a reference to the young generation. + * enabled. This tells the GC that the object may contain a reference to another generation + * (from old generation to young generation, or from image heap to runtime heap). */ @AlwaysInline("GC performance") void dirtyCardForAlignedObject(Object object, boolean verifyOnly); /** * Marks an object as dirty. May only be called for objects for which remembered set tracking is - * enabled. This tells the GC that the object may contain a reference to the young generation. + * enabled. This tells the GC that the object may contain a reference to another generation + * (from old generation to young generation, or from image heap to runtime heap). */ @AlwaysInline("GC performance") void dirtyCardForUnalignedObject(Object object, boolean verifyOnly); /** - * Marks the {@code holderObject} as dirty if {@code object} is in the young generation. May - * only be called for {@code holderObject}s for which remembered set tracking is enabled. This - * tells the GC that the {@code holderObject} may contain a reference to the young generation. + * Marks the {@code holderObject} as dirty if needed according to the location of + * {@code object}. May only be called for {@code holderObject}s for which remembered set + * tracking is enabled. */ @AlwaysInline("GC performance") void dirtyCardIfNecessary(Object holderObject, Object object); @@ -130,17 +132,17 @@ static RememberedSet get() { /** * Walks all dirty objects in an aligned chunk. */ - void walkDirtyObjects(AlignedHeader chunk, GreyToBlackObjectVisitor visitor); + void walkDirtyObjects(AlignedHeader chunk, GreyToBlackObjectVisitor visitor, boolean clean); /** * Walks all dirty objects in an unaligned chunk. */ - void walkDirtyObjects(UnalignedHeader chunk, GreyToBlackObjectVisitor visitor); + void walkDirtyObjects(UnalignedHeader chunk, GreyToBlackObjectVisitor visitor, boolean clean); /** * Walks all dirty objects in a {@link Space}. */ - void walkDirtyObjects(Space space, GreyToBlackObjectVisitor visitor); + void walkDirtyObjects(Space space, GreyToBlackObjectVisitor visitor, boolean clean); /** * Verify the remembered set for an aligned chunk. diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/remset/UnalignedChunkRememberedSet.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/remset/UnalignedChunkRememberedSet.java index 5de36561eba1..1e993fb3f30f 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/remset/UnalignedChunkRememberedSet.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/remset/UnalignedChunkRememberedSet.java @@ -86,11 +86,13 @@ public static void dirtyCardForObject(Object obj, boolean verifyOnly) { } } - public static void walkDirtyObjects(UnalignedHeader chunk, GreyToBlackObjectVisitor visitor) { + public static void walkDirtyObjects(UnalignedHeader chunk, GreyToBlackObjectVisitor visitor, boolean clean) { Pointer rememberedSetStart = getCardTableStart(chunk); UnsignedWord objectIndex = getObjectIndex(); if (CardTable.isDirty(rememberedSetStart, objectIndex)) { - CardTable.setClean(rememberedSetStart, objectIndex); + if (clean) { + CardTable.setClean(rememberedSetStart, objectIndex); + } Pointer objectsStart = UnalignedHeapChunk.getObjectStart(chunk); Object obj = objectsStart.toObject(); From 3b1a421aba08a4f320ffcf4f0dd3cff2bc49b4b4 Mon Sep 17 00:00:00 2001 From: Peter Hofer Date: Fri, 6 Aug 2021 22:24:45 +0200 Subject: [PATCH 2/3] @Fold HeapPolicy.getMaxSurvivorSpaces. --- .../src/com/oracle/svm/core/genscavenge/HeapPolicy.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/HeapPolicy.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/HeapPolicy.java index 2f846e499b19..75f3eb0a5192 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/HeapPolicy.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/HeapPolicy.java @@ -86,7 +86,7 @@ public static UnsignedWord m(long bytes) { return WordFactory.unsigned(bytes).multiply(1024).multiply(1024); } - @Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true) + @Fold public static int getMaxSurvivorSpaces() { return HeapPolicyOptions.MaxSurvivorSpaces.getValue(); } From b632da125e83cfe8213fc2c64fb3d3a5fe604579 Mon Sep 17 00:00:00 2001 From: Peter Hofer Date: Sat, 7 Aug 2021 10:55:29 +0200 Subject: [PATCH 3/3] Fix wrong naming in ImageHeapInfo. --- .../oracle/svm/core/genscavenge/GCImpl.java | 4 ++-- .../svm/core/genscavenge/HeapVerifier.java | 8 +++---- .../svm/core/genscavenge/ImageHeapInfo.java | 22 +++++++++---------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GCImpl.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GCImpl.java index 756ac4aad5ef..a4629b00c2eb 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GCImpl.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GCImpl.java @@ -810,12 +810,12 @@ private void blackenDirtyImageHeapRoots() { Timer blackenImageHeapRootsTimer = timers.blackenImageHeapRoots.open(); try { ImageHeapInfo info = HeapImpl.getImageHeapInfo(); - blackenDirtyImageHeapChunkRoots(info.getFirstAlignedImageHeapChunk(), info.getFirstUnalignedImageHeapChunk()); + blackenDirtyImageHeapChunkRoots(info.getFirstWritableAlignedChunk(), info.getFirstWritableUnalignedChunk()); if (AuxiliaryImageHeap.isPresent()) { ImageHeapInfo auxInfo = AuxiliaryImageHeap.singleton().getImageHeapInfo(); if (auxInfo != null) { - blackenDirtyImageHeapChunkRoots(auxInfo.getFirstAlignedImageHeapChunk(), auxInfo.getFirstUnalignedImageHeapChunk()); + blackenDirtyImageHeapChunkRoots(auxInfo.getFirstWritableAlignedChunk(), auxInfo.getFirstWritableUnalignedChunk()); } } } finally { diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/HeapVerifier.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/HeapVerifier.java index cf6c13d4e9b2..57d06343857c 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/HeapVerifier.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/HeapVerifier.java @@ -77,8 +77,8 @@ private static boolean verifyImageHeapObjects() { private static boolean verifyChunkedImageHeap() { boolean success = true; ImageHeapInfo info = HeapImpl.getImageHeapInfo(); - success &= verifyAlignedChunks(null, info.getFirstAlignedImageHeapChunk()); - success &= verifyUnalignedChunks(null, info.getFirstUnalignedImageHeapChunk()); + success &= verifyAlignedChunks(null, info.getFirstWritableAlignedChunk()); + success &= verifyUnalignedChunks(null, info.getFirstWritableUnalignedChunk()); return success; } @@ -161,8 +161,8 @@ private static boolean verifyRememberedSets() { * GC itself may result in dirty cards. */ ImageHeapInfo info = HeapImpl.getImageHeapInfo(); - success &= rememberedSet.verify(info.getFirstAlignedImageHeapChunk()); - success &= rememberedSet.verify(info.getFirstUnalignedImageHeapChunk()); + success &= rememberedSet.verify(info.getFirstWritableAlignedChunk()); + success &= rememberedSet.verify(info.getFirstWritableUnalignedChunk()); } OldGeneration oldGeneration = HeapImpl.getHeapImpl().getOldGeneration(); diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/ImageHeapInfo.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/ImageHeapInfo.java index 8daa41fb3649..9bb0430f8942 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/ImageHeapInfo.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/ImageHeapInfo.java @@ -68,8 +68,8 @@ public final class ImageHeapInfo { @UnknownObjectField(types = Object.class) public Object firstObject; @UnknownObjectField(types = Object.class) public Object lastObject; - @UnknownPrimitiveField public long offsetOfFirstAlignedChunkWithRememberedSet; - @UnknownPrimitiveField public long offsetOfFirstUnalignedChunkWithRememberedSet; + @UnknownPrimitiveField public long offsetOfFirstWritableAlignedChunk; + @UnknownPrimitiveField public long offsetOfFirstWritableUnalignedChunk; @UnknownPrimitiveField public int dynamicHubCount; @@ -80,10 +80,10 @@ public ImageHeapInfo() { public void initialize(Object firstReadOnlyPrimitiveObject, Object lastReadOnlyPrimitiveObject, Object firstReadOnlyReferenceObject, Object lastReadOnlyReferenceObject, Object firstReadOnlyRelocatableObject, Object lastReadOnlyRelocatableObject, Object firstWritablePrimitiveObject, Object lastWritablePrimitiveObject, Object firstWritableReferenceObject, Object lastWritableReferenceObject, Object firstWritableHugeObject, Object lastWritableHugeObject, - Object firstReadOnlyHugeObject, Object lastReadOnlyHugeObject, long offsetOfFirstAlignedChunkWithRememberedSet, long offsetOfFirstUnalignedChunkWithRememberedSet, + Object firstReadOnlyHugeObject, Object lastReadOnlyHugeObject, long offsetOfFirstWritableAlignedChunk, long offsetOfFirstWritableUnalignedChunk, int dynamicHubCount) { - assert offsetOfFirstAlignedChunkWithRememberedSet == NO_CHUNK || offsetOfFirstAlignedChunkWithRememberedSet >= 0; - assert offsetOfFirstUnalignedChunkWithRememberedSet == NO_CHUNK || offsetOfFirstUnalignedChunkWithRememberedSet >= 0; + assert offsetOfFirstWritableAlignedChunk == NO_CHUNK || offsetOfFirstWritableAlignedChunk >= 0; + assert offsetOfFirstWritableUnalignedChunk == NO_CHUNK || offsetOfFirstWritableUnalignedChunk >= 0; this.firstReadOnlyPrimitiveObject = firstReadOnlyPrimitiveObject; this.lastReadOnlyPrimitiveObject = lastReadOnlyPrimitiveObject; @@ -99,8 +99,8 @@ public void initialize(Object firstReadOnlyPrimitiveObject, Object lastReadOnlyP this.lastWritableHugeObject = lastWritableHugeObject; this.firstReadOnlyHugeObject = firstReadOnlyHugeObject; this.lastReadOnlyHugeObject = lastReadOnlyHugeObject; - this.offsetOfFirstAlignedChunkWithRememberedSet = offsetOfFirstAlignedChunkWithRememberedSet; - this.offsetOfFirstUnalignedChunkWithRememberedSet = offsetOfFirstUnalignedChunkWithRememberedSet; + this.offsetOfFirstWritableAlignedChunk = offsetOfFirstWritableAlignedChunk; + this.offsetOfFirstWritableUnalignedChunk = offsetOfFirstWritableUnalignedChunk; this.dynamicHubCount = dynamicHubCount; // Compute boundaries for checks considering partitions can be empty (first == last == null) @@ -184,12 +184,12 @@ public boolean isInImageHeap(Pointer objectPointer) { return result; } - public AlignedHeader getFirstAlignedImageHeapChunk() { - return asImageHeapChunk(offsetOfFirstAlignedChunkWithRememberedSet); + public AlignedHeader getFirstWritableAlignedChunk() { + return asImageHeapChunk(offsetOfFirstWritableAlignedChunk); } - public UnalignedHeader getFirstUnalignedImageHeapChunk() { - return asImageHeapChunk(offsetOfFirstUnalignedChunkWithRememberedSet); + public UnalignedHeader getFirstWritableUnalignedChunk() { + return asImageHeapChunk(offsetOfFirstWritableUnalignedChunk); } @SuppressWarnings("unchecked")