-
Notifications
You must be signed in to change notification settings - Fork 233
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
does XS allow finalizers to be called outside of gcAndFinalize? #3810
Comments
Peter at Moddable told me that When we move to |
That is not correct. xsnap-worker will run finalizers after the promise queue has drained, so yes after the user code has completed, but before setImmediate trigger which I believe is when we start running unmetered again. This is why I filed #6795
I believe this goal is mistaken. We should disable metering of finalizers at the xsnap level, and reflect that by wrapping finalizer callbacks with
Very much still a concern and the same issue I identified in #6795. We should close one or the other as duplicate. |
Note that with the workaround about WeakRef being considered strong while we investigate #6784, we effectively have finalizers run only during bringOutYourDead through gcAndFinalize. Technically the first delivery after a snapshot may have finalizers run too, since snapshotting forces a full GC, but since we now force bringOutYourDead before snapshot, there should be no more finalization targets found empty in the snapshot forced gc.
For now we have decided to expect that all validators have the same organic gc schedule, and thus we will not fix the lack of metering on finalizers for now. However we know how we could do it, and that is documented in #6795 |
Part of our sufficiently-deterministic-GC story depends upon finalizers (
FinalizationRegistry
callbacks) not being called outside of our deliberategcAndFinalize()
sequence. The JS spec requires that they get run in their own turn, but doesn't otherwise constrain their scheduling. For us, the CPU meter consumed by the callback code will count against the vat, which means if 1: organic GC is not consistent across all validators and 2: finalizers could run any time organic GC releases an object, then 3: the CPU meter consumed by a vat will not be consistent across all validators, which will lead very quickly to a consensus failure. We can't effectively wrap the callbacks in an "unmetered box", as we can for GC-sensitive deserialization code.I'm tracing through the code in XS, and I think finalizers are called from within
xsAPI.c
fxCleanupFinalizationRegistries()
. This is called byfxEndJob
, which is called fromfxEndHost
, which is called from:xsModule.c
:fxRunImport
andCompartment.prototype.import()
, which suggests that a dynamic import statement might be able to trigger finalizersxsRun.c
via a dozen functions likefxRunForOf
, which seem to be called from the (giant) main bytecode interpreter loop in that same timeThe task is to write a test program which registers an object with a finalizer, deletes it, calls gc(), and then performs various things (dynamic import,
for of
) to see if they might trigger the finalizer.The text was updated successfully, but these errors were encountered: