Skip to content
Merged
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 @@ -19,8 +19,10 @@
import org.openjdk.jol.info.GraphLayout;
import org.openjdk.jol.vm.VM;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
Expand Down Expand Up @@ -334,6 +336,26 @@ class ChunkFootprintTest {
*/
private static final int TRACKER_CHUNKS = 16;

/**
* How many classes may carry a negative count before the comparison is treated as broken.
* <p>
* The per class figures are differences between two walks — everything the chunk and its instance
* retain, minus what the instance retains alone. A count below zero cannot be a property of the
* chunk, because a set of objects that exist <em>because</em> the chunk exists has no negative
* cardinality. It means the instance grew between the two walks, and the classes seen doing that
* are the JVM's own bookkeeping: {@code java.io.FileCleanable} when a file handle is registered,
* {@code byte[]} when a string is built. Comparing such a row states nothing about either chunk,
* so it is skipped and its bytes are carried into the total instead.
* </p>
* <p>
* The limit is what keeps that from turning into a way of passing. Skipping one or two rows loses
* nothing; skipping many would mean the walk disagreed with itself wholesale, and the answer to
* that is a failure, not a comparison of whatever survived. Two is the observed ceiling: the
* failures on 2026-08-03 carried exactly one such class each.
* </p>
*/
private static final int UNMEASURABLE_CLASS_LIMIT = 2;

/**
* The width of the label column of the breakdown table.
*/
Expand Down Expand Up @@ -885,11 +907,20 @@ private static void assertOnlyTheDeclaredClassesDiffer(Footprint minestom, Chunk
classNames.addAll(declared.keySet());

long declaredBytes = 0;
long unmeasuredBytes = 0;
final List<String> unmeasured = new ArrayList<>();

for (String className : classNames) {
if (className.startsWith(minestomType) || className.startsWith(falcoType)) {
continue;
}
if (minestom.objectsOf(className) < 0 || falcoSide.objectsOf(className) < 0) {
unmeasured.add(className + ": Minestom " + minestom.objectsOf(className) + " objects / "
+ minestom.bytesOf(className) + " B, Falco " + falcoSide.objectsOf(className)
+ " / " + falcoSide.bytesOf(className) + " B");
unmeasuredBytes += falcoSide.bytesOf(className) - minestom.bytesOf(className);
continue;
}
final Declared row = declared.get(className);

if (row == null) {
Expand Down Expand Up @@ -920,10 +951,21 @@ private static void assertOnlyTheDeclaredClassesDiffer(Footprint minestom, Chunk
+ " bytes, so it holds the declared objects at a size nobody declared");
declaredBytes += expectedBytes - minestom.bytesOf(className);
}
assertEquals(declaredBytes, falcoSide.bytes() - minestom.bytes(),
if (!unmeasured.isEmpty()) {
System.out.println(context + ": " + unmeasured.size() + " class(es) carried a negative count "
+ "and were left out of the comparison, together worth " + unmeasuredBytes
+ " B of the total difference: " + String.join("; ", unmeasured));
}
assertTrue(unmeasured.size() <= UNMEASURABLE_CLASS_LIMIT,
context + ": " + unmeasured.size() + " classes carried a negative count. Skipping that many "
+ "stops this from being a comparison at all — the exclusion exists for the one or "
+ "two bookkeeping classes the JVM adds between the two walks, not for a walk that "
+ "disagreed with itself wholesale: " + String.join("; ", unmeasured));
assertEquals(declaredBytes + unmeasuredBytes, falcoSide.bytes() - minestom.bytes(),
context + ": the two chunks differ by " + (falcoSide.bytes() - minestom.bytes())
+ " bytes while the classes the plan declared account for " + declaredBytes
+ " and every other class was just asserted equal. The two do not add up, which "
+ ", the classes no walk could measure for " + unmeasuredBytes
+ ", and every other class was just asserted equal. The three do not add up, which "
+ "is a statement about the walk rather than about the chunk: the per class table "
+ "of a footprint has to sum to the total that footprint reports.");
assertEquals(ClassLayout.parseInstance(minestomChunk).instanceSize(),
Expand Down
Loading