Skip to content

Commit 996913e

Browse files
committed
Write first object table during planning.
1 parent f405fcc commit 996913e

File tree

5 files changed

+54
-26
lines changed

5 files changed

+54
-26
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -395,8 +395,8 @@ private void compact(Timers timers) {
395395
* chunk during compaction. The remembered set bits are already set after planning.
396396
*/
397397
if (!AlignedHeapChunk.isEmpty(chunk)) {
398-
RememberedSet.get().enableRememberedSetForChunk(chunk);
399-
} // empty chunks will be freed or reset before reuse, no need to reinitialize here
398+
RememberedSet.get().clearRememberedSet(chunk);
399+
} // else: chunks will be freed or reset before reuse, no need to reinitialize here
400400

401401
chunk = HeapChunk.getNext(chunk);
402402
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,7 @@ private Object copyAlignedObject(Object originalObj) {
449449
if (SerialGCOptions.useCompactingOldGen() && GCImpl.getGCImpl().isCompleteCollection()) {
450450
/*
451451
* In a compacting complete collection, the remembered set bit is set already during
452-
* marking and the first object table is built later during compaction.
452+
* marking and the first object table is built during planning.
453453
*/
454454
} else {
455455
/*

substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/compacting/PlanningVisitor.java

Lines changed: 47 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@
3535
import com.oracle.svm.core.genscavenge.HeapChunk;
3636
import com.oracle.svm.core.genscavenge.ObjectHeaderImpl;
3737
import com.oracle.svm.core.genscavenge.Space;
38+
import com.oracle.svm.core.genscavenge.remset.AlignedChunkRememberedSet;
3839
import com.oracle.svm.core.genscavenge.remset.BrickTable;
40+
import com.oracle.svm.core.genscavenge.remset.FirstObjectTable;
3941
import com.oracle.svm.core.hub.LayoutEncoding;
4042

4143
import jdk.graal.compiler.word.Word;
@@ -57,6 +59,9 @@ public PlanningVisitor() {
5759
public void init(Space space) {
5860
allocChunk = space.getFirstAlignedHeapChunk();
5961
allocPointer = AlignedHeapChunk.getObjectsStart(allocChunk);
62+
if (!allocChunk.getShouldSweepInsteadOfCompact()) {
63+
FirstObjectTable.initializeTable(AlignedChunkRememberedSet.getFirstObjectTableStart(allocChunk), AlignedChunkRememberedSet.getFirstObjectTableSize());
64+
}
6065
}
6166

6267
@Override
@@ -70,7 +75,7 @@ public boolean visitChunk(AlignedHeapChunk.AlignedHeader chunk) {
7075
UnsignedWord brickIndex = WordFactory.zero();
7176

7277
/* Initialize the move info structure at the chunk's object start location. */
73-
ObjectMoveInfo.setNewAddress(objSeq, allocPointer);
78+
ObjectMoveInfo.setNewAddress(objSeq, objSeq);
7479
ObjectMoveInfo.setObjectSeqSize(objSeq, WordFactory.zero());
7580
ObjectMoveInfo.setNextObjectSeqOffset(objSeq, WordFactory.zero());
7681

@@ -116,11 +121,43 @@ public boolean visitChunk(AlignedHeapChunk.AlignedHeader chunk) {
116121
}
117122

118123
objSeqSize = objSeqSize.add(objSize);
124+
if (!sweeping) {
125+
if (allocPointer.add(objSeqSize).aboveThan(AlignedHeapChunk.getObjectsEnd(allocChunk))) {
126+
/* Out of space, move to the start of the next chunk. */
127+
allocChunk = HeapChunk.getNext(allocChunk);
128+
assert allocChunk.isNonNull();
129+
assert !allocChunk.getShouldSweepInsteadOfCompact();
130+
allocPointer = AlignedHeapChunk.getObjectsStart(allocChunk);
131+
132+
/*
133+
* TODO: we should reset the FOT entries we already wrote in the last chunk
134+
* (but they should not be accessed, not even by heap verification)
135+
*/
136+
137+
/* Visit previous objects in sequence again to write new FOT entries. */
138+
FirstObjectTable.initializeTable(AlignedChunkRememberedSet.getFirstObjectTableStart(allocChunk), AlignedChunkRememberedSet.getFirstObjectTableSize());
139+
Pointer q = objSeq;
140+
while (q.notEqual(p)) {
141+
UnsignedWord offset = q.subtract(objSeq);
142+
UnsignedWord size = LayoutEncoding.getSizeFromObjectInlineInGC(q.toObject());
143+
FirstObjectTable.setTableForObject(AlignedChunkRememberedSet.getFirstObjectTableStart(allocChunk), offset, offset.add(size));
144+
q = q.add(size);
145+
}
146+
}
147+
148+
Pointer allocEndOffset = allocPointer.add(objSeqSize).subtract(AlignedHeapChunk.getObjectsStart(allocChunk));
149+
FirstObjectTable.setTableForObject(AlignedChunkRememberedSet.getFirstObjectTableStart(allocChunk), allocEndOffset.subtract(objSize), allocEndOffset);
150+
}
151+
119152
} else { // not marked, i.e. not alive and start of a gap of yet unknown size
120153
if (objSeqSize.notEqual(0)) { // end of an object sequence
121-
Pointer newAddress = sweeping ? objSeq : allocate(objSeqSize);
122-
ObjectMoveInfo.setNewAddress(objSeq, newAddress);
123154
ObjectMoveInfo.setObjectSeqSize(objSeq, objSeqSize);
155+
if (sweeping) {
156+
ObjectMoveInfo.setNewAddress(objSeq, objSeq);
157+
} else {
158+
ObjectMoveInfo.setNewAddress(objSeq, allocPointer);
159+
allocPointer = allocPointer.add(objSeqSize); // ensured enough memory above
160+
}
124161

125162
objSeqSize = WordFactory.zero();
126163

@@ -137,13 +174,17 @@ public boolean visitChunk(AlignedHeapChunk.AlignedHeader chunk) {
137174
}
138175
assert gapSize.equal(0) || objSeqSize.equal(0);
139176

140-
/* A gap at the end of the chunk requires updating the chunk top. */
141177
if (gapSize.notEqual(0)) {
142178
chunk.setTopOffset(chunk.getTopOffset().subtract(gapSize));
179+
143180
} else if (objSeqSize.notEqual(0)) {
144-
Pointer newAddress = sweeping ? objSeq : allocate(objSeqSize);
145-
ObjectMoveInfo.setNewAddress(objSeq, newAddress);
146181
ObjectMoveInfo.setObjectSeqSize(objSeq, objSeqSize);
182+
if (sweeping) {
183+
ObjectMoveInfo.setNewAddress(objSeq, objSeq);
184+
} else {
185+
ObjectMoveInfo.setNewAddress(objSeq, allocPointer);
186+
allocPointer = allocPointer.add(objSeqSize); // ensured enough memory above
187+
}
147188
}
148189

149190
if (sweeping) {
@@ -169,17 +210,4 @@ public boolean visitChunk(AlignedHeapChunk.AlignedHeader chunk) {
169210

170211
return true;
171212
}
172-
173-
private Pointer allocate(UnsignedWord size) {
174-
Pointer p = allocPointer;
175-
allocPointer = allocPointer.add(size);
176-
if (allocPointer.aboveThan(AlignedHeapChunk.getObjectsEnd(allocChunk))) {
177-
allocChunk = HeapChunk.getNext(allocChunk);
178-
assert allocChunk.isNonNull();
179-
180-
p = AlignedHeapChunk.getObjectsStart(allocChunk);
181-
allocPointer = p.add(size);
182-
}
183-
return p;
184-
}
185213
}

substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/remset/AlignedChunkRememberedSet.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
import jdk.graal.compiler.replacements.nodes.AssertionNode;
5555
import jdk.graal.compiler.word.Word;
5656

57-
final class AlignedChunkRememberedSet {
57+
public final class AlignedChunkRememberedSet {
5858
private AlignedChunkRememberedSet() {
5959
}
6060

@@ -239,7 +239,7 @@ static UnsignedWord getCardTableSize() {
239239
}
240240

241241
@Fold
242-
static UnsignedWord getFirstObjectTableSize() {
242+
public static UnsignedWord getFirstObjectTableSize() {
243243
return getCardTableSize();
244244
}
245245

@@ -286,7 +286,7 @@ private static Pointer getCardTableStart(Pointer chunk) {
286286
}
287287

288288
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
289-
private static Pointer getFirstObjectTableStart(AlignedHeader chunk) {
289+
public static Pointer getFirstObjectTableStart(AlignedHeader chunk) {
290290
return getFirstObjectTableStart(HeapChunk.asPointer(chunk));
291291
}
292292

substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/remset/FirstObjectTable.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@
109109
* <p>
110110
* Implementation note: Table entries are bytes but converted to and from ints with bounds checks.
111111
*/
112-
final class FirstObjectTable {
112+
public final class FirstObjectTable {
113113
/**
114114
* The number of bytes of memory covered by an entry. Since the indexes into the CardTable are
115115
* used to index into the FirstObjectTable, these need to have the same value.

0 commit comments

Comments
 (0)