Skip to content

Commit 69fa69c

Browse files
committed
[GR-71487] TLAB overallocates because it incorrectly uses filler object size for image heap.
PullRequest: graal/22656
2 parents b224dfa + f11bb05 commit 69fa69c

File tree

3 files changed

+18
-9
lines changed

3 files changed

+18
-9
lines changed

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@
4141

4242
import jdk.graal.compiler.api.replacements.Fold;
4343
import jdk.graal.compiler.core.common.NumUtil;
44-
import jdk.graal.compiler.word.Word;
4544
import jdk.vm.ci.meta.JavaKind;
4645

4746
public class FillerObjectUtil {
@@ -50,8 +49,8 @@ public class FillerObjectUtil {
5049
private static final int ARRAY_ELEMENT_SIZE = ARRAY_ELEMENT_KIND.getByteCount();
5150

5251
@Fold
53-
public static UnsignedWord objectMinSize() {
54-
return Word.unsigned(ConfigurationValues.getObjectLayout().getMinImageHeapObjectSize());
52+
static int instanceMinSize() {
53+
return ConfigurationValues.getObjectLayout().getMinRuntimeHeapInstanceSize();
5554
}
5655

5756
@Fold
@@ -66,7 +65,7 @@ static int arrayBaseOffset() {
6665

6766
@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
6867
public static void writeFillerObjectAt(Pointer p, UnsignedWord size, boolean rememberedSet) {
69-
assert size.aboveThan(0);
68+
assert size.equal(instanceMinSize()) || size.aboveOrEqual(arrayMinSize());
7069
if (size.aboveOrEqual(arrayMinSize())) {
7170
int length = UnsignedUtils.safeToInt(size.subtract(arrayBaseOffset()).unsignedDivide(ARRAY_ELEMENT_SIZE));
7271
FormatArrayNode.formatArray(p, ARRAY_CLASS, length, rememberedSet, false, WITH_GARBAGE_IF_ASSERTIONS_ENABLED, false);

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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -342,14 +342,16 @@ private static UnsignedWord availableTlabMemory(Descriptor tlab) {
342342
* If the minimum object size is greater than {@link ObjectLayout#getAlignment()}, we can end up
343343
* with a shard at the end of the buffer that's smaller than the smallest object (see
344344
* {@link com.oracle.svm.core.heap.FillerObject}). We can't allow that because the buffer must
345-
* look like it's full of objects when we retire it, so we make sure we have enough space for a
346-
* {@link com.oracle.svm.core.heap.FillerArray}) object.
345+
* look like it's full of objects when we retire it, so we make sure we always have enough space
346+
* for a filler object.
347347
*/
348348
@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-23-ga/src/hotspot/share/gc/shared/collectedHeap.cpp#L253-L259")
349349
@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
350350
private static UnsignedWord getFillerObjectSize() {
351-
UnsignedWord minSize = FillerObjectUtil.objectMinSize();
352-
return minSize.aboveThan(ConfigurationValues.getObjectLayout().getAlignment()) ? minSize : Word.zero();
351+
int minSize = FillerObjectUtil.instanceMinSize();
352+
int alignment = ConfigurationValues.getObjectLayout().getAlignment();
353+
assert FillerObjectUtil.arrayMinSize() - minSize <= alignment : "all sizes above min instance size must be fillable";
354+
return (minSize > alignment) ? Word.unsigned(minSize) : Word.zero();
353355
}
354356

355357
@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-23-ga/src/hotspot/share/gc/shared/threadLocalAllocBuffer.cpp#L119-L124")

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/config/ObjectLayout.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,9 +273,17 @@ public long computeArrayTotalSize(long unalignedSize, boolean withOptionalIdHash
273273
return alignUp(size);
274274
}
275275

276+
public int getMinRuntimeHeapInstanceSize() {
277+
return getMinInstanceSize(false);
278+
}
279+
276280
public int getMinImageHeapInstanceSize() {
281+
return getMinInstanceSize(true);
282+
}
283+
284+
private int getMinInstanceSize(boolean withOptionalIdHashField) {
277285
int unalignedSize = firstFieldOffset; // assumes no always-present "synthetic fields"
278-
if (isIdentityHashFieldAtTypeSpecificOffset() || isIdentityHashFieldOptional()) {
286+
if (isIdentityHashFieldAtTypeSpecificOffset() || (withOptionalIdHashField && isIdentityHashFieldOptional())) {
279287
int idHashOffset = NumUtil.roundUp(unalignedSize, Integer.BYTES);
280288
unalignedSize = idHashOffset + Integer.BYTES;
281289
}

0 commit comments

Comments
 (0)