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