diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/FillerObjectUtil.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/FillerObjectUtil.java index c790b5bf8d5d..9eb09161fa09 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/FillerObjectUtil.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/FillerObjectUtil.java @@ -41,7 +41,6 @@ import jdk.graal.compiler.api.replacements.Fold; import jdk.graal.compiler.core.common.NumUtil; -import jdk.graal.compiler.word.Word; import jdk.vm.ci.meta.JavaKind; public class FillerObjectUtil { @@ -50,8 +49,8 @@ public class FillerObjectUtil { private static final int ARRAY_ELEMENT_SIZE = ARRAY_ELEMENT_KIND.getByteCount(); @Fold - public static UnsignedWord objectMinSize() { - return Word.unsigned(ConfigurationValues.getObjectLayout().getMinImageHeapObjectSize()); + static int instanceMinSize() { + return ConfigurationValues.getObjectLayout().getMinRuntimeHeapInstanceSize(); } @Fold @@ -66,7 +65,7 @@ static int arrayBaseOffset() { @Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true) public static void writeFillerObjectAt(Pointer p, UnsignedWord size, boolean rememberedSet) { - assert size.aboveThan(0); + assert size.equal(instanceMinSize()) || size.aboveOrEqual(arrayMinSize()); if (size.aboveOrEqual(arrayMinSize())) { int length = UnsignedUtils.safeToInt(size.subtract(arrayBaseOffset()).unsignedDivide(ARRAY_ELEMENT_SIZE)); FormatArrayNode.formatArray(p, ARRAY_CLASS, length, rememberedSet, false, WITH_GARBAGE_IF_ASSERTIONS_ENABLED, false); diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/TlabSupport.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/TlabSupport.java index 6099dbdc6413..a22c5132d4ea 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/TlabSupport.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/TlabSupport.java @@ -342,14 +342,16 @@ private static UnsignedWord availableTlabMemory(Descriptor tlab) { * If the minimum object size is greater than {@link ObjectLayout#getAlignment()}, we can end up * with a shard at the end of the buffer that's smaller than the smallest object (see * {@link com.oracle.svm.core.heap.FillerObject}). We can't allow that because the buffer must - * look like it's full of objects when we retire it, so we make sure we have enough space for a - * {@link com.oracle.svm.core.heap.FillerArray}) object. + * look like it's full of objects when we retire it, so we make sure we always have enough space + * for a filler object. */ @BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-23-ga/src/hotspot/share/gc/shared/collectedHeap.cpp#L253-L259") @Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true) private static UnsignedWord getFillerObjectSize() { - UnsignedWord minSize = FillerObjectUtil.objectMinSize(); - return minSize.aboveThan(ConfigurationValues.getObjectLayout().getAlignment()) ? minSize : Word.zero(); + int minSize = FillerObjectUtil.instanceMinSize(); + int alignment = ConfigurationValues.getObjectLayout().getAlignment(); + assert FillerObjectUtil.arrayMinSize() - minSize <= alignment : "all sizes above min instance size must be fillable"; + return (minSize > alignment) ? Word.unsigned(minSize) : Word.zero(); } @BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-23-ga/src/hotspot/share/gc/shared/threadLocalAllocBuffer.cpp#L119-L124") diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/config/ObjectLayout.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/config/ObjectLayout.java index 5b9b83b2e5d8..cea1f807f402 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/config/ObjectLayout.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/config/ObjectLayout.java @@ -273,9 +273,17 @@ public long computeArrayTotalSize(long unalignedSize, boolean withOptionalIdHash return alignUp(size); } + public int getMinRuntimeHeapInstanceSize() { + return getMinInstanceSize(false); + } + public int getMinImageHeapInstanceSize() { + return getMinInstanceSize(true); + } + + private int getMinInstanceSize(boolean withOptionalIdHashField) { int unalignedSize = firstFieldOffset; // assumes no always-present "synthetic fields" - if (isIdentityHashFieldAtTypeSpecificOffset() || isIdentityHashFieldOptional()) { + if (isIdentityHashFieldAtTypeSpecificOffset() || (withOptionalIdHashField && isIdentityHashFieldOptional())) { int idHashOffset = NumUtil.roundUp(unalignedSize, Integer.BYTES); unalignedSize = idHashOffset + Integer.BYTES; }