Around 23 o'clock on Nov 30, MenTaLguY wrote:
It looks really interesting to me. I'm not sure it would address
the
general problems we've had with garbage collection[1], nor that it
offers everything we need for C++.
I don't know that it is a good solution, I've just heard from other people
using the Boehm collector that it had "issues" which my little GC system
appears to solve and was wondering if it might be of interest to you as
well.
I have to say I find the use of a "reference stack" in
avoiding the need
to examine the stack or registers to be very elegant.
I was much more interested in portability than transparent use, and with
some practice, it's not that hard to use the macros. One nice thing is
that forgettin to use the macros causes no harm, it just delays the
collection of garbage collected below the function failing to invoke the
macros.
The one issue that does come to mind is the problem of storing
references to collector-managed objects in malloc-managed memory.
And this is easy enough with the nickle collector -- you create a
synthetic object and add it as another root in the system. The 'mark'
function then walks the malloced memory to reference the gc'able objects.
The malloc'ed storage need never know that it's being used in this fashion.
Is there any alternate way the nickle collector could assist us in
marrying the collected and uncollected worlds?
I think the fact that the mark functions are under your control could
yield some benefits, it permits the kind of redirection suggested above.
That would be exceptionally nice to have, especially as large RGBA
image
buffers have a decent chance of looking a lot like arrays of valid
pointers in places.
heh. One wonders how much of the GC time is spent wandering through
non-pointer data. Think of the cache thrashing when you hit something
like this which isn't explicitly marked as non-pointer data...
* implementing other allocation interfaces:
- array new/delete
- an STL allocator
- use in automatic variables
I don't know enough about C++ to understand why this is a special case...
* finalization (required e.g. when collector-managed objects
reference purely refcounted objects)
The nickle collector includes finalizers.
* situations where 'Managed' isn't the root of a class
hierarchy
(e.g. as a result of multiple inheritance) -- we'd basically
need a facility to get the base address of a collector-managed
object, given an interior pointer like boehm's GC_base()
The collector used to have this ability; each malloc'd block of memory
(containing multiple objects) was stored in a balanced binary tree so that
you could search for an object by interior address. I used to need this
when the collector was part of a lisp implementation that exposed strings
as cdr'able objects. Nickle no longer needs this, so I ripped it out.
Restoring this to the collector would be straightforward, it would mostly
be a matter of going back to a previous version in CVS and stealing the
AVL code. Although, I'd prefer to reimplement it using skip lists as AVL
trees are difficult to walk in-order without recursion, while skip lists
are trivial.
Thanks much for taking time to look at the code; the prototype C++ code
looks a lot easier to use than the C macros. Note that you'll still want
to use the macros in places like:
a () { return new a_type; }
b () { return new b_type; }
c () { return new c_type; }
bar () { operate (a (), b(), c()); }
foo () { for (i = 0; i < 100; i++) bar (); }
Failing to use the macros in bar will result in a large pile of
uncollectable garbage until foo returns to some higher level function
which does use the macros. This is probably the most annoying part of the
whole system.
Oh, one thing I used to do was erase newly allocated memory. This was a
huge simplification as it meant you didn't need to be particularily
careful about allocation and initialization order. As it is, any
potential pointer values in newly allocated data must be initialized
before the next allocation call is made. This turned out to be a
non-trivial source of bugs when I stopped calling memset. I'm not sure
it's worth the modest performance improvements myself.
-keith