guile-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: the new gc asserts in master


From: Han-Wen Nienhuys
Subject: Re: the new gc asserts in master
Date: Thu, 28 Aug 2008 01:33:47 -0300
User-agent: Thunderbird 2.0.0.16 (X11/20080723)

Andy Wingo escreveu:
> Hi again!
> 
> On Wed 27 Aug 2008 12:00, Andy Wingo <address@hidden> writes:
> 
>> On Wed 27 Aug 2008 07:00, Han-Wen Nienhuys <address@hidden> writes:
>>
>>>>>>     http://thread.gmane.org/gmane.lisp.guile.user/6372
>>> I think reference counting is the correct solution for this, as far as
>>> I understand the problem from the quoted message.
>> I don't think so; the use case is that (1) we don't want to prevent the
>> C object from being freed, so we don't want to hold a reference on the C
>> object; but (2) we do want to know when it is freed, so we can release
>> our cache; but (3) we want to get the scheme object back if the object
>> has not in fact been swept.


As far as I understand, you are splitting the decision whether an
object is live (reachable) between C and SCM - it's reachable when
there is an SCM reference, but it is also reachable when there is no
SCM reference anymore, but it is still reachable by looking at a C
table and returning the SCM reference inside the C struct.

You can never get a consistent model if you try to split it up like that.
Either the memory management is entirely in SCM (using (weak) hash tables
in SCM and GC which decides whether an object is reachable) or the memory 
management is entirely in C (eg. using ref counting). 

If you try to mix both, you'll get a frankenstein with cloudy semantics 
and edgy corner cases.

> I don't think this is exactly right. I was discussing this on IRC with
> Ludovic and he made me come out with a better characterization of the
> problem.
> 
> Consider a C object, `C'. We wrap it in scheme with a SCM object, `S'. S
> has a reference on C, using reference counting. C has some kind of API
> to associate S with it: set_ptr() and get_ptr(). Cool.
> 
> So what happens if we get C back from a callback at some time in the
> future? Well we call get_ptr(C) and return that if it's non-null.
> Otherwise we make a new smob and call set_ptr (C, S) and then return S.

> 
> So what happens if the scheme object becomes collectable? Well S has a
> free function which will unref the C object and set_ptr (C, NULL). This
> is also OK.
> 
> But what if it goes like this:
> 
>   S becomes collectable in theory
> 
>   mark phase: S is indeed marked as collectable
> 
>   C is returned from a callback: get_ptr() return S
> 
>   at some later time the card containing S is swept; S's free function
>   is run, and S is marked as a free cell

Here you are dividing the responsibity of liveness between SCM and C. SCM 
decides the object is dead, but you hold on to it in in C, and then insert the
dead reference back into SCM, leading to crappage.

I think it is wrong to equate (destructor has run) with (object is
reachable).  One of the important points of GC (RAII will say it's a
detractor) vs. C++ smart pointer is that going out of scope and
running the destructor to go with that can happen at different points
in time.  Between these points, the objects are in a sort of limbo:
you can't do return them back to the 'live' part of the program, but
the destructror hasn't run yet.

-- 
 Han-Wen Nienhuys - address@hidden - http://www.xs4all.nl/~hanwen





reply via email to

[Prev in Thread] Current Thread [Next in Thread]