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

GC unreferenced kernel promise table entries #768

Closed
warner opened this issue Mar 24, 2020 · 1 comment
Closed

GC unreferenced kernel promise table entries #768

warner opened this issue Mar 24, 2020 · 1 comment
Labels
SwingSet package: SwingSet

Comments

@warner
Copy link
Member

warner commented Mar 24, 2020

The last phase of #675 is to make the kernel forget about resolved Promises too, not just the vats. We've moved the kernel storage into a database, so this won't reduce the RAM footprint, but it will reduce the on-disk storage footprint in the long run.

The "kernel promise table" contains an entry for every "kernel promise identifier" (kpid) in the system, which tracks the resolution state. For unresolved promises, it stores the decider vat ID, the set of subscribing vats, and the queue of pending non-pipelined messages (all messages sent to the promise, which want to be delivered to whatever the promise ultimately resolves to). For resolved promises, it stores the resolution data: either resolve-to-data, resolve-to-presence, or reject-with-data. (At some point we may also have a forward-to-other-promise state, although hopefully that will be short-lived).

References into the promise table can come from many sources:

  • c-list entries, for one or more vats
  • the argument bodies of run-queue messages (deliveries and resolution notifications)
  • argument bodies of messages pending in an unresolved promise
  • bodies of the resolution/rejection data of a resolved promise

When all of these references have been dropped, we want to delete the entry from the kernel promise table.

It may also be safe to delete entries when the only references come from the kernel promise table. This will require some cycle-aware mark-and-sweep -style GC algorithm. It must effectively start the sweep from the c-lists and run-queue bodies, following references into kernel promises, then following the resolved bodies and pending messages for those kernel promises into other kernel promises. Any kernel promise which remains unreferenced after this sweep can be collected.

When a resolved promise is collected, the database entry can simply be deleted. When an unresolved promise is collected, I think we need to reject the result promises of any pending messages with some sort of "this message can never be delivered" error (we might be able to rule out this case, since Promises are only created by vats, and vats only forget about promises when they become resolved, so perhaps it's not possible for the kernel to still remember an unresolved promise after all vats have forgotten about it. but we need to analyze it carefully to make sure)

We'll need a batch of test cases to create various cycles in the kernel data structures, to make sure the right things get collected and the right things get retained.

@FUDCo
Copy link
Contributor

FUDCo commented May 20, 2020

Closing as part of refactoring the tickets for #675. Much of the underlying work has been done, except for promises that resolve to data that reference other promises, which is a task unto itself (see #1049)

@FUDCo FUDCo closed this as completed May 20, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
SwingSet package: SwingSet
Projects
None yet
Development

No branches or pull requests

2 participants