
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