Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sufficiently-deterministic GC #2615

Closed
1 of 11 tasks
warner opened this issue Mar 10, 2021 · 1 comment
Closed
1 of 11 tasks

sufficiently-deterministic GC #2615

warner opened this issue Mar 10, 2021 · 1 comment
Assignees
Labels
enhancement New feature or request SwingSet package: SwingSet

Comments

@warner
Copy link
Member

warner commented Mar 10, 2021

What is the Problem Being Solved?

#1872 was about how swingset should approach GC given the lack of engine-level determinism. In #1872 (comment) we figured that we can get enough deterministic behavior out of the engine we're using to use a somewhat simpler design. This ticket captures that subset and replaces #1872.

The checklist of subtasks is:

Description of the Design

On the export side, liveslots will change slotToVal to hold WeakRef values instead of strong references to Remotables. A separate Set named exports will hold strong references until a dispatch.dropExports relieves the vat of that duty.

On the import side, the slotToVal weakref allows liveslots to sense when an import (Presence) becomes unreferenced. Liveslots will use a FinalizationRegistry to detect this. Acting upon the callbacks (calling syscall.dropImports) is deferred to the end of the crank, which liveslots needs to be able to sense internally. Liveslots is also responsible for calling a platform-provided "force GC" function, and giving it time to fire the callbacks. A flag should tell liveslots to enable all this behavior.

We'll have one mode we use on-chain, which requires determinism. It will run vats under XS, trigger a single worker's GC at the end of each crank, and call dropImport right away.

There will be a different mode for solo machines, which need hangover-consistency but not determinism. This can run vats under Node.js, and doesn't need to trigger GC deliberately. If/when finalizers fire, vats will notice it at the end of crank and invoke syscall.dropImports at the right time (we must still make sure dropImports only happens at the end of crank, and only for the vat being invoked). We might need some extra mechanism to make sure infrequently-called vats have a chance to shed their imports.

@warner warner added enhancement New feature or request SwingSet package: SwingSet labels Mar 10, 2021
warner added a commit that referenced this issue Mar 15, 2021
This removes `vatDecref` from manager-local, which will be replaced by a
syscall-based mechanism as part of #2615.
warner added a commit that referenced this issue Mar 15, 2021
This removes `vatDecref` from manager-local, which will be replaced by a
syscall-based mechanism as part of #2615.
warner added a commit that referenced this issue Mar 15, 2021
This removes `vatDecref` from manager-local, which will be replaced by a
syscall-based mechanism as part of #2615.
warner added a commit that referenced this issue Mar 15, 2021
This removes `vatDecref` from manager-local, which will be replaced by a
syscall-based mechanism as part of #2615.
warner added a commit that referenced this issue Mar 15, 2021
This removes `vatDecref` from manager-local, which will be replaced by a
syscall-based mechanism as part of #2615.
warner added a commit that referenced this issue Mar 15, 2021
This removes `vatDecref` from manager-local, which will be replaced by a
syscall-based mechanism as part of #2615.
@warner warner self-assigned this Mar 17, 2021
warner added a commit that referenced this issue Mar 19, 2021
Modify xsnap.c to add a `gc()` function to the globals of the
initial ("start") Compartment. This function should trigger an immediate,
synchronous, full GC sweep. As a non-standard global, the `gc()` function
will be filtered out of the globals in all child Compartments by SES as
usual.

Note that this changes the snapshot format: heap snapshots written before
this change cannot be read by code after this change. This happens because
`gc()` (which is implemented in C) is a new "callback" (a C function made
available to JS code), which is an "exit" from the reference graph. It must
be recognized during serialization, and re-attached during reload, and xsnap
cannot handle loading snapshots with a different set of exits, even purely
additive changes.

closes #2682
refs #2660
refs #2615
warner added a commit that referenced this issue Mar 19, 2021
Modify xsnap.c to add a `gc()` function to the globals of the
initial ("start") Compartment. This function should trigger an immediate,
synchronous, full GC sweep. As a non-standard global, the `gc()` function
will be filtered out of the globals in all child Compartments by SES as
usual.

Note that this changes the snapshot format: heap snapshots written before
this change cannot be read by code after this change. This happens because
`gc()` (which is implemented in C) is a new "callback" (a C function made
available to JS code), which is an "exit" from the reference graph. It must
be recognized during serialization, and re-attached during reload, and xsnap
cannot handle loading snapshots with a different set of exits, even purely
additive changes.

closes #2682
refs #2660
refs #2615
@dckc dckc added this to the Testnet: Stress Test Phase milestone May 19, 2021
warner added a commit that referenced this issue May 21, 2021
Consensus mode will depend upon GC being deterministic, but solo mode does
not. Solo mode requires GC be "sufficiently deterministic", which means a
finalizer may or may not run in any given crank.

To support this, we must not record the GC-related syscalls (dropImport,
retireImport, retireExport) in the transcript. When replaying a transcript,
we ignore these syscalls as well.

closes #3146
refs #2615
refs #2660
refs #2724
warner added a commit that referenced this issue May 21, 2021
Consensus mode will depend upon GC being deterministic, but solo mode does
not. Solo mode requires GC be "sufficiently deterministic", which means a
finalizer may or may not run in any given crank.

To support this, we must not record the GC-related syscalls (dropImport,
retireImport, retireExport) in the transcript. When replaying a transcript,
we ignore these syscalls as well.

closes #3146
refs #2615
refs #2660
refs #2724
warner added a commit that referenced this issue May 21, 2021
Consensus mode will depend upon GC being deterministic, but solo mode does
not. Solo mode requires GC be "sufficiently deterministic", which means a
finalizer may or may not run in any given crank.

To support this, we must not record the GC-related syscalls (dropImport,
retireImport, retireExport) in the transcript. When replaying a transcript,
we ignore these syscalls as well.

closes #3146
refs #2615
refs #2660
refs #2724
warner added a commit that referenced this issue May 24, 2021
Change liveslots to provoke GC at mid-crank, then process the "dead set" and
emit `syscall.dropImports` for everything we can.

For now, we conservatively assume that everything remains recognizable, so we
do *not* emit `syscall.retireImport` for anything. The vref might be used as
a WeakMap/WeakSet key, and the VOM isn't yet tracking those. When #3161 is
done, we'll change liveslots to ask the VOM about each vref, and retire the
ones it does not know how to recognize (which will hopefully be the majority
of them).

closes #3147
refs #2615
refs #2660
warner added a commit that referenced this issue May 25, 2021
Change liveslots to provoke GC at mid-crank, then process the "dead set" and
emit `syscall.dropImports` for everything we can.

For now, we conservatively assume that everything remains recognizable, so we
do *not* emit `syscall.retireImport` for anything. The vref might be used as
a WeakMap/WeakSet key, and the VOM isn't yet tracking those. When #3161 is
done, we'll change liveslots to ask the VOM about each vref, and retire the
ones it does not know how to recognize (which will hopefully be the majority
of them).

closes #3147
refs #2615
refs #2660
@warner
Copy link
Member Author

warner commented Jun 21, 2021

This was sufficiently implemented in #3106 . We still have remaining tasks to handle virtual objects and virtualized data completely, but normal Remotables and Presences ought to be collected now, both in the kernel and over comms.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request SwingSet package: SwingSet
Projects
None yet
Development

No branches or pull requests

2 participants