guile-devel
[Top][All Lists]
Advanced

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

Re: gc issues


From: Michael Livshin
Subject: Re: gc issues
Date: 13 Sep 2000 11:40:26 +0300
User-agent: Gnus/5.0807 (Gnus v5.8.7) XEmacs/21.1 (20 Minutes to Nikko)

Dirk Herrmann <address@hidden> writes:

> With regards to multiple threads running, free cells should be
> conservatively scanned.  If we look at object initialization, it is done
> (or should be) as follows:
> 
> - get a new cell
> - initialize everything but the cell's type entry
> - finally, initialize the cell's type entry
> 
> With multiple threads, where one might be running a gc, it is essential,
> that the type entry is initialized last, because if guile's gc finds a
> type entry, then it assumes that all cell entries are correctly
> initialized.  In other words, if the type entry was initialized, but the
> rest of the cell holds some bogus data, then guile will crash during gc.
> 
> However, even if this pattern was followed throughout guile, there would
> still be the chance, that references get lost:
> 
> SCM make_foo_from_bar (SCM bar)
> {
>   SCM foo;
> 
>   SCM_NEWCELL (foo);
>   SCM_SET_CELL_OBJECT_1 (foo, bar);     /* 1 */
>   SCM_SET_CELL_TYPE (foo, scm_tc_foo);  /* 2 */
> }
> 
> From the compilers point of view, there is no need to keep bar in a local
> variable or register beyond the line marked '1'.  In the example above
> this is unlikely, since there is not much code executed between lines 1
> and 2.  But even in that example:  Assume that the compiler has, in order
> to execute line 2, to fetch scm_tc_foo from memory into a register.  It
> may then use the register which previously held bar.  If a thread switch
> occurs immediately after that, there is no reference any more to bar on
> the stack.  However, there _is_ a reference to bar within the new cell,
> but this can only be found if free cells are scanned conservatively.

hacks are always possible, but here it's better to change the
methodology slightly, I think.

how about the following addition to the API (untested):

#define SCM_NEW_CELL(cell, type, obj1) \
   do {\
     scm_remember (&(obj1));\
     SCM_NEWCELL (cell);\
     SCM_SET_CELL_OBJECT_1 (cell, obj1);\
     SCM_SET_CELL_TYPE (cell, type);\
   while (0)

and something similar for doublecells, of couse.

then the above code would look like:

SCM make_foo_from_bar (SCM bar)
{
  SCM foo;

  SCM_NEW_CELL (foo, scm_tc_foo, bar);
}

looks cleaner too, don't you think?

I'm not sure about the name, as always.

[ one might find the conflation of cell creation and initialization
  somewhat distasteful, but I think that's fine -- who would need an
  uninitialized cell anyway? ]

> The recent changes to the garbage collector made the use of a
> scm_tc_allocated type tag unnecessary.  However, this means, that if
> some code obtains a fresh cell, the type tag of this cell will still be 
> scm_tc_free_cell.
> 
> So far, everything is great.  But, this breaks the way the
> SCM_DEBUG_CELL_ACCESSES debug mode works.  When enabled, this mode checks
> every cell access (read or write), whether a free cell is accessed.  The
> purpose is to detect erroneously freed cells (because for whatever reason
> the reference was temporarily lost and the gc freed the cell).
> 
> There are some options how this can be fixed:
> 
> - get rid of that debugging mode at all.
> - only check read accesses (this will probably work, because the first
>   thing that is done with a new cell is to overwrite its contents _and_
>   cell type with something that makes sense.)
> - re-introduce some scm_tc_allocated tag, but use it only when debugging.
> 
> Maybe there are other/better solutions.

would just checking read accesses be fine?  it seems the simplest
solution to me.  can you think of any examples where the coverage it
provides is insufficient?

-- 
Being really good at C++ is like being  really good at using rocks to
sharpen sticks.
                -- Thant Tessman



reply via email to

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