Source code

Revision control

Copy as Markdown

Other Tools

// Check that we switch to allocating in the tenured heap after the first
// nursery collection.
function buildObjectTree(depth) {
if (depth === 0) {
return "leaf";
}
return {
left: buildObjectTree(depth - 1),
right: buildObjectTree(depth - 1)
};
}
function buildArrayTree(depth) {
if (depth === 0) {
return [];
}
return [
buildArrayTree(depth - 1),
buildArrayTree(depth - 1)
];
}
function testRoundTrip(depth, objectTree, expectedNurseryAllocated) {
const input = objectTree ? buildObjectTree(depth) : buildArrayTree(depth);
gc();
const initialMinorNumber = gcparam('minorGCNumber');
const output = deserialize(serialize(input));
checkHeap(output, depth, objectTree, expectedNurseryAllocated);
const minorCollections = gcparam('minorGCNumber') - initialMinorNumber;
const expectedMinorCollections = expectedNurseryAllocated ? 0 : 1;
assertEq(minorCollections, expectedMinorCollections);
}
function checkHeap(tree, depth, objectTree, expectedNurseryAllocated) {
const counts = countHeapLocations(tree, objectTree);
const total = counts.nursery + counts.tenured;
assertEq(total, (2 ** (depth + 1)) - 1);
if (expectedNurseryAllocated) {
assertEq(counts.tenured, 0);
assertEq(counts.nursery >= 1, true);
} else {
assertEq(counts.tenured >= 1, true);
// We get a single nursery allocation when we trigger minor GC.
assertEq(counts.nursery <= 1, true);
}
}
function countHeapLocations(tree, objectTree, counts) {
if (!counts) {
counts = {nursery: 0, tenured: 0};
}
if (isNurseryAllocated(tree)) {
counts.nursery++;
} else {
counts.tenured++;
}
if (objectTree) {
if (tree !== "leaf") {
countHeapLocations(tree.left, objectTree, counts);
countHeapLocations(tree.right, objectTree, counts);
}
} else {
if (tree.length !== 0) {
countHeapLocations(tree[0], objectTree, counts);
countHeapLocations(tree[1], objectTree, counts);
}
}
return counts;
}
gczeal(0);
gcparam('minNurseryBytes', 1024 * 1024);
gcparam('maxNurseryBytes', 1024 * 1024);
gcparam('semispaceNurseryEnabled', 0);
gc();
testRoundTrip(1, true, true);
testRoundTrip(1, false, true);
testRoundTrip(4, true, true);
testRoundTrip(4, false, true);
testRoundTrip(15, true, false);
testRoundTrip(15, false, false);