On Mon, May 21, 2007 at 06:48:25PM -0700, Allison Randal wrote:

> On variable-sized PMCs, I generally agree with the goals the proposal is 
> trying to accomplish, but I want to tackle these goals in a simpler way. 
> One of the goals mentioned for the proposal was to shrink down the size 
> of PMCs, but it's hard to get much smaller than a struct containing 1 
> struct, 1 pointer to a struct, and a pointer to the vtable, where both 
> of the 2 contained structs can be null.

Apart from

struct PMC {
    struct PMC_DATA *data;
    struct VTABLE *vtable;
};

where the data pointer isn't allowed to be NULL, and what it points to is

struct PMC_DATA {
    ...                 /* Fixed stuff */
    char your_stuff[1]; /* Actually variable length. */
}


Or if it is allowed to be NULL, that NULL has one very well defined meaning, 
with
assumed defaults for all the parts of "Fixed stuff"

> So, rather than making the core PMC struct variable sized, I want to 
> make one of its contained structs variable sized. This is already a 
> common practice, storing a structure pointer in PMC_data. I also want to 
> eliminate the union value from the pobj_t struct. The concept that a PMC 
> contains either a buffer, 2 pointers, 2 ints, a float val, or a string 
> val, and that these all must overlap in storage is shortsighted. One 
> thing that would convince me otherwise is the argument that it's good to 
> have some core PMC data accessible without a pointer dereference. 

I believe that it was intended as a caching layer, precisely to avoid a pointer
dereference. I can't remember far enough back offhand, but it would not surprise
me if the original structure was cache line aligned on ILP32 systems.

> Standing against that is the fact that we're currently allocating (a 
> small piece of) memory for every PMC that may never be used.

This sounds like it ends up with a very similar system to Perl 5's SVs, with
fixed sized heads and variable sized bodies.

IIRC Dan's reason for really not wanting variable sized bodies was the 
experience
of 5005 threads - if the body can be reallocated, then you need take a lock to
even read it, in a multi-threaded environment.


> This is an alternate structure I'm considering:
> 
>     struct PMC {
>         Parrot_UInt flags;
>         DPOINTER *data;          /* Modifiable for each PMC */
>         VTABLE *vtable;
>         struct PMC_EXT *pmc_ext; /* auxiliary data */
>     };
> 

Would it be better to have one pointer to data, and state that free-form data
follows in memory immediately after this structure?

>     struct PMC_EXT {
>         PMC *_roles;                /* runtime roles */
>         PMC *_metadata;             /* properties, replaced by a role */
>         struct _Sync *_synchronize; /* [to be deprecated, see STM] */
>         PMC *_next_for_GC;          /* [GC hack, may be replaced] */
>     };

I'm not sure if the design axioms behind Dan's desire to avoid locking for 
reading
remain. In particular, is the assumption now that if a PMC becomes visible to 
more
than one thread (by being shared) then its vtable is changed to an alternative
vtable that performs locking?

And how often does the type of a PMC change, such that its internal data layout
changes? In Perl 5 this morphing happens everywhere, but in Parrot?


Nicholas Clark

Reply via email to