Skip to content

RFC: Replace ARC with a tracing collector (again) #1298

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

Closed
dcodeIO opened this issue May 27, 2020 · 11 comments
Closed

RFC: Replace ARC with a tracing collector (again) #1298

dcodeIO opened this issue May 27, 2020 · 11 comments

Comments

@dcodeIO
Copy link
Member

dcodeIO commented May 27, 2020

This is a suggestion that has been on my mind for a long time already but I have been hesitating to propose it. However, recently a hard to resolve bug has been reported that made me think about it again, and after talking with @MaxGraey for a bit, who for the record is skeptical but brought up Immix concepts I'm going to mention below, I'd like to elaborate.

While we put a lot of effort into our ARC implementation and people in general welcomed our efforts, it also turned out to complicate the compiler and the external interface to a significant degree, sometimes hindering us to move quickly and deterring new users from picking up AssemblyScript due to the complexity it adds on the boundary. Now, we certainly want to be fast and efficient today, but in my opinion we are in a situation today where we have to spend way too much time on this, keeping us in a lose-lose situation until Wasm GC hits.

Hence I propose to pull the plug on ARC and start over with a simpler tracing GC, for the following reasons:

  • A tracing GC is less intrusive in codegen, and as such less error-prone, enabling us and contributors to move more quickly.
  • A tracing GC has a much simpler external interface, by typically not requiring user intervention at all, and otherwise requiring a user to mark/unmark something as sticky that should be kept alive.
  • A tracing GC can more easily transition or remain as an alternative to Wasm GC, because most of the necessary work of removing ARC will already have taken place.
  • A tracing GC can be more easily extended with better algorithms, like applicable concepts from Immix, if someone wants to invest the effort.
  • A tracing GC can have higher peak performance when a user manually picks collection points wisely, while ARC always runs concurrently to some degree. This also makes it more straight forward to compare with JS.

Of course there will be trade-offs, but from my current perspective these will be worth it overall. Also, not all about our ARC implementation is or was bad, of course, and at the very least it helped us to make the right decision ultimately.

Please let me know of your thoughts, and ask any questions that are on your mind. I expect this to be controversial for various reasons, rightly so, but I recommend not getting attached to the concept of ARC too much if it might subjectively seem more modern or otherwise easier to justify than a more conservative GC.

@MaxGraey
Copy link
Member

I guess need build prototype new Immix tracing iterative GC and compare it with existing approach. Measure speed / collection delay and decide is it make sense replace it or not. Btw own GC (not wasm GC) doesn't resolve cross-module boundary manual management. We still will need something like weak / strong refs for pass to and from host

@dcodeIO
Copy link
Member Author

dcodeIO commented May 27, 2020

My current expectation is that we will, eventually, completely get rid of our own GC, including a tracing GC, replacing it with a post-process step on a Wasm GC enabled binary, potentially provided by Binaryen (I'm just assuming that it would ideally live there at this point) to downlevel Wasm GC to a bundled GC for environments where Wasm GC is not supported. In fact, that'd be a valuable tool for all sorts of languages compiling to Wasm, not just for us. As such, I'd prefer to go for a simpler ITCM-style GC as part of the transition proposed here, while designing the interface in a way that experimenting is possible, since going for Immix in one go is just too heavy and implies that I have to do it right now to fix the bug linked above, which I simply can't right now given all the other stuff I have to do.

@MaxGraey
Copy link
Member

MaxGraey commented May 27, 2020

Hmm, so you suggest just remove ARC part of PureRC approach and stay on simple "stop the world" serial M&S GC for now?

@dcodeIO
Copy link
Member Author

dcodeIO commented May 27, 2020

Btw, I've also registered for the WebAssembly Garbage Collection Subgroup meetings, mostly to inform myself, not so much to participate in design if I don't have to, which I hope will help to get this all right eventually. If one of you guys wants to follow the process there as well, here's the link.

@dcodeIO
Copy link
Member Author

dcodeIO commented May 27, 2020

Hmm, so you suggest just remove ARC part of PureRC approach and stay on simple "stop the world" serial M&S GC?

Yes, I basically suggest to delete most of our ARC implementation and revert to ITCM as a first step. The hooks, like visit_globals are still there, and ITCM is somewhere in our Git history.

@MaxGraey
Copy link
Member

What is ITCM?

@MaxGraey
Copy link
Member

MaxGraey commented May 27, 2020

May better just turn off optimizations for ARC until you fixing that issue? I expect a lot of stability and performance regressions if just rapidly replace existing highly tested solution

@dcodeIO
Copy link
Member Author

dcodeIO commented May 27, 2020

What is ITCM?

The latest version we had is here: https://github.com/AssemblyScript/assemblyscript/blob/3ed76a97f05335504166fce1653da75f4face28f/std/assembly/collector/itcm.ts

May better just turn off optimizations for ARC until you fixing that issue?

That's the alternative, yeah, still leaving us with all the other disadvantages until the next issue, and there will be new issues :(. Remember all the loop problems we had? These pretty much only existed because ARC.

@MaxGraey
Copy link
Member

Ah I forgot about we already have some simple GC.

I vote for temporary turn off ARC optimizations.
Also keep in mind about existing tools / articles and projects which already based on interop with ARC runtime. So another one problem with discarding ARC is compatibility

@dcodeIO
Copy link
Member Author

dcodeIO commented May 27, 2020

So another one problem with discarding ARC is compatibility

I guess it'd be possible to introduce a compatibility layer there, by making __retain count references on the JS side (making an object sticky as long as RC>1), until the last __release is reached, which undoes sticky on RC=0. That looks like a good approach in general, as it also relieves a user from taking special care about making something sticky exactly once.

@ezdiy
Copy link

ezdiy commented Jul 2, 2020

ASC is a hot contender for scripting bare metal on low power devices. There are additional niches - games and ui - where gc pauses, or even the doubled memory usage inherent to M&S gc are unacceptable. Yes there's ABI cost for ARC, but it's a price some are willing to pay.

@dcodeIO dcodeIO closed this as completed Dec 10, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants