Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -409,10 +409,10 @@ public static void resize(IsolateThread thread) {

if (SerialAndEpsilonGCOptions.PrintTLAB.getValue()) {
Log.log().string("TLAB new size: thread ").zhex(thread)
.string(" target refills: ").unsigned(targetRefills)
.string(" alloc avg.: ").unsigned(allocatedAvg)
.string(" desired size: ").hex(desiredSize.get(thread))
.string(" -> ").hex(alignedNewSize).newline();
.string(", target refills: ").unsigned(targetRefills)
.string(", alloc avg.: ").unsigned(allocatedAvg)
.string(", desired size: ").unsigned(desiredSize.get(thread))
.string(" -> ").unsigned(alignedNewSize).newline();
}

desiredSize.set(thread, alignedNewSize);
Expand Down Expand Up @@ -498,13 +498,13 @@ private static void printStats(IsolateThread thread, UnsignedWord allocatedBytes

long waste = gcWaste.get(thread) + refillWaste.get(thread);
Log.log().string("TLAB: thread: ").zhex(thread)
.string(" slow allocs: ").unsigned(slowAllocations.get(thread))
.string(" refills: ").unsigned(numberOfRefills.get(thread))
.string(" alloc bytes: ").unsigned(allocatedBytesSinceLastGC)
.string(" alloc avg.: ").unsigned((long) allocatedBytesAvg.getAddress(thread).getAverage())
.string(" waste bytes: ").zhex(waste)
.string(" GC waste: ").unsigned(gcWaste.get(thread))
.string(" refill waste: ").unsigned(refillWaste.get(thread)).newline();
.string(", slow allocs: ").unsigned(slowAllocations.get(thread))
.string(", refills: ").unsigned(numberOfRefills.get(thread))
.string(", alloc bytes: ").unsigned(allocatedBytesSinceLastGC)
.string(", alloc avg.: ").unsigned((long) allocatedBytesAvg.getAddress(thread).getAverage())
.string(", waste bytes: ").unsigned(waste)
.string(", GC waste: ").unsigned(gcWaste.get(thread))
.string(", refill waste: ").unsigned(refillWaste.get(thread)).newline();
}

static void logTlabChunks(Log log, IsolateThread thread, String shortSpaceName) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ public static void reset() {
@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
public static void emit(long startTicks, DynamicHub hub, UnsignedWord allocationSize, UnsignedWord tlabSize, boolean allocatedOutsideTlab) {
if (HasJfrSupport.get()) {

if (allocatedOutsideTlab) {
emitObjectAllocationOutsideTLAB(startTicks, hub, allocationSize);
} else if (tlabSize.notEqual(0)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,27 +56,28 @@ public void test() throws Throwable {
String[] events = new String[]{JfrEvent.ObjectAllocationOutsideTLAB.getName()};
Recording recording = startRecording(events);

/* Do a GC before the allocations to avoid that the GC interferes with the test. */
System.gc();

/*
* Use a separate thread for allocating the objects, to have better control over the TLAB
* and to make sure the objects are actually allocated outside the TLAB.
*/
Thread testThread = new Thread(() -> {
final long largeObjectThreshold = SerialAndEpsilonGCOptions.LargeArrayThreshold.getValue();
final int arraySize = NumUtil.safeToInt(largeObjectThreshold - 1024);
int arrayDataSize = arrayDataSizeForOutOfTLABAllocation();

// Allocate a small object to make sure we have a TLAB.
Object o = new Object();
GraalDirectives.blackhole(o);
/* Allocate a small object to make sure we have a TLAB. */
GraalDirectives.blackhole(new Object());

allocateByteArray(arraySize / Byte.BYTES);
allocateCharArray(arraySize / Character.BYTES);
/* Allocate large arrays that don't fit into the TLAB. */
GraalDirectives.blackhole(allocateByteArray(arrayDataSize / Byte.BYTES));
GraalDirectives.blackhole(allocateCharArray(arrayDataSize / Character.BYTES));
}, TEST_THREAD_NAME);

testThread.start();
testThread.join();

stopRecording(recording, TestObjectAllocationOutsideTLABEvent::validateEvents);

}

@NeverInline("Prevent escape analysis.")
Expand All @@ -89,9 +90,17 @@ private static char[] allocateCharArray(int length) {
return new char[length];
}

/**
* Returns the required array data size in bytes such that an array is too large to be allocated
* in the TLAB, yet still small enough to fit within an aligned heap chunk.
*/
private static int arrayDataSizeForOutOfTLABAllocation() {
long largeObjectThreshold = SerialAndEpsilonGCOptions.LargeArrayThreshold.getValue();
return NumUtil.safeToInt(largeObjectThreshold - 512);
}

private static void validateEvents(List<RecordedEvent> events) {
final long largeObjectThreshold = SerialAndEpsilonGCOptions.LargeArrayThreshold.getValue();
final int arrayLength = NumUtil.safeToInt(largeObjectThreshold - 1024);
int arrayDataSize = arrayDataSizeForOutOfTLABAllocation();

boolean foundByteArray = false;
boolean foundCharArray = false;
Expand All @@ -105,7 +114,7 @@ private static void validateEvents(List<RecordedEvent> events) {
long allocationSize = event.<Long> getValue("allocationSize");
String className = event.<RecordedClass> getValue("objectClass").getName();

if (allocationSize >= arrayLength) {
if (allocationSize >= arrayDataSize) {
if (className.equals(char[].class.getName())) {
foundCharArray = true;
} else if (className.equals(byte[].class.getName())) {
Expand All @@ -119,5 +128,4 @@ private static void validateEvents(List<RecordedEvent> events) {
assertTrue(foundByteArray);
assertTrue(foundCharArray);
}

}