RFC: Pinning interface for the GC

Rainer Schuetze r.sagitario at gmx.de
Sun Oct 14 02:50:29 PDT 2012



On 10/13/2012 8:58 PM, Alex Rønne Petersen wrote:
> Hi,
>
> With precise garbage collection coming up, and most likely compacting
> garbage collection in the future, I think it's time we start thinking
> about an API to pin garbage collector-managed objects.
>
> A typical approach that people use to 'pin' objects today is to allocate
> a chunk of memory from the C heap, add it as a root [range], and store a
> reference in it. That, or just global variables.

I guess people don't think about pinning because the GC is not moving 
objects ;-)

As of today, you usually add a root to a garbage collected memory object 
to keep it in memory (and it can be scanned precisely), but you add a 
range to a memory chunk not managed by the garbage collector for 
scanning (you can't pass type info for this, so it is scanned 
conservatively).

So this discussion is about addRoot/removeRoot, not addRange/removeRange 
(at least in the terminology of the current gc implementation).

>
> This is kind of terrible because adding the chunk of memory as a root
> forces the GC to actually scan it, which is unnecessary when what you
> really want is to pin the object in place and tell the GC "I know what
> I'm doing, don't touch this".
>
> I propose the following functions in core.memory.GC:
>
>      static bool pin(const(void)* p) nothrow;
>      static bool unpin(const(void)* p) nothrow;
>
> The pin function shall pin the object pointed to by p in place such that
> it is not allowed to be moved nor collected until unpinned. The function
> shall return true if the object was successfully pinned or false if the
> object was already pinned or didn't belong to the garbage collector in
> the first place.
>
> The unpin function shall unpin the object pointed to by p such that it
> is once again eligible for moving and collection as usual. The function
> shall return true if the object was successfully unpinned or false if
> the object was not pinned or didn't belong to the garbage collector in
> the first place.
>
> Destroy!
>

Your proposal splits the addRoot-functionality of holding reference, 
scanning and moving a garbage-collected object into two functions 
addRoot/pin. For a non-moving garbage collector, this is not really an 
issue.
Adding a root means that there is a reference to the object somewhere 
outside the reach of the garbage collector, so moving it would make that 
reference invalid.
Not scanning the root object could cause referenced memory chunks to be 
collected, making the root object invalid.
So I think the addRoot functionality should not change, tearing it apart 
could create invalid references.

The pin/unpin functions do make sense for a moving garbage collector, 
but your motivation above is misleading. It is not related to adding 
roots or ranges, though I guess using roots is the safer way. Well, 
thinking about it again, what's the use case of pinning without an 
external reference and keeping the object alive, just as addRoot would do?

Another question, which also affects addRoot/addRange: should there be a 
pin/unpin counter, so that an object that is pinned twice also needs to 
be unpinned twice to be movable again? This cannot be implemented by the 
simple NO_MOVE flag mentioned by David. roots and ranges implement it, 
but in a slightly inefficient way because the memory is scanned multiple 
times then.


More information about the Digitalmars-d mailing list