September 19, 2014 RFC: reference counted Throwable | ||||
---|---|---|---|---|
| ||||
As discussed, having exception objects being GC-allocated is clearly a large liability that we need to address. They prevent otherwise careful functions from being @nogc so they affect even apps that otherwise would be okay with a little litter here and there. The Throwable hierarchy is somewhat separate from everything else, which makes it a great starting point for investigating an automated reference count approach. Here's what I'm thinking. First, there must be some compiler flag -nogc or something, which triggers the RC exceptions. All modules of an application must be compiled with this flag if it is to work (such that one module can throw an exception caught by the other). Of course a lot of refinement needs to be added here (what happens if one tries to link modules built with and without -nogc, allowing people to detect the flag programmatically by using version(nogc) etc). If -nogc is passed, the compiler severs the inheritance relationship between Throwable and Object, making it impossible to convert a Throwable to an Object. From then henceforth, Throwable and Object form a two-rooted forest. (In all likelihood we'll later add an RCObject root that Throwable inherits.) Whenever a reference to a Throwable is copied about, passed to functions, the compiler inserts appropriately calls to e.g. incRef and decRef. (Compiler may assume they cancel each other for optimization purposes.) Implementation of these is up to the runtime library. Null checking may be left to either the compiler or the library (in the latter case, the functions must be nonmember). However it seems the compiler may have an advantage because it can elide some of these checks. Once we get this going, we should accumulate good experience that we can later apply to generalizing this approach to more objects. Also, if things go well we may as well define _always_ (whether GC or not) Throwable to be reference counted; seems like a good fit for all programs. Please chime in with thoughts. Andrei |
September 19, 2014 Re: RFC: reference counted Throwable | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On 2014-09-19 17:32, Andrei Alexandrescu wrote: > Whenever a reference to a Throwable is copied about, passed to > functions, the compiler inserts appropriately calls to e.g. incRef and > decRef. (Compiler may assume they cancel each other for optimization > purposes.) Implementation of these is up to the runtime library. Are you suggesting we implement ARC? -- /Jacob Carlborg |
September 19, 2014 Re: RFC: reference counted Throwable | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On 9/19/14, 12:42 PM, Jacob Carlborg wrote:
> On 2014-09-19 17:32, Andrei Alexandrescu wrote:
>
>> Whenever a reference to a Throwable is copied about, passed to
>> functions, the compiler inserts appropriately calls to e.g. incRef and
>> decRef. (Compiler may assume they cancel each other for optimization
>> purposes.) Implementation of these is up to the runtime library.
>
> Are you suggesting we implement ARC?
Yes. -- Andrei
|
September 20, 2014 Re: RFC: reference counted Throwable | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Friday, 19 September 2014 at 15:32:38 UTC, Andrei Alexandrescu wrote:
> First, there must be some compiler flag -nogc or something, which triggers the RC exceptions. All modules of an application must be compiled with this flag if it is to work (such that one module can throw an exception caught by the other). Of course a lot of refinement needs to be added here (what happens if one tries to link modules built with and without -nogc, allowing people to detect the flag programmatically by using version(nogc) etc).
Won't using -nogc preclude using this in Phobos/Druntime?
How about instead of a new switch, change the name mangling of anything that inherits from RCObject? E.g. 'C' is used for classes, 'R' could be used for reference-counting classes. Then an ordinary version block can be used to switch between the two.
|
September 20, 2014 Re: RFC: reference counted Throwable | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On 9/19/2014 8:32 AM, Andrei Alexandrescu wrote: > As discussed, having exception objects being GC-allocated is clearly a large > liability that we need to address. They prevent otherwise careful functions from > being @nogc so they affect even apps that otherwise would be okay with a little > litter here and there. > > The Throwable hierarchy is somewhat separate from everything else, which makes > it a great starting point for investigating an automated reference count > approach. Here's what I'm thinking. > > First, there must be some compiler flag -nogc or something, which triggers the > RC exceptions. All modules of an application must be compiled with this flag if > it is to work (such that one module can throw an exception caught by the other). > Of course a lot of refinement needs to be added here (what happens if one tries > to link modules built with and without -nogc, allowing people to detect the flag > programmatically by using version(nogc) etc). Having a compiler switch to change the behavior of every module in incompatible ways would be a disastrous balkanization. It has to be done in such a way that the ARC and the existing exceptions can coexist. > If -nogc is passed, the compiler severs the inheritance relationship between > Throwable and Object, making it impossible to convert a Throwable to an Object. > From then henceforth, Throwable and Object form a two-rooted forest. (In all > likelihood we'll later add an RCObject root that Throwable inherits.) > > Whenever a reference to a Throwable is copied about, passed to functions, the > compiler inserts appropriately calls to e.g. incRef and decRef. (Compiler may > assume they cancel each other for optimization purposes.) Implementation of > these is up to the runtime library. Null checking may be left to either the > compiler or the library (in the latter case, the functions must be nonmember). > However it seems the compiler may have an advantage because it can elide some of > these checks. > > Once we get this going, we should accumulate good experience that we can later > apply to generalizing this approach to more objects. Also, if things go well we > may as well define _always_ (whether GC or not) Throwable to be reference > counted; seems like a good fit for all programs. > > Please chime in with thoughts. > > > Andrei |
September 20, 2014 Re: RFC: reference counted Throwable | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On 9/19/14, 6:18 PM, Walter Bright wrote:
> Having a compiler switch to change the behavior of every module in
> incompatible ways would be a disastrous balkanization. It has to be done
> in such a way that the ARC and the existing exceptions can coexist.
Could you please elaborate why the disaster? -- Andrei
|
September 20, 2014 Re: RFC: reference counted Throwable | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On Saturday, 20 September 2014 at 01:19:05 UTC, Walter Bright wrote: > Having a compiler switch to change the behavior of every module in incompatible ways would be a disastrous balkanization. Don't -version, -debug etc. have this problem anyway? Anyway, if you change the name mangling, then you'll get link errors instead of mysterious crashes. > It has to be done in such a way that the ARC and the existing exceptions can coexist. How? |
September 20, 2014 Re: RFC: reference counted Throwable | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On 9/19/2014 6:48 PM, Andrei Alexandrescu wrote:
> On 9/19/14, 6:18 PM, Walter Bright wrote:
>> Having a compiler switch to change the behavior of every module in
>> incompatible ways would be a disastrous balkanization. It has to be done
>> in such a way that the ARC and the existing exceptions can coexist.
>
> Could you please elaborate why the disaster? -- Andrei
>
1. Every library for D will have to come in two versions. One which works, and the other is likely untested. This will divide the D community in half.
2. RC and GC engender different styles of programming. The idea that one can successfully switch between them with merely a compiler switch is a fantasy. You cannot write non-trivial programs that function well and pay no attention to how memory management is done.
|
September 20, 2014 Re: RFC: reference counted Throwable | ||||
---|---|---|---|---|
| ||||
Posted in reply to Vladimir Panteleev | On 9/19/2014 7:04 PM, Vladimir Panteleev wrote: > On Saturday, 20 September 2014 at 01:19:05 UTC, Walter Bright wrote: >> Having a compiler switch to change the behavior of every module in >> incompatible ways would be a disastrous balkanization. > > Don't -version, -debug etc. have this problem anyway? I submit that it is a poor practice to write code that way. > Anyway, if you change the name mangling, then you'll get link errors instead of > mysterious crashes. > >> It has to be done in such a way that the ARC and the existing exceptions can >> coexist. > > How? Good question. It's a challenge. But it has to be done, or D will divide in half and both halves will fail. We've had this discussion numerous times before - "throw the magic compiler switch" and D becomes an ARC system and everything is wonderful. It cannot work. ARC and GC are not equivalent. |
September 20, 2014 Re: RFC: reference counted Throwable | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On Saturday, 20 September 2014 at 02:26:49 UTC, Walter Bright wrote:
> Good question. It's a challenge. But it has to be done, or D will divide in half and both halves will fail.
>
>
> We've had this discussion numerous times before - "throw the magic compiler switch" and D becomes an ARC system and everything is wonderful. It cannot work. ARC and GC are not equivalent.
I basically agree with Walter on this one, no switch please, it's maintenance nightmare for library devs.
My proposal would be to permanently use ARC for Throwable, no flags.
What does the GC bring to exceptions that makes it sufficiently invaluable to warrant two parallel implementations? It can't be about performance, since _thrown_ exceptions are already in the slow path... Backwards compatibility?
|
Copyright © 1999-2021 by the D Language Foundation