@@ -54,6 +54,11 @@ final class AlignedChunkRememberedSet {
5454 private AlignedChunkRememberedSet () {
5555 }
5656
57+ @ Fold
58+ public static int wordSize () {
59+ return ConfigurationValues .getTarget ().wordSize ;
60+ }
61+
5762 @ Fold
5863 public static UnsignedWord getHeaderSize () {
5964 UnsignedWord headerSize = getFirstObjectTableLimitOffset ();
@@ -126,28 +131,67 @@ public static void dirtyCardForObject(Object object, boolean verifyOnly) {
126131 }
127132
128133 public static void walkDirtyObjects (AlignedHeader chunk , GreyToBlackObjectVisitor visitor , boolean clean ) {
129- Pointer cardTableStart = getCardTableStart (chunk );
130- Pointer fotStart = getFirstObjectTableStart (chunk );
131134 Pointer objectsStart = AlignedHeapChunk .getObjectsStart (chunk );
132135 Pointer objectsLimit = HeapChunk .getTopPointer (chunk );
133136 UnsignedWord memorySize = objectsLimit .subtract (objectsStart );
134- UnsignedWord indexLimit = CardTable .indexLimitForMemorySize (memorySize );
135137
136- for (UnsignedWord index = WordFactory .zero (); index .belowThan (indexLimit ); index = index .add (1 )) {
137- if (CardTable .isDirty (cardTableStart , index )) {
138+ Pointer cardTableStart = getCardTableStart (chunk );
139+ Pointer cardTableLimit = cardTableStart .add (CardTable .tableSizeForMemorySize (memorySize ));
140+
141+ assert cardTableStart .unsignedRemainder (wordSize ()).equal (0 );
142+ assert getCardTableSize ().unsignedRemainder (wordSize ()).equal (0 );
143+
144+ Pointer dirtyHeapStart = objectsLimit ;
145+ Pointer dirtyHeapEnd = objectsLimit ;
146+ Pointer cardPos = cardTableLimit .subtract (1 );
147+ Pointer heapPos = CardTable .cardToHeapAddress (cardTableStart , cardPos , objectsStart );
148+
149+ while (cardPos .aboveOrEqual (cardTableStart )) {
150+ if (cardPos .readByte (0 ) != CardTable .CLEAN_ENTRY ) {
138151 if (clean ) {
139- CardTable .setClean (cardTableStart , index );
152+ cardPos .writeByte (0 , CardTable .CLEAN_ENTRY );
153+ }
154+ dirtyHeapStart = heapPos ;
155+ } else {
156+ /* Hit a clean card, so process the dirty range. */
157+ if (dirtyHeapStart .belowThan (dirtyHeapEnd )) {
158+ walkObjects (chunk , dirtyHeapStart , dirtyHeapEnd , visitor );
140159 }
141160
142- Pointer ptr = FirstObjectTable .getFirstObjectImprecise (fotStart , objectsStart , objectsLimit , index );
143- Pointer cardLimit = CardTable .indexToMemoryPointer (objectsStart , index .add (1 ));
144- Pointer walkLimit = PointerUtils .min (cardLimit , objectsLimit );
145- while (ptr .belowThan (walkLimit )) {
146- Object obj = ptr .toObject ();
147- visitor .visitObjectInline (obj );
148- ptr = LayoutEncoding .getObjectEndInlineInGC (obj );
161+ if (PointerUtils .isAMultiple (cardPos , WordFactory .unsigned (wordSize ()))) {
162+ /* Fast forward through word-aligned continuous range of clean cards. */
163+ cardPos = cardPos .subtract (wordSize ());
164+ while (cardPos .aboveOrEqual (cardTableStart ) && ((UnsignedWord ) cardPos .readWord (0 )).equal (CardTable .CLEAN_WORD )) {
165+ cardPos = cardPos .subtract (wordSize ());
166+ }
167+ cardPos = cardPos .add (wordSize ());
168+ heapPos = CardTable .cardToHeapAddress (cardTableStart , cardPos , objectsStart );
149169 }
170+
171+ /* Reset the dirty range. */
172+ dirtyHeapEnd = heapPos ;
173+ dirtyHeapStart = heapPos ;
150174 }
175+
176+ cardPos = cardPos .subtract (1 );
177+ heapPos = heapPos .subtract (CardTable .BYTES_COVERED_BY_ENTRY );
178+ }
179+
180+ /* Process the remaining dirty range. */
181+ if (dirtyHeapStart .belowThan (dirtyHeapEnd )) {
182+ walkObjects (chunk , dirtyHeapStart , dirtyHeapEnd , visitor );
183+ }
184+ }
185+
186+ private static void walkObjects (AlignedHeader chunk , Pointer start , Pointer end , GreyToBlackObjectVisitor visitor ) {
187+ Pointer fotStart = getFirstObjectTableStart (chunk );
188+ Pointer objectsStart = AlignedHeapChunk .getObjectsStart (chunk );
189+ UnsignedWord index = CardTable .memoryOffsetToIndex (start .subtract (objectsStart ));
190+ Pointer ptr = FirstObjectTable .getFirstObjectImprecise (fotStart , objectsStart , index );
191+ while (ptr .belowThan (end )) {
192+ Object obj = ptr .toObject ();
193+ visitor .visitObjectInline (obj );
194+ ptr = LayoutEncoding .getObjectEndInlineInGC (obj );
151195 }
152196 }
153197
0 commit comments