On Saturday, 1 April 2017 at 22:08:27 UTC, Walter Bright wrote:
On 4/1/2017 7:54 AM, deadalnix wrote:
It doesn't need any kind of throw new scope Exception, and was proposed,
literally, years ago during discussion around DIP25 and alike.

A link to that proposal would be appreciated.

The forum search isn't returning anything useful so I'm not sure how to get that link. However, it goes roughly as follow. Note that it's a solution to solve DIP25+DIP1000+RC+nogc exception and a sludge of other issues, and that comparing it to any of these independently will yield the obvious it is more complex. But that wouldn't be a fair comparison, as one should compare it to the sum of all these proposals, not to any of them independently.

The compiler already has the nothing of "unique" and use it to some extent, for instance to optimize pure functions and allow to do some magic with new allocations. The proposal relax and extend the concept of unique and make it explicit, via the type qualifier 'owned'. Going into the details here would take too long, so i'll just reference this paper ( https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/msr-tr-2012-79.pdf ) for detailed work in C# about this. This is easily applicable to D.

The GC heap is currently composed of several islands. One island per thread + one shared island + one immutable island. The owned qualifier essentially enable to have more island, and each indirection tagged owned is a jump to another island. What's currently understood as "unique" by the compiler can be considered owned, which includes values returned from strongly pure functions and fresh new allocations.

Let's see how that apply to exceptions and the GC:
- If a T is thrown, the runtime assumes GC ownership of the exception. - If a owned(T) is thrown, the runtime takes ownership of the exception (and of the graph of objects reachable from the exception.

When catching:
- If the catch isn't scope or owned, then is is a "consume" operation. If the runtime had ownership of the exception, it transfers it to the GC. - If the catch is scope, then the runtime keeps ownership of the Exception. Exiting the catch block is going to destroy the Exception and the whole island associated with it. - If the catch is owned, then the ownership of the Exception is transferred to the catch block. It is then either transferred back to the runtime in case of rethrow, or consumed/destroyed depending on what the catch block is doing with it.

The only operations that need to be disallowed in nogc code are consuming owned such as their ownership is transferred to the GC, in this case, catch blocks which aren't owned or scope.

This mechanism solves numerous other issues. Notably and non exhaustively:
 - General reduction in the amount of garbage created.
- Ability to transfers ownership of data between thread safely (without cast to/from shared).
 - Safe std.parralelism .
 - Elaborate construction of shared and immutable objects.
 - Safe reference counting.
- Safe "arena" style reference counting such as: https://www.youtube.com/watch?v=JfmTagWcqoE
 - Solves problems with collection ownership and alike.

Reply via email to