From: chromatic <[EMAIL PROTECTED]>
   Date: Sun, 24 Feb 2008 17:22:19 -0800

   On Sunday 24 February 2008 16:55:48 Bob Rogers wrote:

   > Why do constant PMCs ever need to point to non-constant ones?  In other
   > words, why are those pointed-to PObjs not also constant?

   The reason is practical.  PMCs have headers and bodies.  When we
   create a PMC, we first create a header.  This header can come from a
   constant pool or a non-constant pool.

   With the header, we initialize the PMC.  The PMC may contain other
   PMCs.  For example, a String PMC contains a STRING.  Thus the
   initializer itself might allocate new PMCs . . .

Granted, and it's tough to make a PMC truly read-only until after it's
completely initialized . . .

   There's a similar problem for accessors and setters.  Again, that's
   solveable with more code or more cleverness.

So, you're saying it is legal to invoke a setter on a constant PObj?  In
what sense then is that PObj a constant?

   However, it's difficult to determine at the point of allocating a header 
   whether any given PObj is going to end up contained within a constant PMC 
   somewhere... so we'd have to perform this check on every operation that 
could 
   possibly store a PObj in a constant PMC.  That's doable, with plenty of code 
   or cleverness.

   However, some of those PObjs might have active references pointing to them 
   from elsewhere, so silently upgrading them to constant PObjs (that is, 
   allocating a new constant header and then copying everything to that new 
   header) requires fixing up all of the old references.

   That's fixable, but I usually have to go lie down after thinking
   about it.

Do you really need to fix up old references?  After all, if the data
structure truly is constant, other code should have no way of telling
the difference.

   BTW, that is the strategy used by most Lisp systems (and they don't
bother fixing up the old objects).  Typically, there is an internal
"purify" function that makes its argument pure (and therefore read-only)
by copying it recursively into pure space.  This is normally done to
constants when loading compiled code, and also happens to selected data
structures before dumping a new Lisp image.  In these cases, the fact
that the old objects are still non-constant doesn't matter, as they are
usually immediately GCed.  The chief purpose of this, though, is to take
long-lived constant data structures out of the way of GC.

   And, as I'm sure you've noticed, this also gets around the "can't
initialize a constant PMC" problem, without requiring a separate API for
constant creation.

   > IIUC, this is 
   > different from any GC system that I've ever heard of.  The whole point
   > of having "pure space" (or whatever you want to call the readonly
   > constant space) is to avoid having to follow pointers into pure space;
   > this ought to be unnecessary because pure objects can't keep dynamic
   > space objects live.  If you allow pointers from pure space into the rest
   > of the heap, then that invariant no longer applies, and you are forced
   > to trace pure objects just like any other.  Am I missing something here?

   Hysterical raisins, mostly.  This would be easier with a redirection
   scheme or stricter rules on assignment and such.

So I gather that the purpose of read-only PMCs in the current design is
something other than GC efficiency.  Which raises a few questions:

   1.  What *is* the purpose of constant PMCs?  The only mention of "the
constant PMC pool" in PDD17 is part of the explanation of the
"singleton" modifier to "pmclass" -- though the bare reference doesn't
explain much.

   2.  What would be the cost of storing constant PMCs in the normal
pool, and having GC treat them normally?  From what you say, speed is
probably not an issue.  And any non-GC purposes of constant PMCs ought
not to require special GC treatment.  On the other hand, the benefit may
be to squash a whole nasty class of GC bugs.

   > I wish I understood even a tenth part of Parrot's memory management
   > . . .

   docs/dev/ has some good information, but the best way to understand
   it further is to debug it for a while.  Sadly, I think I've fixed
   many of the easier bugs.

   -- c

I was afraid of that.  In the mean time, if you want to bounce ideas or
code off of someone, feel free.

                                        -- Bob

Reply via email to