[LLVMdev] LLVM's GC support

Paul Melis p.e.c.melis at alumnus.utwente.nl
Sun Dec 6 09:19:43 PST 2009

Hi Gordon,

Gordon Henriksen wrote:
> On 2009-12-04, at 09:34, Paul Melis wrote:
>> I hope you don't mind me sending this mail directly to you (instead
>> of to llvm-dev), but you seem to be the expert on LLVM's GC support
>> :)  If you'd rather have me send to llvm-dev, please say so.
> You'll reach a wider audience with the list, though I haven't been
> able to keep up with it lately.
>> I'm trying to get a very simple copying collector to work with
>> LLVM, basically your standard semi-space collector with Cheney scan,
>> using the included shadow stack support to track roots. I'm writing
>> everything in C, using llvm-gcc's gcroot attribute in a test app to
>> mark GC roots where appropriate, which seems to work fine when
>> translating to LLVM IR (and finally an executable).
> Be forewarned that this attribute should be considered ‘experimental’
> at best.
>> Implementing a GC is actually quite new to me, so perhaps that's
>> where I'm getting confused. Anyways, suppose I have a function that
>> has a pointer to a GC-tracked object as a parameter and a collection
>> can be triggered from this function, e.g.
>> object*
>> f(object *some_obj)
>> {
>>    object __attribute__((gcroot)) *new_obj;
>>    new_obj = allocate_object();
>>    // A collection could have been executed at this point,
>>    // and so some_obj might have become invalid
>>    new_obj->child = some_obj;
>>    return new_obj;
>> }
> To ensure that *some_obj isn't collected prematurely, your code will
> need to copy the value of some_obj into a gcroot local at the top of
> the function body.
> You also need to beware of temporaries:
>     object *f();
>     object *g();
>     void h(object *x, object *y);
>     void func() {
>       // dangerous
>       object __attribute((gcroot)) *result1 = h(f(), g());
>       // safer
>       object __attribute((gcroot)) *temp1 = f();
>       object __attribute((gcroot)) *temp2 = g();
>       object __attribute((gcroot)) *result2 = h(temp1, temp2);
>     }
>> How can I ensure that the pointer parameter (or any other root)
>> is updated during the collection phase? It seems that LLVM's shadow
>> stack data structures only provide the root objects pointed to and
>> not the memory locations of the pointer variables holding the roots.
> The shadow stack structure is itself the storage location for the
> variables; the LLVM IR is rearranged to read the stack roots directly
> from the shadow stack.
Ah, clever trick. Thanks for all the comments above, I now seem to have
my stuff working!


More information about the llvm-dev mailing list