From a3a6149edb291a87378598c6597c224e3a8a47d3 Mon Sep 17 00:00:00 2001 From: Brian Warner Date: Tue, 1 Jun 2021 11:01:32 -0700 Subject: [PATCH] make test-gc-and-finalize slightly more devious --- .../SwingSet/test/test-gc-and-finalize.js | 29 +++++++++++++++---- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/packages/SwingSet/test/test-gc-and-finalize.js b/packages/SwingSet/test/test-gc-and-finalize.js index ac6ccebe0890..3bd0eb71f4dd 100644 --- a/packages/SwingSet/test/test-gc-and-finalize.js +++ b/packages/SwingSet/test/test-gc-and-finalize.js @@ -15,14 +15,30 @@ test(`have gc() on Node.js`, async t => { // `gc` C callback on the global object. }); -function setup() { - const victim = { doomed: 'oh no' }; +function setup1() { + // The worst case I can think of is a four-pole counter-rotating cycle, + // held in place by N and S, with E as our victim/sensor. Dropping N or S + // does not drop a refcount to zero. + const N = {}; + const S = {}; + const E = { N, S }; + const W = { N, S }; + N.E = E; + N.W = W; + S.E = E; + S.W = W; const finalized = ['finalizer not called']; const fr = new FinalizationRegistry(_tag => { finalized[0] = 'finalizer was called'; }); - const wr = new WeakRef(victim); - fr.register(victim, 'tag'); + const wr = new WeakRef(E); + fr.register(E, 'tag'); + return { N, S, finalized, fr, wr }; +} + +function setup2() { + const { N: _ignoreN, S: _ignoreS, finalized, fr, wr } = setup1(); + // I want N and S to be dropped after E and W. return { finalized, fr, wr }; } @@ -32,7 +48,7 @@ async function provokeGC() { // we must retain the FinalizationRegistry to let the callback fire // eslint-disable-next-line no-unused-vars - const { finalized, fr, wr } = setup(); + const { finalized, fr, wr } = setup2(); // the transition from UNREACHABLE to COLLECTED can happen at any moment, // but is far more likely to happen if we force it @@ -82,7 +98,8 @@ test(`can provoke gc on xsnap`, async t => { const vat = xsnap(opts); const code = ` ${gcAndFinalize} -${setup} +${setup1} +${setup2} ${provokeGC} provokeGC().then(data => issueCommand(ArrayBuffer.fromString(JSON.stringify(data)))); `;