> I suspect the "bug" may be in my understanding of the memory
> management API, though. If I want to maintain a linked-list of my own
> objects, how do I do it? If I carve out my objects (hash buckets) from
> a Buffer, then GC would keep moving them around and breaking the
> ->next link pointers. Setting the immobile flag doesn't seem to do it,
> probably for the same reason that the GC PDD says "don't set this on
> Parrot_allocated memory". I guess if there were a way of registering a
> callback for when the memory gets moved, I could use that to fix
> things up, but that would bloat up the Buffers.

I think the only way to accomplish this with the current GC is with PMCs.
Buffers almost work, but they don't allow for custom mark routines, and
thus can't do intelligent stuff on their data. Not sure if this is by
design, or something that just needs implementing. You could write a PMC
which points to a buffer, and in the buffer, store two things. First, is a
'next' pointer, which points to a PMC header. The second is the contents,
be it the node data itself, or a pointer to a header (buffer or PMC,
doesn't matter).

Then write a custom 'mark' method which correctly mark_used's the next
pointer, and may ignore, mark_used, or buffer_lives the contents of the
node data, depending upon whether it's struct data, a PMC pointer, or a
buffer ptr.

As far as a hashtable implementation goes, from a conversation I had with
Dan about hashtables and GC. I think it's quite similar to what you're
already doing, but there might be some differences:
- Make an array of buffer data, in order of insertion into the hashtable.
set pmc_pointer and buffer_ptr and let the GC rip through it.
- The hashtable itself just uses indices into this array. Each
linked-list node would be a PMC header, that follows the logic mentioned
above, where the linked-list node data would simply be an integer lookup
into the array of buffer data.

> For now, is it the case that if you want to store pointers in memory,
> you have to use mem_sys_allocate() for anything pointed to?

Yes. And luckily, PMC headers and Buffer headers are allocated in pools
which were allocated with mem_sys_allocate. It's always safe to point to
them...never to their contents.

> Btw, this is only a weak guess about what's going on, because the
> corruption I'm seeing isn't even in the linked list nodes. It only
> happens with GC_DEBUG, but it's not an infant mortality bug.

GC_DEBUG adds extra calls to do_dod_run (infant mortality), and
do_collect. You're likely running into problems where you are referencing
memory which is getting moved out from under you. Instead of blindly
referencing the data in the buffer itself, you should be referencing the
buffer header.

Looking forward to seeing a hashtable implementation sometime soon.. :)

Mike Lambert

Reply via email to