[Top][All Lists]

[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]