@nogc and exceptions

monarch_dodra via Digitalmars-d digitalmars-d at puremagic.com
Fri Sep 12 04:03:06 PDT 2014


On Friday, 12 September 2014 at 03:37:10 UTC, Jakob Ovrum wrote:
> 2) The above really shows how beneficial dynamic memory 
> allocation is for exceptions. A possibility would be to 
> allocate exceptions on a non-GC heap, like the C heap (malloc) 
> or a thread-local heap. Of course, without further amendments 
> the onus is then on the catch-site to explicitly manage memory, 
> which would silently break virtually all exception-handling 
> code really badly.
>
> However, if we assume that most catch-sites *don't* escape 
> references to exceptions from the caught chain, we could 
> gracefully work around this with minimal and benevolent 
> breakage: amend the compiler to implicitly insert a cleanup 
> call at the end of each catch-block. The cleanup function would 
> destroy and free the whole chain, but only if a flag indicates 
> that the exception was allocated with this standard heap 
> mechanism. Chains of exceptions with mixed allocation origin 
> would have to be dealt with in some manner. If inside the 
> catch-block, the chain is rethrown or sent in flight by a 
> further exception, the cleanup call would simply not be reached 
> and deferred to the next catch-site, and so on.
>
> Escaping references to caught exceptions would be undefined 
> behaviour. To statically enforce this doesn't happen, exception 
> references declared in catch-blocks could be made implicitly 
> `scope`. This depends on `scope` actually working reasonably 
> well. This would be the only breaking change for user code, and 
> the fix is simply making a copy of the escaped exception.
>
> Anyway, I'm wondering what thoughts you guys have on this 
> nascent but vitally important issue. What do we do about this?

I think option "b)" is the right direction. However, I don't 
think it is reasonable to have the "catch" code be responsible 
for the cleanup proper, as that would lead to a closed design 
(limited allocation possibilities).

I like the option of having "exception allocators" that can later 
be explicitly called in a "release all exceptions" style, or 
plugged into the GC, to be cleaned up automatically like any 
other GC allocated exception. This would make the exceptions 
themselves still @nogc, but the GC would have a hook to 
(potentially) collect them. For those that don't want that, then 
they can make calls to the cleanup at deterministic times.

This, combined with the fact that we used an (unshared) allocator 
means the cleanup itself would be 0(1).

Finally, if somebody *does* want to keep exceptions around, he 
would still be free to do so *provided* he re-allocates the 
exceptions himself using a memory scheme he chooses to use (a 
simple GC new, for example).



... well, either that, or have each exception carry a callback to 
its allocator, so that catch can do the cleanup, regardless of 
who did the allocation, and how. GC exceptions would have no 
callback, meaning a "catch" would still be @nogc. An existing 
code that escapes exceptions would not immediately break.

Either way, some sort of custom (no-gc) allocator seems in order 
here.


More information about the Digitalmars-d mailing list