Idea #1 on integrating RC with GC

Joseph Cassman jc7919 at outlook.com
Wed Feb 5 23:26:05 PST 2014


On Wednesday, 5 February 2014 at 21:03:25 UTC, Brad Anderson 
wrote:
> On Wednesday, 5 February 2014 at 20:18:33 UTC, Adam D. Ruppe 
> wrote:
>> [...]
>> A major source of little allocations in my code is std.conv 
>> and std.string. But these aren't difficult to change to 
>> external allocation, in theory at least:
>>
>> string s = to!string(50); // GC allocates (I'd keep this for 
>> convenience and compatibility)
>>
>> char[16] buffer;
>> char[] s = toBuffer(buffer[], 50); // same thing, using a 
>> buffer
>>
>> char[] s = toLowerBuffer(buffer[], "FOO");
>> assert(buffer.ptr is s);
>> assert(s == "foo");
>>
>>
>> That's not hard to use (though remembering that s is a 
>> borrowed reference to a stack buffer might be - escape 
>> analysis is something we should really have).
>>
>> And it gives full control over both allocation and 
>> deallocation. It'd take some changes in phobos, but so does 
>> the RCSlice sooo yeah, and this actually decouples it from the 
>> GC.
>
> Yeah, because RCSlice would require changes to Phobos too I'd 
> much rather have this approach because it is just so much more 
> flexible and hardly adds any inconvenience.
>
> Combined with the upcoming allocators it would be incredibly 
> powerful. You could have an output range that uses an allocator 
> which stores on the stack unless it grows too big (and the 
> stack size could be completely customizable by the user who 
> knows best). Or you could pass in an output range that 
> reference counts its memory. Or an output range that must 
> remain unique and frees its contents when it goes out of scope.
>
> I think three things would work together really well for 
> addressing users that want to avoid the GC while making use of 
> Phobos. 1) Increasing the support for output ranges, 2) 
> Andrei's slick allocator design, and 3) @nogc. With those three 
> I really think managing memory and avoiding the GC will be 
> rather pleasant. @nogc would enable people trying to avoid all 
> the tough to spot implicit GC allocations to identify them 
> easily. Once uncovered, they just switch to the output range 
> version of a function in Phobos and they then use std.allocator 
> with the output range they feed in to create an ideal 
> allocation strategy for their use case (whether it stack, GC, 
> scope freed heap, reference counted, a memory pool, or some 
> hybrid of those).
> [...]

My thinking as well. That combination of functionality looks very 
advantageous to me. It is more flexible than just providing two 
choices to the programmer: GC and RC. To me both GC and RC are 
useful, depending on the type of program being written. However, 
why limit to just the two? There are other styles of memory 
allocation/management I might need to make use of, perhaps even 
in the same program.

I really like the new allocator module. I had been thinking that 
a goal for its use was to allow replacing the compiler-supported 
allocation style with a custom one, either at the module level or 
on a function-by-function basis, as shown in the code above. In 
my opinion, this would give the necessary flexibility over memory 
allocation by giving final control to the programmer (i.e. 
control over external and internal allocation style). Doing so 
seems good to me as the programmer knows a priori the type of 
allocation pattern to support based on the type of program being 
produced (e.g. real-time, long-running process, batch system). Of 
course minimizing memory allocation in Phobos is an excellent 
goal and that work will proceed orthogonal to this effort. 
However, in the end, some memory will have to be allocated. 
Letting the programmer choose how that memory is to be allocated 
by giving full access to std.allocator seems the way to go.

Joseph


More information about the Digitalmars-d mailing list