Progress update: * The new exception handling implementation is the default with `--gc:arc` (and `--gc:orc`). * The compiler infers the `sink` parameter annotation for you, there is little need to use it explicitly. * The cycle collector `--gc:orc` is now **much** faster. The implementation does exploit the revived `acyclic` annotation.
That means the existing async designs (stdlib, chronos) work without modifications with `--gc:orc`. (In theory; in practice more testing is required.) If you use `ref object` like C++'s unique_ptr the performance is on par (or - because of Nim's superior parameter passing semantics - better than) C++'s unique_ptr: all RC operations are elided and the cycle collector isn't involved either. **So how does --gc:orc work?** It's a myth that reference counting doesn't work with cyclic structures, but it is true that it reintroduces the "tracing" aspects and heuristics _when_ to run the tracing and over which subgraphs in order to make this fast enough. The current implementation is based on so called "trial deletion" with Bacon's improvements, read [https://researcher.watson.ibm.com/researcher/files/us-bacon/Bacon01Concurrent.pdf](https://researcher.watson.ibm.com/researcher/files/us-bacon/Bacon01Concurrent.pdf) for more information. **Highlights** * Only traces the subgraphs that were modified since the last GC run, somewhat comparable to a generational GC (but in theory actually better than a generational GC). What you don't touch in memory the GC doesn't touch either, it's independent of the involved heap sizes (but not independent of the involved subgraphs (SCCs) ...). * Our implementation uses a novel "type tag free" optimization so that most heap objects do not have to store a type tag in the heap, saving 8 bytes of memory which we use to make cyclic root removal an O(1) operation. This implies that at runtime we exploit even more acyclic cases than previous designs.