Skip to content

Commit 4370d98

Browse files
author
Thomas Schrott
committed
Allocate TLAB as part of chunks and size them dynamically
1 parent ba37569 commit 4370d98

File tree

9 files changed

+697
-229
lines changed

9 files changed

+697
-229
lines changed

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

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -221,10 +221,7 @@ public static final class OnlyCompletely extends BasicPolicy {
221221

222222
@Override
223223
public boolean shouldCollectCompletely(boolean followingIncrementalCollection) {
224-
if (!followingIncrementalCollection && shouldCollectYoungGenSeparately(false)) {
225-
return false;
226-
}
227-
return true;
224+
return followingIncrementalCollection || !shouldCollectYoungGenSeparately(false);
228225
}
229226

230227
@Override

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ assert getCollectionEpoch().equal(data.getRequestingEpoch()) ||
260260
collectionTimer.stop();
261261
}
262262

263+
resizeAllTlabs();
263264
accounting.updateCollectionCountAndTime(completeCollection, collectionTimer.totalNanos());
264265
HeapImpl.getAccounting().notifyAfterCollection();
265266
GenScavengeMemoryPoolMXBeans.singleton().notifyAfterCollection();
@@ -402,6 +403,14 @@ public static UnsignedWord getChunkBytes() {
402403
return youngBytes.add(oldBytes);
403404
}
404405

406+
private static void resizeAllTlabs() {
407+
if (SubstrateGCOptions.TlabOptions.ResizeTLAB.getValue()) {
408+
for (IsolateThread thread = VMThreads.firstThread(); thread.isNonNull(); thread = VMThreads.nextThread(thread)) {
409+
TlabSupport.resize(thread);
410+
}
411+
}
412+
}
413+
405414
private void printGCBefore(GCCause cause) {
406415
if (!SubstrateGCOptions.VerboseGC.getValue()) {
407416
return;
@@ -1317,7 +1326,7 @@ protected PrintGCSummaryOperation() {
13171326

13181327
@Override
13191328
protected void operate() {
1320-
ThreadLocalAllocation.disableAndFlushForAllThreads();
1329+
HeapImpl.getHeapImpl().makeParseable();
13211330

13221331
Log log = Log.log();
13231332
log.string("GC summary").indent(true);

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

Lines changed: 8 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,6 @@
5050
import com.oracle.svm.core.annotate.Substitute;
5151
import com.oracle.svm.core.annotate.TargetClass;
5252
import com.oracle.svm.core.genscavenge.AlignedHeapChunk.AlignedHeader;
53-
import com.oracle.svm.core.genscavenge.ThreadLocalAllocation.Descriptor;
54-
import com.oracle.svm.core.genscavenge.UnalignedHeapChunk.UnalignedHeader;
5553
import com.oracle.svm.core.genscavenge.graal.nodes.FormatArrayNode;
5654
import com.oracle.svm.core.genscavenge.remset.RememberedSet;
5755
import com.oracle.svm.core.graal.snippets.SubstrateAllocationSnippets;
@@ -196,7 +194,7 @@ public boolean isInPrimaryImageHeap(Pointer objPointer) {
196194
@Override
197195
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
198196
public void suspendAllocation() {
199-
ThreadLocalAllocation.suspendInCurrentThread();
197+
TlabSupport.suspendAllocationInCurrentThread();
200198
}
201199

202200
@Override
@@ -415,13 +413,14 @@ public void endSafepoint() {
415413
@Uninterruptible(reason = "Called during startup.")
416414
@Override
417415
public void attachThread(IsolateThread isolateThread) {
418-
// nothing to do
416+
TlabSupport.startupInitialization();
417+
TlabSupport.initialize(isolateThread);
419418
}
420419

421420
@Override
422421
@Uninterruptible(reason = "Thread is detaching and holds the THREAD_MUTEX.")
423422
public void detachThread(IsolateThread isolateThread) {
424-
ThreadLocalAllocation.disableAndFlushForThread(isolateThread);
423+
TlabSupport.disableAndFlushForThread(isolateThread);
425424
}
426425

427426
@Fold
@@ -707,7 +706,7 @@ public void optionValueChanged(RuntimeOptionKey<?> key) {
707706
@Override
708707
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
709708
public long getThreadAllocatedMemory(IsolateThread thread) {
710-
UnsignedWord allocatedBytes = ThreadLocalAllocation.allocatedBytes.getVolatile(thread);
709+
UnsignedWord allocatedBytes = ThreadLocalAllocation.getAllocatedBytes(thread);
711710

712711
/*
713712
* The current aligned chunk in the TLAB is only partially filled and therefore not yet
@@ -717,9 +716,8 @@ public long getThreadAllocatedMemory(IsolateThread thread) {
717716
* can cause that the memory in the current aligned TLAB chunk is counted twice.
718717
*/
719718
ThreadLocalAllocation.Descriptor tlab = ThreadLocalAllocation.getTlab(thread);
720-
AlignedHeader alignedTlab = tlab.getAlignedChunk();
719+
Pointer start = tlab.getAlignedAllocationStart(SubstrateAllocationSnippets.TLAB_START_IDENTITY);
721720
Pointer top = tlab.getAllocationTop(SubstrateAllocationSnippets.TLAB_TOP_IDENTITY);
722-
Pointer start = AlignedHeapChunk.getObjectsStart(alignedTlab);
723721

724722
if (top.aboveThan(start)) {
725723
UnsignedWord usedTlabSize = top.subtract(start);
@@ -787,7 +785,7 @@ private boolean printLocationInfo(Log log, Pointer ptr, boolean allowJavaHeapAcc
787785
if (AuxiliaryImageHeap.isPresent() && AuxiliaryImageHeap.singleton().containsObject(ptr)) {
788786
log.string("points into the auxiliary image heap");
789787
return true;
790-
} else if (printTlabInfo(log, ptr, CurrentIsolate.getCurrentThread())) {
788+
} else if (TlabSupport.printTlabInfo(log, ptr, CurrentIsolate.getCurrentThread())) {
791789
return true;
792790
}
793791

@@ -805,7 +803,7 @@ private boolean printLocationInfo(Log log, Pointer ptr, boolean allowJavaHeapAcc
805803
* If we are not at a safepoint, then it is unsafe to access thread locals of another
806804
* thread as the IsolateThread could be freed at any time.
807805
*/
808-
if (printTlabInfo(log, ptr)) {
806+
if (TlabSupport.printTlabInfo(log, ptr)) {
809807
return true;
810808
}
811809
}
@@ -824,53 +822,6 @@ boolean isInHeap(Pointer ptr) {
824822
return isInImageHeap(ptr) || youngGeneration.isInSpace(ptr) || oldGeneration.isInSpace(ptr);
825823
}
826824

827-
private static boolean printTlabInfo(Log log, Pointer ptr) {
828-
for (IsolateThread thread = VMThreads.firstThreadUnsafe(); thread.isNonNull(); thread = VMThreads.nextThread(thread)) {
829-
if (printTlabInfo(log, ptr, thread)) {
830-
return true;
831-
}
832-
}
833-
return false;
834-
}
835-
836-
private static boolean printTlabInfo(Log log, Pointer ptr, IsolateThread thread) {
837-
ThreadLocalAllocation.Descriptor tlab = getTlabUnsafe(thread);
838-
AlignedHeader aChunk = tlab.getAlignedChunk();
839-
while (aChunk.isNonNull()) {
840-
if (HeapChunk.asPointer(aChunk).belowOrEqual(ptr) && ptr.belowThan(HeapChunk.getEndPointer(aChunk))) {
841-
/* top may be null for a thread's current aligned allocation chunk. */
842-
boolean unusablePart = HeapChunk.getTopPointer(aChunk).isNonNull() && ptr.aboveOrEqual(HeapChunk.getTopPointer(aChunk));
843-
printTlabChunkInfo(log, thread, aChunk, "aligned", unusablePart);
844-
return true;
845-
}
846-
aChunk = HeapChunk.getNext(aChunk);
847-
}
848-
849-
UnalignedHeader uChunk = tlab.getUnalignedChunk();
850-
while (uChunk.isNonNull()) {
851-
if (HeapChunk.asPointer(uChunk).belowOrEqual(ptr) && ptr.belowThan(HeapChunk.getEndPointer(uChunk))) {
852-
boolean unusablePart = ptr.aboveOrEqual(HeapChunk.getTopPointer(uChunk));
853-
printTlabChunkInfo(log, thread, uChunk, "unaligned", unusablePart);
854-
return true;
855-
}
856-
uChunk = HeapChunk.getNext(uChunk);
857-
}
858-
859-
return false;
860-
}
861-
862-
private static void printTlabChunkInfo(Log log, IsolateThread thread, HeapChunk.Header<?> chunk, String chunkType, boolean unusablePart) {
863-
String unusable = unusablePart ? "unusable part of " : "";
864-
log.string("points into ").string(unusable).string(chunkType).string(" chunk ").zhex(chunk).spaces(1);
865-
log.string("(TLAB of thread ").zhex(thread).string(")");
866-
}
867-
868-
@Uninterruptible(reason = "This whole method is unsafe, so it is only uninterruptible to satisfy the checks.")
869-
static Descriptor getTlabUnsafe(IsolateThread thread) {
870-
assert SubstrateDiagnostics.isFatalErrorHandlingThread() : "can cause crashes, so it may only be used while printing diagnostics";
871-
return ThreadLocalAllocation.getTlab(thread);
872-
}
873-
874825
@Override
875826
@Uninterruptible(reason = "Called during early startup.")
876827
public boolean verifyImageHeapMapping() {

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import com.oracle.svm.core.config.ConfigurationValues;
4141
import com.oracle.svm.core.genscavenge.GCImpl.ChunkReleaser;
4242
import com.oracle.svm.core.genscavenge.remset.RememberedSet;
43+
import com.oracle.svm.core.graal.snippets.SubstrateAllocationSnippets;
4344
import com.oracle.svm.core.heap.Heap;
4445
import com.oracle.svm.core.heap.ObjectHeader;
4546
import com.oracle.svm.core.heap.ObjectVisitor;
@@ -549,7 +550,7 @@ private static boolean areEdenBytesCorrect() {
549550
/* Verify that there are no threads that have a TLAB. */
550551
for (IsolateThread thread = VMThreads.firstThread(); thread.isNonNull(); thread = VMThreads.nextThread(thread)) {
551552
ThreadLocalAllocation.Descriptor tlab = ThreadLocalAllocation.getTlab(thread);
552-
if (tlab.getAlignedChunk().isNonNull() || tlab.getUnalignedChunk().isNonNull()) {
553+
if (tlab.getAlignedAllocationStart(SubstrateAllocationSnippets.TLAB_START_IDENTITY).isNonNull() || tlab.getUnalignedChunk().isNonNull()) {
553554
return false;
554555
}
555556
}

0 commit comments

Comments
 (0)