From 3624b34dde2afbd1d0e9e6dec251925faaefb311 Mon Sep 17 00:00:00 2001 From: Brian Warner Date: Sun, 25 Aug 2024 15:53:18 -0700 Subject: [PATCH] updated tests dropping a Remotable now checks for local recognizers, in preparation for fixing #9956 --- packages/swingset-liveslots/src/boyd-gc.js | 18 +++++++++++++---- .../test/liveslots-real-gc.test.js | 20 +++++++++++++++++-- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/packages/swingset-liveslots/src/boyd-gc.js b/packages/swingset-liveslots/src/boyd-gc.js index ff7e8ac83654..c3b6cb3b23d9 100644 --- a/packages/swingset-liveslots/src/boyd-gc.js +++ b/packages/swingset-liveslots/src/boyd-gc.js @@ -276,6 +276,7 @@ export const makeBOYDKit = ({ for (const vrefOrBaseRef of [...possiblyDeadSet].sort()) { const parsed = parseVatSlot(vrefOrBaseRef); assert.equal(parsed.type, 'object', vrefOrBaseRef); + let res = {}; if (parsed.virtual || parsed.durable) { const baseRef = vrefOrBaseRef; @@ -287,12 +288,17 @@ export const makeBOYDKit = ({ const vref = vrefOrBaseRef; res = checkImportPresence(vref); } - // note the syscalls we need to make at end-of-crank + + // prepare our end-of-crank syscalls if (res.dropImport) { importsToDrop.add(res.dropImport); + possiblyRetiredSet.add(vrefOrBaseRef); + } + for (const facetVref of res.exportsToRetire || []) { + exportsToRetire.add(facetVref); } - res.exportsToRetire?.map(facetVref => exportsToRetire.add(facetVref)); gcAgain ||= !!res.gcAgain; + // remove the vref now, so we don't process it again in the // next pass unless something else shakes it loose before then possiblyDeadSet.delete(vrefOrBaseRef); @@ -322,11 +328,15 @@ export const makeBOYDKit = ({ const parsed = parseVatSlot(vref); assert.equal(parsed.type, 'object', vref); if (!parsed.allocatedByVat) { + // if we're dropping the vref, we can safely skip the + // isReachable check, because checkImportPresence already did + // it + const isReachable = + !importsToDrop.has(vref) && + (slotToVal.has(vref) || vrm.isPresenceReachable(vref)); // TODO: the old version used getValForSlot, which also // deref()ed the weakref (and assertNotMetered), think about // the significance - const isReachable = - slotToVal.has(vref) || vrm.isPresenceReachable(vref); const isRecognizable = isReachable || vrm.isVrefRecognizable(vref); if (!isRecognizable) { importsToRetire.add(vref); diff --git a/packages/swingset-liveslots/test/liveslots-real-gc.test.js b/packages/swingset-liveslots/test/liveslots-real-gc.test.js index 8832eb045461..80641d82a44d 100644 --- a/packages/swingset-liveslots/test/liveslots-real-gc.test.js +++ b/packages/swingset-liveslots/test/liveslots-real-gc.test.js @@ -308,6 +308,14 @@ test.serial('GC dispatch.dropExports', async t => { // that should allow ex1 to be collected t.true(collected.result); + // upon collection, the vat should scan for local recognizers (weak + // collection keys) in case any need to be dropped, and find none + t.deepEqual(log.shift(), { + type: 'vatstoreGetNextKey', + priorKey: `vom.ir.${ex1}|`, + result: 'vom.rc.o+d6/1', + }); + // and once it's collected, the vat should emit `syscall.retireExport` // because nobody else will be able to recognize it again const l2 = log.shift(); @@ -394,8 +402,16 @@ test.serial( // which should let the export be collected t.true(collected.result); - // the vat should *not* emit `syscall.retireExport`, because it already - // received a dispatch.retireExport + // the vat should scan for local recognizers (weak collection + // keys) in case any need to be dropped, and find none + t.deepEqual(log.shift(), { + type: 'vatstoreGetNextKey', + priorKey: 'vom.ir.o+10|', + result: 'vom.rc.o+d6/1', + }); + + // the vat should *not* emit `syscall.retireExport`, because it + // already received a dispatch.retireExport t.deepEqual(log, []); }, );