To make sub classing pmc from pir work correctly, I planned to make the following changes to the parrot core. Here is a example to clarify things a little bit up. If you create for example an oject which is sub classed from the exception pmc class in pir now you get the following structure. You get a pmc which is a instance object in which there is a field "proxy¨ which points to the pmc holding the object. Here is a description of the actual memory layout. I could be not all information is complete or 100% correct. pmc flags *vtable -> = interp->vtables[394] (example) *data = Parrot_Object_attributes _class -> to a pmcproxy pmc describing the pir subclass of exception pmc class = interp->vtables[394]->_classe (example) _attrib_store = pmc flags *vtable -> vtable of resizeable pmc array = interp->vtables[enum_class_ResizablePMCArray] *data = Parrot_ResizablePMCArray_attributes size -> equal to the size of the amount of attributes in the object in this case = 13 fields + 1 for proxy **pmc_array -> array of 14 pmc objects [0] proxy = pmc flags *vtable -> to pmcproxy pmc describing the exception pmc class *data id = INTVAL birthtime = FLOATVAL etc thrower = PMC* *metadata *_synchronize *_next_for_GC [1] id = pmc holding a boxed intval [2] birthtime = pmc holding a boxed floatval etc [13] thrower = pmc resize_threshold *metadata *_synchronize *_next_for_GC *metadata *_synchronize *_next_for_GC *Note that all attributes of the base pmc object are stored twice interp ... **vtables [...] [enum_class_ResizablePMCArray] *_namespace -> [parrot] base_type -> enum_class_ResizablePMCArray *whoami -> String holding "ResizablePMCArray" flags *provides_str "scalar" *isa_hash -> hash containing item "Exception" *pmc_class = pmc flags vtable -> null or points to pmc of type pmcproxy describing the pmcproxy pmc class *data id -> = vtable->base_type *name -> = vtable->whoami *fullname *_namespace -> = vtable->_namespace (at least should be) instantiated -> 1 class is instantiated *parents *all_parents -> = vtable->mro *roles -> provides same information as vtable->provides_str *methods *vtable_overrides *attrib_metadata -> build from vtable->attribute_defs *attrib_index *attrib_cache *resolve_method *parent_overrides *metadata *_synchronize *_next_for_GC *mro -> pmc array holding parents *attribute_defs -> "Iid Fbirthtime Smessage Fpayload etc " *ro_variant_vtable -> vtable where only flags and functions are different rest is redundant the list of functions [...] [394] *_namespace -> [parrot;mypackage;myclass] base_type -> 394 *whoami -> String holding "myclass" flags *provides_str "scalar" (cloned from interp->vtables[enum_class_ResizablePMCArray]) *isa_hash -> hash containing item "Exception" (cloned from interp->vtables[enum_class_ResizablePMCArray]) *pmc_class = pmc flags vtable -> null or points to pmc of type pmcproxy describing the pmcproxy pmc class *data id -> = vtable->base_type *name -> = vtable->whoami *fullname *_namespace -> = vtable->_namespace (at least should be) instantiated -> 1 class is instantiated *parents *all_parents -> = vtable->mro *roles -> provides same information as vtable->provides_str + extra added roles *methods *vtable_overrides *attrib_metadata -> build from vtable->attribute_defs + extra added attributes *attrib_index *attrib_cache *resolve_method *parent_overrides *metadata *_synchronize *_next_for_GC *mro -> = this->pmc_class->all_parents *attribute_defs -> "Iid Fbirthtime Smessage Fpayload etc " (cloned from interp->vtables[enum_class_ResizablePMCArray]) *ro_variant_vtable -> vtable where only flags and functions are different rest is redundant a clone(from interp->vtables[enum_class_ResizablePMCArray]) the list of functions -> cloned from interp->vtables[enum_class_ResizablePMCArray] ... My plan is to do the following things * Make all pmc an object *Move all functionality from object.pmc to default.pmc - Remove object.pmc - Rename default.pmc to object.pmc *Move the _attrib_store to the pmc struct *Doing this by combining it into the *data field -change the indexing mechanism of class.pmc -DISCUSS! whether where are going to store (U)INTVAL and FLOATVAL as primitive or as boxed items (see below) *Remove all fields form vtable except the functions *This will remove redundant fields in the system *Add vtable and ro_vtable field to class.pmc *replace interp->vtables by interp->classes -bootstrap, loading/initing of the core pmc class object -registering of new classes *replace pmc->vtable by pmc->_class *Remove the pmcproxy.pmc class This will result in the following things. *all pmc items becoming object, without any extra memory usage, except for extra attributes in class.pmc -so their attributes can be accessed via pir. -We migth want to make an option to declare certain fields in a pmc as private. * subclassing from pir works as expected * typeof and related ops works as expected see tickets #879 #880 +more * will solve several different tickets * memory usage reduction (big one :) ) * performance boost * the pmc structure will become struct PMC { Parrot_UInt flags; PMC *_class; DPOINTER *data; /* with different structure see xx*/ PMC *_class; PMC *_metadata; /* properties */ struct _Sync *_synchronize; PMC *_next_for_GC; /* other are busy removing this one */ } * interp->vtables replaced by interp->classes * 2 added fields to class.pmc holding vtable and read only vtable * added field to class.pmc to handle new indexing mechanism * vtable struct will only contain the pointers to the functions The data structure will become an array of aligned items. For example I would have the following items which is created in pir code by extending the pmc class somepmcclass. * INTVAL myint * FLOAT myfloat * DOUBLE mydouble * PMC * aPMC * PMC added by pir class this also is PMC* "addedpmc" * DOUBLE added by pir class "addeddouble" * FLOAT added by pir class "addedfloat" If a would compile on a 32 bits i368 machine then alignSize = 4 byte INTVALSize = 4 byte FLAOTSize = 4 byte DOUBLESize = 8 byte pointSize = 4 byte So my index will be come myInt = 0 myfloat = 1 mydouble = 2 aPMC = 4 /* double uses to aligmentSizes */ addedpmc = 5 addeddouble = 6 addedfloat = 8 The struct of this class for the code in pmc class will look in this typedef struct Parrot_somepmcclass_attributes { INTVAL myint; FLOAT myfloat; DOUBLE mydouble; PMC * aPMC; } Parrot_somepmcclass_attributes; The class.pmc will also get a extra field which tells on which indexes there are pmc objects present, which is needed for the mark function. In the example described above this will become. int * = [4,5] Because my plan is to store all primitive as primitives as done now in pmc classes I might get the following problem. When I have a hll which does not use parrot boxed type but it own type, it will get a parrot boxed type if does return from getattribe op. But the same problem also happens with the box op. I do not know the details of this but a hll could override these ops to solve this problem. Ok we then have solved that problem. The big question which leave my are there any hll which stores extra information onto a integer,float or double which have to be preserved when doing set attribute and after that doing a get attribute. Because this is a big change I made a plan for myself to implement this in phases. Here is the list of phases I planned for this change. * move object attribute store to pmc struct by adding extra field _pmc_array (done) -storage does not have to be re-sizable because ones class is instantiated it can't add or remove any properties to the class * add interp->classes field and allocation stuff (done) * add vtable and ro_vtable field in class.pmc (done) * add bootstrap code to load interp->classes data (understanding of pmc2c.pl done, now to change it) * add class registering code for interp->classes data * replace interp->vtable[] code by interp->classes[]->vtable * replace pmc->vtable by pmc->class * make new indexing system * merge newly created _pmc_array with data and remove _pmc_array again * move functionality of object.pmc to default.pmc * hope merging of vtable functions goes correctly that none of the important object acces vtable function overlap with other vtable functions in other pmc objects * removal of pmcproxy class * removal of object.pmc * rename default.pmc -> object.pmc * remove any left references to the fields in vtable struct except the functions doh * remove these fields * cleanup of code, broken test etc, coding std Of course unexpected things can let me reshuffle this list. After the change the same memory layout as above will look like pmc flags *_class -> = interp->classes[394] (example) *data [0] id = INTVAL [1] birthtime = FLOATVAL etc [12] thrower = pmc* *metadata *_synchronize *_next_for_GC *Note that in this case there is no DOUBLEVAl present other wise that one would take up 2 indexes interp ... **classes [...] [394] flags _class = pmc object flags _class -> = interp->classes[enum_class_Class] points to the class describing the class.pmc *data id -> = 394 *name -> = "myclass" *fullname *_namespace -> = [parrot;mypackage;myclass] instantiated -> 1 class is instantiated *parents *all_parents *roles *methods *vtable_overrides *attrib_metadata *attrib_index -> index using new indexing mechanism *attrib_cache *resolve_method *parent_overrides *vtable -> vtable holding only function pointers (initialily cloned from pmc base obect) *ro_vtable -> vtable holding only function pointers (initialily cloned from pmc base obect) *is_pmc_index -> telling which attributes in the pmc->data are pmc (pobj*) objects *metadata *_synchronize *_next_for_GC Because it is a big change, it would be fine to have separate branch for this. If you guys accept my plan :).