Ticket #1020: plan.txt

File plan.txt, 11.1 KB (added by jessevdam, 5 years ago)

the describtion

Line 
1To make sub classing pmc from pir work correctly, I planned to make the following changes
2to the parrot core.
3
4Here is a example to clarify things a little bit up.
5If you create for example an oject which is sub classed from the exception pmc class in pir now you get the following structure.
6You get a pmc which is a instance object in which there is a field "proxyš which points
7to the pmc holding the object. Here is a description of the actual memory layout.
8I could be not all information is complete or 100% correct.
9 pmc
10    flags
11    *vtable -> = interp->vtables[394] (example)
12    *data = Parrot_Object_attributes
13      _class -> to a pmcproxy pmc describing the pir subclass of exception pmc class = interp->vtables[394]->_classe (example)
14      _attrib_store = pmc
15        flags
16        *vtable -> vtable of resizeable pmc array = interp->vtables[enum_class_ResizablePMCArray]
17        *data = Parrot_ResizablePMCArray_attributes
18          size -> equal to the size of the amount of attributes in the object in this case = 13 fields + 1 for proxy
19          **pmc_array -> array of 14 pmc objects
20            [0] proxy = pmc
21              flags
22              *vtable -> to pmcproxy pmc describing the exception pmc class
23              *data
24                id = INTVAL
25                birthtime = FLOATVAL
26                etc
27                thrower = PMC*
28              *metadata
29              *_synchronize
30              *_next_for_GC               
31            [1] id = pmc holding a boxed intval
32            [2] birthtime = pmc holding a boxed floatval
33            etc
34            [13] thrower = pmc
35          resize_threshold
36        *metadata
37        *_synchronize
38        *_next_for_GC 
39    *metadata
40    *_synchronize
41    *_next_for_GC
42   
43*Note that all attributes of the base pmc object are stored twice
44   
45interp
46   ...
47   **vtables
48     [...]
49     [enum_class_ResizablePMCArray]
50        *_namespace -> [parrot]
51        base_type -> enum_class_ResizablePMCArray
52        *whoami -> String holding "ResizablePMCArray"
53        flags
54        *provides_str "scalar"
55        *isa_hash -> hash containing item "Exception"
56        *pmc_class = pmc
57          flags
58          vtable -> null or points to pmc of type pmcproxy describing the pmcproxy pmc class
59          *data
60            id -> = vtable->base_type
61            *name -> = vtable->whoami
62            *fullname
63            *_namespace -> = vtable->_namespace (at least should be)
64            instantiated -> 1 class is instantiated
65            *parents
66            *all_parents -> = vtable->mro
67            *roles -> provides same information as vtable->provides_str
68            *methods
69            *vtable_overrides
70            *attrib_metadata -> build from vtable->attribute_defs
71            *attrib_index
72            *attrib_cache 
73            *resolve_method
74            *parent_overrides
75          *metadata
76          *_synchronize
77          *_next_for_GC
78        *mro -> pmc array holding parents
79        *attribute_defs -> "Iid Fbirthtime Smessage Fpayload etc "
80        *ro_variant_vtable -> vtable where only flags and functions are different rest is redundant
81        the list of functions
82     [...]
83     [394]
84        *_namespace -> [parrot;mypackage;myclass]
85        base_type -> 394
86        *whoami -> String holding "myclass"
87        flags
88        *provides_str "scalar" (cloned from interp->vtables[enum_class_ResizablePMCArray])
89        *isa_hash -> hash containing item "Exception" (cloned from interp->vtables[enum_class_ResizablePMCArray])
90        *pmc_class = pmc
91          flags
92          vtable -> null or points to pmc of type pmcproxy describing the pmcproxy pmc class
93          *data
94            id -> = vtable->base_type
95            *name -> = vtable->whoami
96            *fullname
97            *_namespace -> = vtable->_namespace (at least should be)
98            instantiated -> 1 class is instantiated
99            *parents
100            *all_parents -> = vtable->mro
101            *roles -> provides same information as vtable->provides_str + extra added roles
102            *methods
103            *vtable_overrides
104            *attrib_metadata -> build from vtable->attribute_defs + extra added attributes
105            *attrib_index
106            *attrib_cache 
107            *resolve_method
108            *parent_overrides
109          *metadata
110          *_synchronize
111          *_next_for_GC
112        *mro -> = this->pmc_class->all_parents
113        *attribute_defs -> "Iid Fbirthtime Smessage Fpayload etc " (cloned from interp->vtables[enum_class_ResizablePMCArray])
114        *ro_variant_vtable -> vtable where only flags and functions are different rest is redundant a clone(from interp->vtables[enum_class_ResizablePMCArray])
115        the list of functions -> cloned from interp->vtables[enum_class_ResizablePMCArray]   
116   ...
117   
118My plan is to do the following things
119* Make all pmc an object
120  *Move all functionality from object.pmc to default.pmc
121    - Remove object.pmc
122    - Rename default.pmc to object.pmc
123  *Move the _attrib_store to the pmc struct
124    *Doing this by combining it into the *data field
125      -change the indexing mechanism of class.pmc
126      -DISCUSS! whether where are going to store (U)INTVAL and FLOATVAL as
127        primitive or as boxed items (see below)
128  *Remove all fields form vtable except the functions
129    *This will remove redundant fields in the system
130    *Add vtable and ro_vtable field to class.pmc
131    *replace interp->vtables by interp->classes
132      -bootstrap, loading/initing of the core pmc class object
133      -registering of new classes     
134    *replace pmc->vtable by pmc->_class
135  *Remove the pmcproxy.pmc class
136 
137This will result in the following things.
138*all pmc items becoming object, without any extra memory usage, except for extra attributes in class.pmc
139  -so their attributes can be accessed via pir.
140  -We migth want to make an option to declare certain fields in a pmc as private.
141* subclassing from pir works as expected
142* typeof and related ops works as expected see tickets #879 #880 +more
143* will solve several different tickets
144* memory usage reduction (big one :) )
145* performance boost
146
147* the pmc structure will become
148  struct PMC {
149    Parrot_UInt     flags;
150    PMC            *_class;
151    DPOINTER       *data; /* with different structure see xx*/
152    PMC            *_class;
153    PMC *_metadata;      /* properties */
154    struct _Sync *_synchronize;
155    PMC *_next_for_GC; /* other are busy removing this one */
156  }
157* interp->vtables replaced by interp->classes
158* 2 added fields to class.pmc holding vtable and read only vtable
159* added field to class.pmc to handle new indexing mechanism
160* vtable struct will only contain the pointers to the functions
161
162The data structure will become an array of aligned items. For example I would
163have the following items which is created in pir code by extending
164the pmc class somepmcclass.
165* INTVAL myint
166* FLOAT myfloat
167* DOUBLE mydouble
168* PMC * aPMC
169* PMC added by pir class this also is PMC* "addedpmc"
170* DOUBLE added by pir class "addeddouble"
171* FLOAT added by pir class "addedfloat"
172If a would compile on a 32 bits i368 machine then
173alignSize = 4 byte
174INTVALSize = 4 byte
175FLAOTSize = 4 byte
176DOUBLESize = 8 byte
177pointSize = 4 byte
178So my index will be come
179myInt = 0
180myfloat = 1
181mydouble = 2
182aPMC = 4 /* double uses to aligmentSizes */
183addedpmc = 5
184addeddouble = 6
185addedfloat = 8
186
187The struct of this class for the code in pmc class will look in this
188typedef struct Parrot_somepmcclass_attributes {
189    INTVAL myint;
190    FLOAT myfloat;
191    DOUBLE mydouble;
192    PMC * aPMC;
193} Parrot_somepmcclass_attributes;
194
195The class.pmc will also get a extra field which tells on which indexes there are
196pmc objects present, which is needed for the mark function.
197In the example described above this will become.
198int * = [4,5]
199
200Because my plan is to store all primitive as primitives as done now in pmc classes
201I might get the following problem.
202When I have a hll which does not use parrot boxed type but it own type, it will
203get a parrot boxed type if does return from getattribe op.
204But the same problem also happens with the box op. I do not know the details of this
205but a hll could override these ops to solve this problem.
206Ok we then have solved that problem.
207The big question which leave my are there any hll which stores extra information onto
208a integer,float or double which have to be preserved when doing set attribute and
209after that doing a get attribute.
210
211Because this is a big change I made a plan for myself to implement this in phases.
212Here is the list of phases I planned for this change.
213* move object attribute store to pmc struct by adding extra field _pmc_array (done)
214  -storage does not have to be re-sizable because ones class is instantiated it can't add
215   or remove any properties to the class
216* add interp->classes field and allocation stuff (done)
217* add vtable and ro_vtable field in class.pmc (done)
218* add bootstrap code to load interp->classes data (understanding of pmc2c.pl done, now to change it)
219* add class registering code for interp->classes data
220* replace interp->vtable[] code by interp->classes[]->vtable
221* replace pmc->vtable by pmc->class
222* make new indexing system
223* merge newly created _pmc_array with data and remove _pmc_array again
224* move functionality of object.pmc to default.pmc
225* hope merging of vtable functions goes correctly that none of the important object acces vtable
226  function overlap with other vtable functions in other pmc objects
227* removal of pmcproxy class
228* removal of object.pmc
229* rename default.pmc -> object.pmc
230* remove any left references to the fields in vtable struct except the functions doh
231* remove these fields
232* cleanup of code, broken test etc, coding std
233
234Of course unexpected things can let me reshuffle this list.
235
236After the change the same memory layout as above will look like
237 pmc
238    flags
239    *_class -> = interp->classes[394] (example)
240    *data
241      [0] id = INTVAL
242      [1] birthtime = FLOATVAL
243      etc
244      [12] thrower = pmc*
245    *metadata
246    *_synchronize
247    *_next_for_GC
248   
249*Note that in this case there is no DOUBLEVAl present other wise that one would take up 2 indexes
250   
251interp
252   ...
253   **classes
254     [...]
255     [394]
256       flags
257       _class = pmc object
258          flags
259          _class -> = interp->classes[enum_class_Class] points to the class describing the class.pmc
260          *data
261            id -> = 394
262            *name -> = "myclass"
263            *fullname
264            *_namespace -> = [parrot;mypackage;myclass]
265            instantiated -> 1 class is instantiated
266            *parents
267            *all_parents
268            *roles
269            *methods
270            *vtable_overrides
271            *attrib_metadata
272            *attrib_index -> index using new indexing mechanism
273            *attrib_cache 
274            *resolve_method
275            *parent_overrides
276            *vtable -> vtable holding only function pointers (initialily cloned from pmc base obect)
277            *ro_vtable -> vtable holding only function pointers (initialily cloned from pmc base obect)
278            *is_pmc_index -> telling which attributes in the pmc->data are pmc (pobj*) objects
279          *metadata
280          *_synchronize
281          *_next_for_GC
282   
283Because it is a big change, it would be fine to have separate branch for this.
284If you guys accept my plan :).