Skip to content

Commit

Permalink
fix(swingset): retire unreachable orphans
Browse files Browse the repository at this point in the history
If a kernel object ("koid", the object subset of krefs) is
unreachable, and then becomes orphaned (either because the owning vat
was terminated, or called `syscall.abandonExports`, or was upgraded
and the koid was ephemeral), then retire it immediately.

The argument is that the previously-owning vat can never again talk
about the object, so as far as the rest of the world is concerned, the
object has been retired. And because the owning vat can't retire it by
itself, the kernel needs to do the retirement.

TODO: do we handle entering this state from the other direction: when
an orphaned object becomes unreachable? `processRefcounts()` has
something but I'm not sure it's sufficient.

closes #7212
  • Loading branch information
warner committed Jun 26, 2024
1 parent b4a033b commit 8de8111
Showing 1 changed file with 10 additions and 1 deletion.
11 changes: 10 additions & 1 deletion packages/SwingSet/src/kernel/state/kernelKeeper.js
Original file line number Diff line number Diff line change
Expand Up @@ -599,14 +599,23 @@ export default function makeKernelKeeper(kernelStorage, kernelSlog) {
}

function orphanKernelObjects(krefs, oldVat) {
const retiredKrefs = [];
for (const kref of krefs) {
const ownerKey = `${kref}.owner`;
const ownerVat = kvStore.get(ownerKey);
ownerVat === oldVat || Fail`export ${kref} not owned by old vat`;
kvStore.delete(ownerKey);
// note that we do not delete the object here: it will be
if (getObjectRefCount(kref).reachable === 0) {
// unreachable orphans are retired: the original exporting vat
// won't be around to retire it
retiredKrefs.push(kref);
}
// else, note that we do not delete the object here: it will be
// collected if/when all other references are dropped
}
if (retiredKrefs.length) {
retireKernelObjects(retiredKrefs);
}
}

function deleteKernelObject(koid) {
Expand Down

0 comments on commit 8de8111

Please sign in to comment.