Skip to content

Commit c698f80

Browse files
Various cleanups and fixes for the parallel GC.
1 parent b338cb3 commit c698f80

File tree

6 files changed

+205
-162
lines changed

6 files changed

+205
-162
lines changed

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

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -210,17 +210,15 @@ private Pointer allocateMemoryParallel(UnsignedWord objectSize) {
210210
}
211211
}
212212
/* Slow-path: try allocating a new chunk for the requested memory. */
213-
return allocateInNewChunkParallel(oldChunk, objectSize);
213+
return allocateInNewChunkParallel(objectSize);
214214
}
215215

216216
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
217-
private Pointer allocateInNewChunkParallel(AlignedHeapChunk.AlignedHeader oldChunk, UnsignedWord objectSize) {
217+
private Pointer allocateInNewChunkParallel(UnsignedWord objectSize) {
218218
AlignedHeapChunk.AlignedHeader newChunk;
219219
ParallelGC.singleton().getMutex().lockNoTransitionUnspecifiedOwner();
220220
try {
221-
if (oldChunk.isNonNull()) {
222-
ParallelGC.singleton().pushAllocChunk(oldChunk);
223-
}
221+
ParallelGC.singleton().pushAllocChunk();
224222
newChunk = requestAlignedHeapChunk();
225223
} finally {
226224
ParallelGC.singleton().getMutex().unlockNoTransitionUnspecifiedOwner();
@@ -361,7 +359,7 @@ private void extractUnalignedHeapChunk(UnalignedHeapChunk.UnalignedHeader uChunk
361359
private static boolean verifyMutualExclusionForAppendChunk() {
362360
return !SubstrateOptions.MultiThreaded.getValue() ||
363361
VMThreads.ownsThreadMutex(true) ||
364-
ParallelGC.isEnabled() && VMOperation.isGCInProgress() && ParallelGC.singleton().isInParallelPhase() && ParallelGC.singleton().getMutex().isOwner();
362+
ParallelGC.isEnabled() && VMOperation.isGCInProgress() && ParallelGC.singleton().isInParallelPhase() && ParallelGC.singleton().getMutex().isOwner(true);
365363
}
366364

367365
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)

substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/jvmstat/SerialGCPerfData.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import com.oracle.svm.core.genscavenge.HeapAccounting;
3535
import com.oracle.svm.core.genscavenge.HeapImpl;
3636
import com.oracle.svm.core.genscavenge.HeapParameters;
37+
import com.oracle.svm.core.genscavenge.parallel.ParallelGC;
3738
import com.oracle.svm.core.jvmstat.PerfDataHolder;
3839
import com.oracle.svm.core.jvmstat.PerfLongConstant;
3940
import com.oracle.svm.core.jvmstat.PerfLongCounter;
@@ -45,6 +46,7 @@
4546
/**
4647
* Performance data for our serial GC.
4748
*/
49+
// TODO (chaeubl): rename this class
4850
public class SerialGCPerfData implements PerfDataHolder {
4951
private final PerfDataGCPolicy gcPolicy;
5052
private final PerfDataCollector youngCollector;
@@ -78,7 +80,9 @@ public void allocate() {
7880
gcPolicy.allocate();
7981

8082
youngCollector.allocate("Serial young collection pauses");
81-
oldCollector.allocate("Serial full collection pauses");
83+
84+
String oldCollectorName = ParallelGC.isEnabled() ? "Parallel" : "Serial";
85+
oldCollector.allocate(oldCollectorName + " full collection pauses");
8286

8387
youngGen.allocate("young");
8488
youngGen.spaces[0].allocate("eden");
Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,15 @@
4040
import com.oracle.svm.core.util.VMError;
4141

4242
/**
43-
* Synchronized buffer that stores pointers into "grey" heap chunks that need to be scanned. Note
44-
* that the pointers don't necessarily point to the beginning of a chunk.
43+
* A queue that stores pointers into "grey" heap chunks that need to be scanned. Note that the
44+
* pointers don't necessarily point to the beginning of a chunk. GC workers threads may only access
45+
* the queue if they hold {@link ParallelGC#getMutex()}.
4546
*/
46-
public class ChunkBuffer {
47+
public class ChunkQueue {
4748
private static final int INITIAL_SIZE = 1024 * wordSize();
4849

4950
private Pointer buffer;
50-
private int size = INITIAL_SIZE;
51+
private int size;
5152
private int top;
5253

5354
@Fold
@@ -56,42 +57,39 @@ static int wordSize() {
5657
}
5758

5859
@Platforms(Platform.HOSTED_ONLY.class)
59-
ChunkBuffer() {
60+
ChunkQueue() {
6061
}
6162

6263
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
6364
public void initialize() {
65+
assert top == 0 && size == 0 && buffer.isNull();
66+
top = 0;
67+
size = INITIAL_SIZE;
6468
buffer = ImageSingletons.lookup(UnmanagedMemorySupport.class).malloc(WordFactory.unsigned(size));
65-
VMError.guarantee(buffer.isNonNull());
69+
VMError.guarantee(buffer.isNonNull(), "Failed to allocate native memory for the ChunkBuffer.");
6670
}
6771

6872
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
6973
void push(Pointer ptr) {
70-
assert !ParallelGC.singleton().isInParallelPhase() && VMThreads.ownsThreadMutex() || ParallelGC.singleton().getMutex().hasOwner();
74+
assert !ParallelGC.singleton().isInParallelPhase() && VMThreads.ownsThreadMutex() || ParallelGC.singleton().isInParallelPhase() && ParallelGC.singleton().getMutex().isOwner(true);
7175
if (top >= size) {
7276
size *= 2;
7377
assert top < size;
7478
buffer = ImageSingletons.lookup(UnmanagedMemorySupport.class).realloc(buffer, WordFactory.unsigned(size));
75-
VMError.guarantee(buffer.isNonNull());
79+
VMError.guarantee(buffer.isNonNull(), "Failed to allocate native memory for the ChunkBuffer.");
7680
}
7781
buffer.writeWord(top, ptr);
7882
top += wordSize();
7983
}
8084

8185
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
8286
Pointer pop() {
83-
assert ParallelGC.singleton().isInParallelPhase();
84-
ParallelGC.singleton().getMutex().lockNoTransitionUnspecifiedOwner();
85-
try {
86-
if (top > 0) {
87-
top -= wordSize();
88-
return buffer.readWord(top);
89-
} else {
90-
return WordFactory.nullPointer();
91-
}
92-
} finally {
93-
ParallelGC.singleton().getMutex().unlockNoTransitionUnspecifiedOwner();
87+
assert ParallelGC.singleton().isInParallelPhase() && ParallelGC.singleton().getMutex().isOwner(true);
88+
if (top > 0) {
89+
top -= wordSize();
90+
return buffer.readWord(top);
9491
}
92+
return WordFactory.nullPointer();
9593
}
9694

9795
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
@@ -101,7 +99,10 @@ boolean isEmpty() {
10199
}
102100

103101
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
104-
void release() {
102+
void teardown() {
105103
ImageSingletons.lookup(UnmanagedMemorySupport.class).free(buffer);
104+
buffer = WordFactory.nullPointer();
105+
size = 0;
106+
top = 0;
106107
}
107108
}

0 commit comments

Comments
 (0)