summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/structured-clone/tenuring.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit-test/tests/structured-clone/tenuring.js')
-rw-r--r--js/src/jit-test/tests/structured-clone/tenuring.js92
1 files changed, 92 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/structured-clone/tenuring.js b/js/src/jit-test/tests/structured-clone/tenuring.js
new file mode 100644
index 0000000000..0fffa064fa
--- /dev/null
+++ b/js/src/jit-test/tests/structured-clone/tenuring.js
@@ -0,0 +1,92 @@
+// Check that we switch to allocating in the tenure 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);
+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);