diff options
Diffstat (limited to 'js/src/jit-test/tests/gc/finalizationRegistry-ccw.js')
-rw-r--r-- | js/src/jit-test/tests/gc/finalizationRegistry-ccw.js | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/gc/finalizationRegistry-ccw.js b/js/src/jit-test/tests/gc/finalizationRegistry-ccw.js new file mode 100644 index 0000000000..88c98519ca --- /dev/null +++ b/js/src/jit-test/tests/gc/finalizationRegistry-ccw.js @@ -0,0 +1,81 @@ +// Test combinations of arguments in different compartments. + +gczeal(0); + +let heldValues = []; + +function ccwToObject() { + return evalcx('({})', newGlobal({newCompartment: true})); +} + +function newRegistry() { + return new FinalizationRegistry(value => { + heldValues.push(value); + }); +} + +function ccwToRegistry() { + let global = newGlobal({newCompartment: true}); + global.heldValues = heldValues; + return global.eval( + `new FinalizationRegistry(value => heldValues.push(value))`); +} + +function incrementalGC() { + startgc(1); + while (gcstate() !== "NotActive") { + gcslice(1000); + } +} + +// Test the case when the registry remains live. +for (let w of [false, true]) { + for (let x of [false, true]) { + for (let y of [false, true]) { + for (let z of [false, true]) { + let registry = w ? ccwToRegistry(w) : newRegistry(); + let target = x ? ccwToObject() : {}; + let heldValue = y ? ccwToObject() : {}; + let token = z ? ccwToObject() : {}; + registry.register(target, heldValue, token); + registry.unregister(token); + registry.register(target, heldValue, token); + target = undefined; + token = undefined; + heldValue = undefined; + incrementalGC(); + heldValues.length = 0; // Clear, don't replace. + drainJobQueue(); + assertEq(heldValues.length, 1); + } + } + } +} + +// Test the case when registry has no more references. +for (let w of [false, true]) { + for (let x of [false, true]) { + for (let y of [false, true]) { + for (let z of [false, true]) { + let registry = w ? ccwToRegistry(w) : newRegistry(); + let target = x ? ccwToObject() : {}; + let heldValue = y ? ccwToObject() : {}; + let token = z ? ccwToObject() : {}; + registry.register(target, heldValue, token); + registry.unregister(token); + registry.register(target, heldValue, token); + target = undefined; + token = undefined; + heldValue = undefined; + registry = undefined; // Remove last reference to registry. + incrementalGC(); + heldValues.length = 0; + drainJobQueue(); + // The cleanup callback may or may not be run depending on + // which order the zones are swept in, which itself depends on + // the arrangement of CCWs. + assertEq(heldValues.length <= 1, true); + } + } + } +} |