On Mon, Apr 29, 2002 at 01:41:56PM -0400, Mike Lambert wrote:
> > 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.

This is similar to what I'm doing. I have a PMC (a PerlHash) whose
->data member is a Buffer (actually a subclass HASH of Buffer with
extra fields.) The PMC's mark() vtable entry correctly traverses
through the HASH's PMCs and Buffers.

> 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.

I don't want to pay for a whole PMC for each bucket, but that would
work.

I've considered using indexes instead of pointers, since it's a
trivial change to the current code. But it makes the code a little bit
uglier and it just seems wrong to me that you can't safely use
parrot's memory routines for data structures with self-referential
pointers. It all needs to be GC-aware to some degree, but I guess I'd
prefer to write an update_self_on_move() routine just so the rest of
the code can live in a make-believe world where I can implement things
exactly the same as I would without GC.

And maybe this is unfounded, but from a performance standpoint using
bufstart[link_index] all the time instead of *link feels slower -- not
because of the extra arithmetic, but because the CPU's code scheduler
has to assume that the memory location you're referencing can conflict
with any other memory address in the pipeline. And there should be a
lot more hashtable lookups than garbage collections, so I'd rather
penalize the latter.

> > 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.

Doesn't look like it. I've instrumented every place where memory gets
moved around, and it appears that even though it is correctly marking
my Buffer as live, it's still copying something else onto its memory.
Which is in itself not a problem, because that's what I thought should
happen -- but it should be copying my stuff to somewhere else first! I
feel discriminated against. My memory isn't as important as someone
else's.

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

Well, if you're anxious, I sent out a working one last week. It just
relied on mem_sys_allocate() for everything and nothing ever got
collected. :-)

Reply via email to