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

Fix Rust values getting GC'd while still borrowed and not getting GC'd if created via. constructor #3940

Open
wants to merge 12 commits into
base: main
Choose a base branch
from

Conversation

Liamolucko
Copy link
Collaborator

Fixes #3854.
Supersedes #3743.

This implements the alternative reference-counting based fix that I proposed in #3743.

I also added some tests for it. It turns out there was already an existing test around GC, which meant that Node's --expose-gc flag was already enabled for manually triggering garbage collection.

I ended up merging it together with my tests, and then running them sequentially since attempting to run multiple GCs in parallel seemed to make it flaky. It was still somewhat flaky after that point, though: the garbage collector just decided not to clean up the OwnedValues sometimes. For whatever reason, 'warming it up' by just running a bunch of pointless GCs before the tests seems to fix it; I might try and investigate why at some point, but for now it works.

At first I tried fixing them so that they didn't need to (giving each of them
their own `dropCount`), but running multiple GCs in parallel seems to be flaky.
I also discovered and fixed an extra bug while working on this, which
was that `LongRefFromWasmAbi` wasn't getting used for `self`: this bug
didn't cause any problems before, because the only type that had a
different `LongRefFromWasmAbi` impl than its `RefFromWasmAbi` impl was
`JsValue` which can't be the type of `self`.

It became a problem here because I made the new `LongRefFromWasmAbi`
impl for exported Rust types clone the `Rc`, whereas the
`RefFromWasmAbi` impl doesn't because garbage collection can't occur
during the synchronous call that the value has to live for.

I might actually change it so that both of the impls behave like the
current `LongRefFromWasmAbi` impl, though: cloning an `Rc` isn't
expensive and so having the second different impl just makes things more
complicated for no good reason. I just left it in this commit as
explanation for how I discovered the `LongRefFromWasmAbi` issue.
Now that borrowing a Rust value always clones its `Rc`, `Rc::into_inner`
is a sufficient check that the value isn't borrowed.
For some reason I was getting errors before without it, but that seems
to be fixed now. (It's probably something to do with having removed the
`borrow_mut`, but that only takes `&self`, so I still don't get it.)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

FinalizationRegistry.register() call missing in exported rust types that define a constructor
1 participant