From 983e2777d0b1574bcc5ef91fd962d61a25899c39 Mon Sep 17 00:00:00 2001 From: Peter Hofer Date: Fri, 5 Jan 2024 18:18:18 +0100 Subject: [PATCH] Avoid needlessly rescanning objects. --- .../svm/core/genscavenge/AlignedHeapChunk.java | 4 ++-- .../svm/core/genscavenge/GreyObjectsWalker.java | 6 +++++- .../com/oracle/svm/core/genscavenge/HeapChunk.java | 14 +++++++------- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/AlignedHeapChunk.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/AlignedHeapChunk.java index e45c244257d0..8e45dbc58ced 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/AlignedHeapChunk.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/AlignedHeapChunk.java @@ -149,8 +149,8 @@ static boolean walkObjects(AlignedHeader that, ObjectVisitor visitor) { @AlwaysInline("GC performance") @Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true) - static boolean walkObjectsInline(AlignedHeader that, ObjectVisitor visitor) { - return HeapChunk.walkObjectsFromInline(that, getObjectsStart(that), visitor); + static boolean walkObjectsFromInline(AlignedHeader that, Pointer start, ObjectVisitor visitor) { + return HeapChunk.walkObjectsFromInline(that, start, visitor); } @Fold diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GreyObjectsWalker.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GreyObjectsWalker.java index 09ad12fd3568..c0d70a40f52b 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GreyObjectsWalker.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GreyObjectsWalker.java @@ -87,12 +87,15 @@ void walkGreyObjects() { @Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true) private void walkAlignedGreyObjects() { AlignedHeapChunk.AlignedHeader aChunk; + Pointer aStart; if (alignedHeapChunk.isNull() && alignedTop.isNull()) { /* If the snapshot is empty, then I have to walk from the beginning of the Space. */ aChunk = space.getFirstAlignedHeapChunk(); + aStart = (aChunk.isNonNull() ? AlignedHeapChunk.getObjectsStart(aChunk) : WordFactory.nullPointer()); } else { /* Otherwise walk Objects that arrived after the snapshot. */ aChunk = alignedHeapChunk; + aStart = alignedTop; } /* Visit Objects in the AlignedChunks. */ GreyToBlackObjectVisitor visitor = GCImpl.getGCImpl().getGreyToBlackObjectVisitor(); @@ -100,10 +103,11 @@ private void walkAlignedGreyObjects() { AlignedHeapChunk.AlignedHeader lastChunk; do { lastChunk = aChunk; - if (!AlignedHeapChunk.walkObjectsInline(aChunk, visitor)) { + if (!AlignedHeapChunk.walkObjectsFromInline(aChunk, aStart, visitor)) { throw VMError.shouldNotReachHereAtRuntime(); } aChunk = HeapChunk.getNext(aChunk); + aStart = (aChunk.isNonNull() ? AlignedHeapChunk.getObjectsStart(aChunk) : WordFactory.nullPointer()); } while (aChunk.isNonNull()); /* Move the scan point. */ diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/HeapChunk.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/HeapChunk.java index 33d7acb9f0b6..84406410daf5 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/HeapChunk.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/HeapChunk.java @@ -297,20 +297,20 @@ private static SignedWord offsetFromPointer(Header that, PointerBase pointer) } @NeverInline("Not performance critical") - public static boolean walkObjectsFrom(Header that, Pointer offset, ObjectVisitor visitor) { - return walkObjectsFromInline(that, offset, visitor); + public static boolean walkObjectsFrom(Header that, Pointer start, ObjectVisitor visitor) { + return walkObjectsFromInline(that, start, visitor); } @AlwaysInline("GC performance") @Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true) - public static boolean walkObjectsFromInline(Header that, Pointer startOffset, ObjectVisitor visitor) { - Pointer offset = startOffset; - while (offset.belowThan(getTopPointer(that))) { // crucial: top can move, so always re-read - Object obj = offset.toObject(); + public static boolean walkObjectsFromInline(Header that, Pointer start, ObjectVisitor visitor) { + Pointer p = start; + while (p.belowThan(getTopPointer(that))) { // crucial: top can move, so always re-read + Object obj = p.toObject(); if (!callVisitor(visitor, obj)) { return false; } - offset = offset.add(LayoutEncoding.getSizeFromObjectInlineInGC(obj)); + p = p.add(LayoutEncoding.getSizeFromObjectInlineInGC(obj)); } return true; }