Proposal: Exceptions and @nogc
rikki cattermole via Digitalmars-d
digitalmars-d at puremagic.com
Sat Apr 1 22:29:00 PDT 2017
On 02/04/2017 6:16 AM, Walter Bright wrote:
> Problem
> =======
>
> Exceptions are assumed to be GC collected by the EH design, in that no
> attempt is made to control copies or lifetimes. This dependency is not
> a performance issue, as exceptions are presumed to be slow.
>
> The issue is it impairs use of @nogc on any code that throws exceptions,
> and prevents building D programs that do not link in the GC runtime.
>
> To fix this, the allocation and destruction of the exception objects
> must be completely controlled.
>
> Solution
> ========
>
> Using a ref counted solution brings with it a host of problems because
> the compiler is not set up to ref count class object references, nor
> is any existing code set up to deal with that.
>
> Instead, rely on Exception objects having a single, trackable owner.
>
> Create three druntime library functions,
>
> 1. allocate an Exception object
> 2. free an Exception object
> 3. copy (a.k.a. clone) an Exception object
>
> Whether the implementations use malloc/free, or some other custom
> allocator,
> is immaterial. The contents of the allocated object still need to be
> subject to scanning by the GC.
>
> throw Expression
> ----------------
>
> The Expression is evaluated, and 'copy' is called to make the actual
> Exception object that is thrown. If the Expression is:
>
> new Exception
>
> then it is optimized to call 'allocate' instead.
>
> catch (Exception e)
> -------------------
>
> 'e' becomes implicitly 'scope', so 'e' cannot escape the
> catch clause. At the exit of the catch clause, 'free' is
> called on 'e'. If 'e' is rethrown, a 'copy' is made of it.
>
> Chained Exceptions
> ------------------
>
> These get 'free' called on them when the head of the chain
> is free'd. The head of the chain owns these instances.
> Access to these by user code needs to be protected by
> 'scope', and hence must be hidden behind an access function to
> enforce that.
>
> Copying Exceptions
> ------------------
>
> There isn't any current mechanism to copy class objects. The
> trouble comes in the form of any postblits that may be required
> for fields. An initial solution is to disallow any Exception
> objects with postblit fields. The eventual solution is to
> auto-generate the copy code, like what is done for structs.
>
> Legacy Code Breakage
> --------------------
>
> This will break an unknown amount of existing code.
>
> Breakage will come in the form of:
>
> 1. dependency on identifying Exception objects by their addresses,
> which won't work anymore because of the copying.
> (good code shouldn't rely on this anyway)
>
> 2. leaking Exception objects from catch clauses (caught by
> the compiler)
>
> 3. Disallowing Exception objects with postblit fields.
>
> 4. Catch objects being 'scope' will cause problems in that
> everything done with those objects will also have to be 'scope'.
> The most likely problem will be printing the objects which
> relies on Object.toString() which is not 'scope'. One possible
> solution is to force Throwable.toString() to be 'scope', which
> will likely cause minimal disruption. Of course, compiling
> with -dip1000 will disable such checking and can work in
> the interim.
>
> Conclusion
> ----------
>
> The result of this should be no leaking memory, no need to link
> in the GC, and memory safety.
>
> References
> ----------
>
> http://www.digitalmars.com/d/archives/digitalmars/D/Exceptions_in_nogc_code_299261.html
Questions:
1) What if an exception dtor throws (yuck but eh)?
2) Could this in some form be paired with allocators? e.g.
typeof(this) dup(IAllocator) { ... }
throw new MyException(8); versus throw alloc.make!MyException(8);
3) Do we really need to copy an exception before rethrowing? It seems
overkill, couldn't we introduce a new local variable to determine if it
should free or not?
And as probably expected, DIP please. Its a big set of changes and
warrants documenting in that form.
More information about the Digitalmars-d
mailing list