Ticket #895: auto_attrs.patch

File auto_attrs.patch, 59.7 KB (added by NotFound, 5 years ago)

diff between trunk and auto_attrs branch at r40501

Line 
1Index: src/gc/api.c
2===================================================================
3--- src/gc/api.c        (.../trunk)     (revision 40501)
4+++ src/gc/api.c        (.../branches/auto_attrs)       (revision 40501)
5@@ -373,6 +373,16 @@
6     if (PObj_active_destroy_TEST(pmc))
7         VTABLE_destroy(interp, pmc);
8 
9+    if (PMC_data(pmc) && pmc->vtable->attr_size) {
10+#if 0
11+        mem_sys_free(PMC_data(pmc));
12+        PMC_data(pmc) = NULL;
13+#else
14+        Parrot_gc_free_pmc_attributes(interp, pmc, pmc->vtable->attr_size);
15+#endif
16+    }
17+    PARROT_ASSERT(NULL == PMC_data(pmc));
18+
19     if (PObj_is_PMC_EXT_TEST(pmc))
20         Parrot_gc_free_pmc_ext(interp, pmc);
21Index: src/pmc.c
22===================================================================
23--- src/pmc.c   (.../trunk)     (revision 40501)
24+++ src/pmc.c   (.../branches/auto_attrs)       (revision 40501)
25@@ -241,6 +241,24 @@
26     /* Set the right vtable */
27     pmc->vtable = new_vtable;
28 
29+    if (PMC_data(pmc) && pmc->vtable->attr_size) {
30+#if 0
31+        mem_sys_free(PMC_data(pmc));
32+#else
33+        Parrot_gc_free_pmc_attributes(interp, pmc, pmc->vtable->attr_size);
34+#endif
35+    }
36+
37+    if (new_vtable->attr_size) {
38+#if 0
39+        PMC_data(pmc) = mem_sys_allocate_zeroed(new_vtable->attr_size);
40+#else
41+        Parrot_gc_allocate_pmc_attributes(interp, pmc, pmc->vtable->attr_size);
42+#endif
43+}
44+    else
45+        PMC_data(pmc) = NULL;
46+
47     return pmc;
48 }
49 
50@@ -361,6 +379,14 @@
51     /* Do we have an extension area? */
52     INTVAL const has_ext = (PObj_is_PMC_EXT_TEST(pmc) && pmc->pmc_ext);
53 
54+    if (PMC_data(pmc) && pmc->vtable->attr_size) {
55+#if 0
56+        mem_sys_free(PMC_data(pmc));
57+#else
58+        Parrot_gc_free_pmc_attributes(interp, pmc, pmc->vtable->attr_size);
59+#endif
60+    }
61+
62     /* Do we need one? */
63     if (flags & VTABLE_PMC_NEEDS_EXT) {
64         /* If we need an ext area, go allocate one */
65@@ -465,6 +491,14 @@
66     pmc            = Parrot_gc_new_pmc_header(interp, flags);
67     pmc->vtable    = vtable;
68 
69+    if (vtable->attr_size) {
70+#if 0
71+        PMC_data(pmc) = mem_sys_allocate_zeroed(vtable->attr_size);
72+#else
73+        Parrot_gc_allocate_pmc_attributes(interp, pmc, pmc->vtable->attr_size);
74+#endif
75+    }
76+
77 #if GC_VERBOSE
78     if (Interp_flags_TEST(interp, PARROT_TRACE_FLAG)) {
79         /* XXX make a more verbose trace flag */
80Index: src/pmc/role.pmc
81===================================================================
82--- src/pmc/role.pmc    (.../trunk)     (revision 40501)
83+++ src/pmc/role.pmc    (.../branches/auto_attrs)       (revision 40501)
84@@ -198,7 +198,7 @@
85 
86 */
87 
88-pmclass Role need_ext {
89+pmclass Role need_ext auto_attrs {
90     ATTR STRING *name;            /* The name of the role. */
91     ATTR PMC    *_namespace;      /* The namespace it's linked to, if any. */
92     ATTR PMC    *roles;           /* Roles from which this role is composed. */
93@@ -221,12 +221,11 @@
94 */
95 
96     VTABLE void init() {
97-        Parrot_Role_attributes * const role = mem_allocate_zeroed_typed(Parrot_Role_attributes);
98-        PMC_data(SELF)        = role;
99+        Parrot_Role_attributes * const role =
100+                (Parrot_Role_attributes *) PMC_data(SELF);
101 
102-        /* Set flags for custom GC mark and destroy. */
103+        /* Set flags for custom GC mark. */
104         PObj_custom_mark_SET(SELF);
105-        PObj_active_destroy_SET(SELF);
106 
107         /* Set up the object. */
108         role->name            = CONST_STRING(interp, "");
109@@ -246,21 +245,6 @@
110 
111 /*
112 
113-=item C<void destroy()>
114-
115-Free the memory associated with the object's underlying struct.
116-
117-=cut
118-
119-*/
120-
121-    VTABLE void destroy() {
122-        mem_sys_free(PMC_data(SELF));
123-        PMC_data(SELF) = NULL;
124-    }
125-
126-/*
127-
128 =item C<void mark()>
129 
130 Mark referenced strings and PMCs in the structure as live.
131Index: src/pmc/class.pmc
132===================================================================
133--- src/pmc/class.pmc   (.../trunk)     (revision 40501)
134+++ src/pmc/class.pmc   (.../branches/auto_attrs)       (revision 40501)
135@@ -443,7 +443,7 @@
136 */
137 
138 pmclass Class
139-    need_ext {
140+    need_ext auto_attrs {
141 
142     ATTR INTVAL id;             /* The type number of the PMC. [deprecated: See RT #48024] */
143     ATTR STRING *name;          /* The name of the class. */
144@@ -479,14 +479,13 @@
145 */
146 
147     VTABLE void init() {
148-        Parrot_Class_attributes * const _class = mem_allocate_zeroed_typed(Parrot_Class_attributes);
149+        Parrot_Class_attributes * const _class =
150+                (Parrot_Class_attributes *) PMC_data(SELF);
151 
152-        /* Set flags for custom GC mark and destroy. */
153+        /* Set flag for custom GC mark. */
154         PObj_custom_mark_SET(SELF);
155-        PObj_active_destroy_SET(SELF);
156 
157         /* Set up the object. */
158-        PMC_data(SELF)          = _class;
159         _class->name            = CONST_STRING(interp, "");
160         _class->_namespace      = PMCNULL;
161         _class->parents         = pmc_new(interp, enum_class_ResizablePMCArray);
162@@ -559,21 +558,6 @@
163 
164 /*
165 
166-=item C<void destroy()>
167-
168-Frees the memory associated with the class's underlying struct.
169-
170-=cut
171-
172-*/
173-
174-    VTABLE void destroy() {
175-        mem_sys_free(PMC_data(SELF));
176-        PMC_data(SELF) = NULL;
177-    }
178-
179-/*
180-
181 =item C<STRING *get_string()>
182 
183 Returns the name of the class (without the HLL namespace).
184Index: src/pmc/string.pmc
185===================================================================
186--- src/pmc/string.pmc  (.../trunk)     (revision 40501)
187+++ src/pmc/string.pmc  (.../branches/auto_attrs)       (revision 40501)
188@@ -20,7 +20,7 @@
189 
190 */
191 
192-pmclass String extends scalar provides string provides scalar {
193+pmclass String extends scalar provides string provides scalar auto_attrs {
194     ATTR STRING * str_val;
195 
196 /*
197@@ -34,33 +34,14 @@
198 */
199 
200     VTABLE void init() {
201-        Parrot_String_attributes *attrs =
202-            mem_allocate_typed(Parrot_String_attributes);
203         STRING *str_val = Parrot_str_new_noinit(INTERP, enum_stringrep_one, 0);
204-        PMC_data(SELF) = attrs;
205         SET_ATTR_str_val(INTERP, SELF, str_val);
206 
207-        PObj_custom_mark_destroy_SETALL(SELF);
208+        PObj_custom_mark_SET(SELF);
209     }
210 
211 /*
212 
213-=item C<void destroy()>
214-
215-Destroys this String PMC.
216-
217-=cut
218-
219-*/
220-
221-    VTABLE void destroy() {
222-        mem_sys_free(PMC_data(SELF));
223-        PMC_data(SELF) = NULL;
224-    }
225-
226-
227-/*
228-
229 =item C<PMC instantiate_str(STRING *rep)>
230 
231 Class method to construct a String from the string representation C<rep>.
232@@ -111,7 +92,6 @@
233 
234     VTABLE PMC *clone() {
235         PMC * const dest = pmc_new(INTERP, SELF->vtable->base_type);
236-        PObj_custom_mark_destroy_SETALL(dest);
237         VTABLE_set_string_native(INTERP, dest, Parrot_str_copy(INTERP, SELF.get_string()));
238         return dest;
239     }
240Index: src/pmc/complex.pmc
241===================================================================
242--- src/pmc/complex.pmc (.../trunk)     (revision 40501)
243+++ src/pmc/complex.pmc (.../branches/auto_attrs)       (revision 40501)
244@@ -217,7 +217,7 @@
245 }
246 
247 
248-pmclass Complex need_ext {
249+pmclass Complex need_ext auto_attrs {
250 
251     ATTR FLOATVAL re; /* real part */
252     ATTR FLOATVAL im; /* imaginary part */
253@@ -327,10 +327,6 @@
254 Initializes the complex number with the specified initializer.
255 The initializer can be a string PMC or a numeric array with (real, imag)
256 
257-=item C<void destroy()>
258-
259-Cleans up.
260-
261 =item C<PMC *clone()>
262 
263 Creates an identical copy of the complex number.
264@@ -340,12 +336,8 @@
265 */
266 
267     VTABLE void init() {
268-        /* XXX should check if mem_sys_allocate failed */
269-        PMC_data(SELF) = mem_allocate_typed(Parrot_Complex_attributes);
270         SET_ATTR_re(INTERP, SELF, 0.0);
271         SET_ATTR_im(INTERP, SELF, 0.0);
272-
273-        PObj_active_destroy_SET(SELF);
274     }
275 
276     VTABLE void init_pmc(PMC *initializer) {
277@@ -380,11 +372,6 @@
278         }
279     }
280 
281-    VTABLE void destroy() {
282-        mem_sys_free(PMC_data(SELF));
283-        PMC_data(SELF) = NULL;
284-    }
285-
286     VTABLE PMC *clone() {
287         PMC * const dest = pmc_new(INTERP, VTABLE_type(INTERP, SELF));
288         FLOATVAL re, im;
289Index: src/pmc/exporter.pmc
290===================================================================
291--- src/pmc/exporter.pmc        (.../trunk)     (revision 40501)
292+++ src/pmc/exporter.pmc        (.../branches/auto_attrs)       (revision 40501)
293@@ -90,7 +90,7 @@
294 
295 */
296 
297-pmclass Exporter need_ext {
298+pmclass Exporter need_ext auto_attrs {
299 
300     ATTR PMC *ns_src;
301     ATTR PMC *ns_dest;
302@@ -107,10 +107,6 @@
303 */
304 
305     VTABLE void init() {
306-        Parrot_Exporter_attributes * const exp =
307-            mem_allocate_zeroed_typed(Parrot_Exporter_attributes);
308-        PMC_data(SELF)       = exp;
309-
310         /* Set up the object. */
311         SET_ATTR_ns_src(INTERP, SELF, PMCNULL);
312         SET_ATTR_ns_dest(INTERP, SELF, CONTEXT(interp)->current_namespace);
313@@ -118,28 +114,10 @@
314 
315         /* Set flags for custom GC mark and destroy. */
316         PObj_custom_mark_SET(SELF);
317-        PObj_active_destroy_SET(SELF);
318     }
319 
320-
321 /*
322 
323-=item C<void destroy()>
324-
325-Free the memory associated with the object's underlying struct.
326-
327-=cut
328-
329-*/
330-
331-    VTABLE void destroy() {
332-        mem_sys_free(PMC_data(SELF));
333-        PMC_data(SELF) = NULL;
334-    }
335-
336-
337-/*
338-
339 =item C<void mark()>
340 
341 Mark referenced strings and PMCs in the structure as live.
342Index: src/pmc/resizablepmcarray.pmc
343===================================================================
344--- src/pmc/resizablepmcarray.pmc       (.../trunk)     (revision 40501)
345+++ src/pmc/resizablepmcarray.pmc       (.../branches/auto_attrs)       (revision 40501)
346@@ -23,7 +23,7 @@
347 #define PMC_array(x)     ((Parrot_ResizablePMCArray_attributes *)PMC_data(x))->pmc_array
348 #define PMC_threshold(x) ((Parrot_ResizablePMCArray_attributes *)PMC_data(x))->resize_threshold
349 
350-pmclass ResizablePMCArray extends FixedPMCArray need_ext provides array {
351+pmclass ResizablePMCArray extends FixedPMCArray need_ext auto_attrs provides array {
352     ATTR INTVAL resize_threshold; /* max size before array needs resizing */
353 
354 
355@@ -37,10 +37,6 @@
356 */
357 
358     VTABLE void init() {
359-        Parrot_ResizablePMCArray_attributes *attrs =
360-            mem_allocate_zeroed_typed(Parrot_ResizablePMCArray_attributes);
361-
362-        PMC_data(SELF) = attrs;
363         PObj_custom_mark_destroy_SETALL(SELF);
364     }
365 
366Index: src/pmc/pointer.pmc
367===================================================================
368--- src/pmc/pointer.pmc (.../trunk)     (revision 40501)
369+++ src/pmc/pointer.pmc (.../branches/auto_attrs)       (revision 40501)
370@@ -20,7 +20,7 @@
371 
372 */
373 
374-pmclass Pointer need_ext {
375+pmclass Pointer need_ext auto_attrs {
376     ATTR void * mark_function;
377     ATTR void * pointer;
378 
379@@ -35,28 +35,11 @@
380 */
381 
382     VTABLE void init() {
383-        PObj_custom_mark_destroy_SETALL(SELF);
384-        PMC_data(SELF) = mem_allocate_zeroed_typed(Parrot_Pointer_attributes);
385+        PObj_custom_mark_SET(SELF);
386     }
387 
388 /*
389 
390-=item C<void destroy()>
391-
392-Destroy the Pointer and free associated memory
393-
394-=cut
395-
396-*/
397-
398-    VTABLE void destroy() {
399-        mem_sys_free(PARROT_POINTER(SELF));
400-        PMC_data(SELF) = NULL;
401-    }
402-
403-
404-/*
405-
406 =item C<void mark()>
407 
408 Marks the pointer as live.
409Index: src/pmc/cpointer.pmc
410===================================================================
411--- src/pmc/cpointer.pmc        (.../trunk)     (revision 40501)
412+++ src/pmc/cpointer.pmc        (.../branches/auto_attrs)       (revision 40501)
413@@ -46,7 +46,7 @@
414 
415 */
416 
417-pmclass CPointer need_ext {
418+pmclass CPointer need_ext auto_attrs {
419     ATTR void   *pointer; /* The stored pointer. */
420     ATTR STRING *sig;     /* A string signature for the pointer. */
421 
422@@ -61,13 +61,9 @@
423 */
424 
425     VTABLE void init() {
426-        Parrot_CPointer_attributes * const pdata_struct =
427-            mem_allocate_typed(Parrot_CPointer_attributes);
428+        SET_ATTR_pointer(INTERP, SELF, NULL);
429+        SET_ATTR_sig(INTERP, SELF, NULL);
430 
431-        PMC_data(SELF)        = pdata_struct;
432-        pdata_struct->pointer = NULL;
433-        pdata_struct->sig     = NULL;
434-
435         PObj_custom_mark_destroy_SETALL(SELF);
436     }
437 
438@@ -83,19 +79,21 @@
439 */
440 
441     VTABLE void mark() {
442-        Parrot_CPointer_attributes * const data = PARROT_CPOINTER(SELF);
443+        STRING *sig;
444+        GET_ATTR_sig(INTERP, SELF, sig);
445+        if (sig) {
446+            void *pointer;
447+            GET_ATTR_pointer(INTERP, SELF, pointer);
448+            Parrot_gc_mark_PObj_alive(interp, (PObj *)sig);
449 
450-        if (data->sig) {
451-            Parrot_gc_mark_PObj_alive(interp, (PObj *)data->sig);
452-
453-            if (data->pointer) {
454-                if (Parrot_str_equal(interp, data->sig, CONST_STRING(interp, "P"))) {
455-                    PMC ** const pmc_pointer = (PMC **) data->pointer;
456+            if (pointer) {
457+                if (Parrot_str_equal(interp, sig, CONST_STRING(interp, "P"))) {
458+                    PMC ** const pmc_pointer = (PMC **) pointer;
459                     PARROT_ASSERT(*pmc_pointer);
460                     Parrot_gc_mark_PObj_alive(interp, (PObj *) *pmc_pointer);
461                 }
462-                else if (Parrot_str_equal(interp, data->sig, CONST_STRING(interp, "S"))) {
463-                    STRING ** const str_pointer = (STRING **) data->pointer;
464+                else if (Parrot_str_equal(interp, sig, CONST_STRING(interp, "S"))) {
465+                    STRING ** const str_pointer = (STRING **) pointer;
466                     PARROT_ASSERT(*str_pointer);
467                     Parrot_gc_mark_PObj_alive(interp, (PObj *) *str_pointer);
468                 }
469@@ -114,12 +112,6 @@
470 */
471 
472     VTABLE void destroy() {
473-        Parrot_CPointer_attributes * const data = PARROT_CPOINTER(SELF);
474-
475-        if (data) {
476-            mem_sys_free(data);
477-            PMC_data(SELF) = NULL;
478-        }
479     }
480 
481 /*
482Index: src/pmc/fixedfloatarray.pmc
483===================================================================
484--- src/pmc/fixedfloatarray.pmc (.../trunk)     (revision 40501)
485+++ src/pmc/fixedfloatarray.pmc (.../branches/auto_attrs)       (revision 40501)
486@@ -19,7 +19,7 @@
487 
488 */
489 
490-pmclass FixedFloatArray need_ext provides array {
491+pmclass FixedFloatArray need_ext auto_attrs provides array {
492     ATTR INTVAL    size;
493     ATTR FLOATVAL *float_array;
494 
495@@ -40,9 +40,6 @@
496 */
497 
498     VTABLE void init() {
499-        Parrot_FixedFloatArray_attributes* attrs =
500-            mem_allocate_zeroed_typed(Parrot_FixedFloatArray_attributes);
501-        PMC_data(SELF) = attrs;
502     }
503 
504 /*
505@@ -60,9 +57,6 @@
506         GET_ATTR_float_array(INTERP, SELF, float_array);
507         if (float_array)
508             mem_sys_free(float_array);
509-
510-        mem_sys_free(PMC_data(SELF));
511-        PMC_data(SELF) = NULL;
512     }
513 
514 /*
515Index: src/pmc/retcontinuation.pmc
516===================================================================
517--- src/pmc/retcontinuation.pmc (.../trunk)     (revision 40501)
518+++ src/pmc/retcontinuation.pmc (.../branches/auto_attrs)       (revision 40501)
519@@ -23,7 +23,7 @@
520 
521 #include "parrot/oplib/ops.h"
522 
523-pmclass RetContinuation extends Continuation need_ext {
524+pmclass RetContinuation extends Continuation need_ext auto_attrs {
525 
526 /*
527 
528@@ -37,9 +37,7 @@
529 
530     VTABLE void init() {
531         Parrot_RetContinuation_attributes * const attrs =
532-            mem_allocate_typed(Parrot_RetContinuation_attributes);
533-
534-        PMC_data(SELF) = attrs;
535+            (Parrot_RetContinuation_attributes *) PMC_data(SELF);
536         PMC_cont(SELF) = new_ret_continuation(INTERP);
537 
538         PObj_custom_mark_destroy_SETALL(SELF);
539@@ -55,9 +53,6 @@
540 
541         if (cc)
542             mem_sys_free(cc);
543-
544-        mem_sys_free(PMC_data(SELF));
545-        PMC_data(SELF) = NULL;
546     }
547 /*
548 
549Index: src/pmc/parrotinterpreter.pmc
550===================================================================
551--- src/pmc/parrotinterpreter.pmc       (.../trunk)     (revision 40501)
552+++ src/pmc/parrotinterpreter.pmc       (.../branches/auto_attrs)       (revision 40501)
553@@ -240,8 +240,9 @@
554             Parrot_ParrotInterpreter_attributes *attrs =
555                 mem_allocate_zeroed_typed(Parrot_ParrotInterpreter_attributes);
556             PMC_data(SELF) = attrs;
557+        }
558+        if (!PMC_interp(SELF)) {
559             create_interp(SELF, INTERP);
560-            PARROT_ASSERT(attrs->interp);
561         }
562         PObj_active_destroy_SET(SELF);
563     }
564@@ -261,8 +262,15 @@
565     VTABLE void init_pmc(PMC *parent) {
566         Parrot_Interp p = PMC_interp(parent);
567 
568-        if (!PMC_interp(SELF))
569+        if (!PMC_data(SELF)) {
570+            Parrot_ParrotInterpreter_attributes *attrs =
571+                mem_allocate_zeroed_typed(Parrot_ParrotInterpreter_attributes);
572+            PMC_data(SELF) = attrs;
573+        }
574+        if (!PMC_interp(SELF)) {
575             create_interp(SELF, p);
576+        }
577+        PObj_active_destroy_SET(SELF);
578     }
579 
580 
581Index: src/pmc/filehandle.pmc
582===================================================================
583--- src/pmc/filehandle.pmc      (.../trunk)     (revision 40501)
584+++ src/pmc/filehandle.pmc      (.../branches/auto_attrs)       (revision 40501)
585@@ -31,7 +31,7 @@
586 #endif
587 #endif
588 
589-pmclass FileHandle extends Handle {
590+pmclass FileHandle extends Handle auto_attrs {
591     ATTR INTVAL flags;                /* Filehandle flags             */
592     ATTR STRING *filename;            /* The opened path and filename */
593     ATTR STRING *mode;                /* The mode string used in open */
594@@ -64,9 +64,8 @@
595 
596     VTABLE void init() {
597         Parrot_FileHandle_attributes * const data_struct =
598-                mem_allocate_typed(Parrot_FileHandle_attributes);
599+                (Parrot_FileHandle_attributes *) PMC_data(SELF);
600 
601-        PMC_data(SELF)             = data_struct;
602         data_struct->flags         = 0;
603         data_struct->filename      = NULL;
604         data_struct->mode          = NULL;
605@@ -150,9 +149,6 @@
606 
607             if (data_struct->buffer_start)
608                 mem_sys_free(data_struct->buffer_start);
609-
610-            mem_sys_free(PARROT_FILEHANDLE(SELF));
611-            PMC_data(SELF) = NULL;
612         }
613     }
614 
615Index: src/pmc/resizableintegerarray.pmc
616===================================================================
617--- src/pmc/resizableintegerarray.pmc   (.../trunk)     (revision 40501)
618+++ src/pmc/resizableintegerarray.pmc   (.../branches/auto_attrs)       (revision 40501)
619@@ -20,7 +20,7 @@
620 
621 */
622 
623-pmclass ResizableIntegerArray extends FixedIntegerArray need_ext provides array {
624+pmclass ResizableIntegerArray extends FixedIntegerArray need_ext auto_attrs provides array {
625     ATTR INTVAL resize_threshold; /* max size before array needs to be resized */
626 
627 /*
628@@ -33,10 +33,7 @@
629 
630 */
631     VTABLE void init() {
632-        Parrot_ResizableIntegerArray_attributes* attrs =
633-            mem_allocate_zeroed_typed(Parrot_ResizableIntegerArray_attributes);
634-        PMC_data(SELF) = attrs;
635-        PObj_active_destroy_SET(SELF);
636+        SUPER();
637     }
638 
639 /*
640Index: src/pmc/exception.pmc
641===================================================================
642--- src/pmc/exception.pmc       (.../trunk)     (revision 40501)
643+++ src/pmc/exception.pmc       (.../branches/auto_attrs)       (revision 40501)
644@@ -52,7 +52,7 @@
645 #include "parrot/exceptions.h"
646 #include "pmc_sub.h"
647 
648-pmclass Exception {
649+pmclass Exception auto_attrs {
650 
651     ATTR INTVAL          id;           /* The task ID in the scheduler. */
652     ATTR FLOATVAL        birthtime;    /* The creation time stamp of the exception. */
653@@ -83,15 +83,8 @@
654 */
655 
656     VTABLE void init() {
657-        Parrot_Exception_attributes * const core_struct =
658-            mem_allocate_zeroed_typed(Parrot_Exception_attributes);
659-
660-        /* Set up the core struct and default values for the exception object. */
661-        PMC_data(SELF)            = core_struct;
662-
663-        /* Set flags for custom GC mark and destroy. */
664+        /* Set flags for custom GC mark. */
665         PObj_custom_mark_SET(SELF);
666-        PObj_active_destroy_SET(SELF);
667 
668         SET_ATTR_severity(INTERP, SELF, EXCEPT_error);
669         SET_ATTR_handled(INTERP, SELF, 0);
670@@ -116,9 +109,6 @@
671         INTVAL severity_val;
672         STRING *message_val;
673 
674-        Parrot_Exception_attributes * const core_struct =
675-            mem_allocate_zeroed_typed(Parrot_Exception_attributes);
676-
677         INTVAL ishash = VTABLE_isa(interp, values, CONST_STRING(interp, 'Hash'));
678 
679         if (ishash) {
680@@ -132,10 +122,8 @@
681             message_val  = VTABLE_get_string(interp, values);
682         }
683 
684-        PMC_data(SELF)            = core_struct;
685-        /* Set flags for custom GC mark and destroy. */
686+        /* Set flags for custom GC mark. */
687         PObj_custom_mark_SET(SELF);
688-        PObj_active_destroy_SET(SELF);
689 
690         /* Set up the core struct and default values for the exception object. */
691 
692@@ -175,25 +163,6 @@
693 
694 /*
695 
696-=item C<void destroy()>
697-
698-Destroys the exception.
699-
700-=cut
701-
702-*/
703-
704-    VTABLE void destroy() {
705-        Parrot_Exception_attributes * const core_struct = PARROT_EXCEPTION(SELF);
706-        if (core_struct) {
707-            if (core_struct->thrower)
708-                Parrot_free_context(interp, core_struct->thrower, 1);
709-            mem_sys_free(core_struct);
710-        }
711-    }
712-
713-/*
714-
715 =item C<INTVAL get_bool()>
716 
717 Return true.
718Index: src/pmc/orderedhashiterator.pmc
719===================================================================
720--- src/pmc/orderedhashiterator.pmc     (.../trunk)     (revision 40501)
721+++ src/pmc/orderedhashiterator.pmc     (.../branches/auto_attrs)       (revision 40501)
722@@ -21,7 +21,7 @@
723 #include "pmc_hash.h"
724 #include "pmc_hashiteratorkey.h"
725 
726-pmclass OrderedHashIterator extends Iterator no_ro {
727+pmclass OrderedHashIterator extends Iterator no_ro auto_attrs {
728     ATTR PMC        *pmc_hash;      /* the Hash which this Iterator iterates */
729     ATTR Hash       *parrot_hash;   /* Underlying implementation of hash */
730     ATTR INTVAL      pos;           /* */
731@@ -41,7 +41,7 @@
732 
733     VTABLE void init_pmc(PMC *hash) {
734         Parrot_OrderedHashIterator_attributes * const attrs =
735-            mem_allocate_zeroed_typed(Parrot_OrderedHashIterator_attributes);
736+           (Parrot_OrderedHashIterator_attributes *) PMC_data(SELF);
737 
738         attrs->pmc_hash         = hash;
739         attrs->parrot_hash      = (Hash*)VTABLE_get_pointer(INTERP, hash);
740@@ -49,28 +49,12 @@
741         /* Will be decreased on initial advance_to_next */
742         /* XXX Do we really need to support this use-case ? */
743         attrs->elements         = attrs->parrot_hash->entries;
744-        PMC_data(SELF)          = attrs;
745 
746-        PObj_custom_mark_destroy_SETALL(SELF);
747+        PObj_custom_mark_SET(SELF);
748     }
749 
750 /*
751 
752-=item C<void destroy()>
753-
754-destroys this PMC
755-
756-=cut
757-
758-*/
759-
760-    VTABLE void destroy() {
761-        mem_sys_free(PMC_data(SELF));
762-        PMC_data(SELF) = NULL;
763-    }
764-
765-/*
766-
767 =item C<void mark()>
768 
769 Marks the hash as live.
770Index: src/pmc/task.pmc
771===================================================================
772--- src/pmc/task.pmc    (.../trunk)     (revision 40501)
773+++ src/pmc/task.pmc    (.../branches/auto_attrs)       (revision 40501)
774@@ -20,7 +20,7 @@
775 
776 #include "parrot/scheduler_private.h"
777 
778-pmclass Task need_ext {
779+pmclass Task need_ext auto_attrs {
780     ATTR INTVAL        id;        /* The task ID. */
781     ATTR INTVAL        priority;  /* The priority of the task. */
782     ATTR FLOATVAL      birthtime; /* The creation time stamp of the task. */
783@@ -44,14 +44,12 @@
784 
785     VTABLE void init() {
786         Parrot_Task_attributes * const core_struct =
787-            mem_allocate_zeroed_typed(Parrot_Task_attributes);
788+            (Parrot_Task_attributes *) PMC_data(SELF);
789 
790-        /* Set flags for custom GC mark and destroy. */
791+        /* Set flags for custom GC mark. */
792         PObj_custom_mark_SET(SELF);
793-        PObj_active_destroy_SET(SELF);
794 
795         /* Set up the core struct. */
796-        PMC_data(SELF)           = core_struct;
797         core_struct->id          = 0;
798         core_struct->type        = CONST_STRING(interp, "");
799         core_struct->subtype     = CONST_STRING(interp, "");
800@@ -123,14 +121,12 @@
801             Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
802                 "Task initializer must be a Hash");
803 
804-        core_struct = mem_allocate_zeroed_typed(Parrot_Task_attributes);
805+        core_struct = (Parrot_Task_attributes *) PMC_data(SELF);
806 
807-        /* Set flags for custom GC mark and destroy. */
808+        /* Set flags for custom GC mark. */
809         PObj_custom_mark_SET(SELF);
810-        PObj_active_destroy_SET(SELF);
811 
812         /* Set up the core struct. */
813-        PMC_data(SELF)           = core_struct;
814 
815         elem = VTABLE_get_pmc_keyed_str(INTERP, data, CONST_STRING(INTERP, "id"));
816         if (! PMC_IS_NULL(elem))
817@@ -369,20 +365,6 @@
818 
819 /*
820 
821-=item C<void destroy()>
822-
823-Free the task's underlying struct.
824-
825-=cut
826-
827-*/
828-    VTABLE void destroy() {
829-        mem_sys_free(PMC_data(SELF));
830-        PMC_data(SELF) = NULL;
831-    }
832-
833-/*
834-
835 =item C<void mark()>
836 
837 Mark any referenced strings and PMCs.
838Index: src/pmc/capture.pmc
839===================================================================
840--- src/pmc/capture.pmc (.../trunk)     (revision 40501)
841+++ src/pmc/capture.pmc (.../branches/auto_attrs)       (revision 40501)
842@@ -1,5 +1,5 @@
843 /*
844-Copyright (C) 2001-2008, Parrot Foundation.
845+Copyright (C) 2001-2009, Parrot Foundation.
846 $Id$
847 
848 =head1 NAME
849@@ -26,7 +26,7 @@
850     if (!PARROT_CAPTURE(obj)->hash) \
851         PARROT_CAPTURE(obj)->hash = pmc_new((i), enum_class_Hash);
852 
853-pmclass Capture need_ext {
854+pmclass Capture need_ext auto_attrs {
855     ATTR PMC    *array;
856     ATTR PMC    *hash;
857     ATTR INTVAL  data_size;
858@@ -37,31 +37,19 @@
859 
860 Initializes the Capture instance.
861 
862-=item C<void destroy()>
863-
864-Free structures.
865-
866 =cut
867 
868 */
869 
870     VTABLE void init() {
871-        Parrot_Capture_attributes *capture = mem_allocate_typed(Parrot_Capture_attributes);
872-        PMC_data(SELF)          = capture;
873+        Parrot_Capture_attributes *capture =
874+                (Parrot_Capture_attributes *) PMC_data(SELF);
875         capture->array          = NULL;
876         capture->hash           = NULL;
877         capture->data_size      = CAPTURE_DATA_SIZE;
878-        PObj_active_destroy_SET(SELF);
879         PObj_custom_mark_SET(SELF);
880     }
881 
882-    VTABLE void destroy() {
883-        if (PARROT_CAPTURE(SELF)) {
884-            mem_sys_free(PARROT_CAPTURE(SELF));
885-            PMC_data(SELF) = NULL;
886-        }
887-    }
888-
889 /*
890 
891 =item C<PMC *clone()>
892Index: src/pmc/multisub.pmc
893===================================================================
894--- src/pmc/multisub.pmc        (.../trunk)     (revision 40501)
895+++ src/pmc/multisub.pmc        (.../branches/auto_attrs)       (revision 40501)
896@@ -19,7 +19,7 @@
897 
898 */
899 
900-pmclass MultiSub extends ResizablePMCArray need_ext provides array {
901+pmclass MultiSub extends ResizablePMCArray need_ext auto_attrs provides array {
902 
903     VTABLE void push_pmc(PMC *value) {
904         STRING * const _sub = CONST_STRING(interp, "Sub");
905Index: src/pmc/resizablefloatarray.pmc
906===================================================================
907--- src/pmc/resizablefloatarray.pmc     (.../trunk)     (revision 40501)
908+++ src/pmc/resizablefloatarray.pmc     (.../branches/auto_attrs)       (revision 40501)
909@@ -20,7 +20,7 @@
910 
911 */
912 
913-pmclass ResizableFloatArray extends FixedFloatArray need_ext provides array {
914+pmclass ResizableFloatArray extends FixedFloatArray need_ext auto_attrs provides array {
915     ATTR INTVAL resize_threshold; /* max size before array needs resizing */
916 
917 
918@@ -35,9 +35,7 @@
919 
920 */
921     VTABLE void init() {
922-        Parrot_ResizableFloatArray_attributes* attrs =
923-            mem_allocate_zeroed_typed(Parrot_ResizableFloatArray_attributes);
924-        PMC_data(SELF) = attrs;
925+        SUPER();
926     }
927 
928 /*
929Index: src/pmc/resizablestringarray.pmc
930===================================================================
931--- src/pmc/resizablestringarray.pmc    (.../trunk)     (revision 40501)
932+++ src/pmc/resizablestringarray.pmc    (.../branches/auto_attrs)       (revision 40501)
933@@ -18,7 +18,7 @@
934 
935 */
936 
937-pmclass ResizableStringArray extends FixedStringArray need_ext provides array {
938+pmclass ResizableStringArray extends FixedStringArray need_ext auto_attrs provides array {
939     ATTR UINTVAL resize_threshold; /*max capacity before resizing */
940 
941 /*
942@@ -36,12 +36,7 @@
943 */
944 
945     VTABLE void init() {
946-        Parrot_ResizableStringArray_attributes *attrs =
947-            mem_allocate_zeroed_typed(Parrot_ResizableStringArray_attributes);
948-
949-        PMC_data(SELF)   = attrs;
950-
951-        PObj_custom_mark_destroy_SETALL(SELF);
952+        SUPER();
953     }
954 
955 /*
956Index: src/pmc/hashiteratorkey.pmc
957===================================================================
958--- src/pmc/hashiteratorkey.pmc (.../trunk)     (revision 40501)
959+++ src/pmc/hashiteratorkey.pmc (.../branches/auto_attrs)       (revision 40501)
960@@ -19,48 +19,12 @@
961 
962 */
963 
964-pmclass HashIteratorKey no_ro {
965+pmclass HashIteratorKey no_ro auto_attrs {
966     ATTR Hash        *parrot_hash; /* Underlying parrot's hash */
967     ATTR HashBucket  *bucket;      /* Current bucket from HashItertor */
968 
969 /*
970 
971-=item C<void init()>
972-
973-Initializes the PMC.
974-
975-Not really part of public API.
976-
977-=cut
978-
979-*/
980-
981-    VTABLE void init() {
982-        Parrot_HashIteratorKey_attributes *attrs =
983-            mem_allocate_zeroed_typed(Parrot_HashIteratorKey_attributes);
984-
985-        PMC_data(SELF) = attrs;
986-
987-        PObj_active_destroy_SET(SELF);
988-    }
989-
990-/*
991-
992-=item C<void destroy()>
993-
994-Destroys this PMC
995-
996-=cut
997-
998-*/
999-
1000-    VTABLE void destroy() {
1001-        mem_sys_free(PMC_data(SELF));
1002-        PMC_data(SELF) = NULL;
1003-    }
1004-
1005-/*
1006-
1007 =item C<get_pmc()>
1008 
1009 Get "key".
1010Index: src/pmc/continuation.pmc
1011===================================================================
1012--- src/pmc/continuation.pmc    (.../trunk)     (revision 40501)
1013+++ src/pmc/continuation.pmc    (.../branches/auto_attrs)       (revision 40501)
1014@@ -45,7 +45,7 @@
1015  * need the next_for_GC pointer in the pmc_ext area.
1016  */
1017 
1018-pmclass Continuation need_ext {
1019+pmclass Continuation need_ext auto_attrs {
1020     ATTR struct Parrot_cont *cont; /* the continuation struct */
1021 
1022 /*
1023@@ -60,8 +60,7 @@
1024 
1025     VTABLE void init() {
1026         Parrot_Continuation_attributes *attrs =
1027-            mem_allocate_zeroed_typed(Parrot_Continuation_attributes);
1028-        PMC_data(SELF) = attrs;
1029+            (Parrot_Continuation_attributes *) PMC_data(SELF);
1030 
1031         PMC_cont(SELF) = new_continuation(INTERP, NULL);
1032         PObj_custom_mark_destroy_SETALL(SELF);
1033@@ -120,8 +119,6 @@
1034 
1035             mem_sys_free(cc);
1036         }
1037-        mem_sys_free(PMC_data(SELF));
1038-        PMC_data(SELF) = NULL;
1039     }
1040 /*
1041 
1042Index: src/pmc/timer.pmc
1043===================================================================
1044--- src/pmc/timer.pmc   (.../trunk)     (revision 40501)
1045+++ src/pmc/timer.pmc   (.../branches/auto_attrs)       (revision 40501)
1046@@ -57,7 +57,7 @@
1047 
1048 #include "parrot/scheduler_private.h"
1049 
1050-pmclass Timer extends Task provides event need_ext {
1051+pmclass Timer extends Task provides event need_ext auto_attrs {
1052     ATTR FLOATVAL      duration;  /* The duration of the timer pause */
1053     ATTR FLOATVAL      interval;  /* How often to repeat */
1054     ATTR INTVAL        repeat;    /* Whether to repeat:
1055@@ -75,14 +75,13 @@
1056 
1057     VTABLE void init() {
1058         Parrot_Timer_attributes * const core_struct =
1059-            mem_allocate_zeroed_typed(Parrot_Timer_attributes);
1060+            (Parrot_Timer_attributes *) PMC_data(SELF);
1061 
1062         /* Set flags for custom GC mark and destroy. */
1063         PObj_custom_mark_SET(SELF);
1064         PObj_active_destroy_SET(SELF);
1065 
1066         /* Set up the core struct. */
1067-        PMC_data(SELF)           = core_struct;
1068         core_struct->id          = 0;
1069         core_struct->type        = CONST_STRING(interp, "timer");
1070         core_struct->subtype     = CONST_STRING(interp, "");
1071@@ -179,8 +178,6 @@
1072 
1073     VTABLE void destroy() {
1074         Parrot_cx_delete_task(INTERP, SELF);
1075-        mem_sys_free(PMC_data(SELF));
1076-        PMC_data(SELF) = NULL;
1077     }
1078 
1079 /*
1080Index: src/pmc/stringiterator.pmc
1081===================================================================
1082--- src/pmc/stringiterator.pmc  (.../trunk)     (revision 40501)
1083+++ src/pmc/stringiterator.pmc  (.../branches/auto_attrs)       (revision 40501)
1084@@ -22,7 +22,7 @@
1085 */
1086 
1087 
1088-pmclass StringIterator extends Iterator {
1089+pmclass StringIterator auto_attrs extends Iterator {
1090     ATTR PMC    *string;    /* String to iterate over */
1091     ATTR INTVAL  pos;       /* Current position of iterator for forward iterator */
1092                             /* Previous position of iterator for reverse iterator */
1093@@ -39,35 +39,15 @@
1094 
1095 */
1096     VTABLE void init_pmc(PMC *string) {
1097-        Parrot_StringIterator_attributes * const attrs =
1098-            mem_allocate_zeroed_typed(Parrot_StringIterator_attributes);
1099+        SET_ATTR_string(INTERP, SELF, string);
1100 
1101-        attrs->string    = string;
1102-        PMC_data(SELF)   = attrs;
1103-
1104-        PObj_custom_mark_destroy_SETALL(SELF);
1105-
1106         /* by default, iterate from start */
1107         SELF.set_integer_native(ITERATE_FROM_START);
1108+        PObj_custom_mark_SET(SELF);
1109     }
1110 
1111 /*
1112 
1113-=item C<void destroy()>
1114-
1115-destroys this PMC
1116-
1117-=cut
1118-
1119-*/
1120-
1121-    VTABLE void destroy() {
1122-        mem_sys_free(PMC_data(SELF));
1123-        PMC_data(SELF) = NULL;
1124-    }
1125-
1126-/*
1127-
1128 =item C<void mark()>
1129 
1130 Marks the current idx/key and the aggregate as live.
1131Index: src/pmc/hashiterator.pmc
1132===================================================================
1133--- src/pmc/hashiterator.pmc    (.../trunk)     (revision 40501)
1134+++ src/pmc/hashiterator.pmc    (.../branches/auto_attrs)       (revision 40501)
1135@@ -75,7 +75,7 @@
1136     return bucket;
1137 }
1138 
1139-pmclass HashIterator extends Iterator no_ro {
1140+pmclass HashIterator extends Iterator no_ro auto_attrs {
1141     ATTR PMC        *pmc_hash;      /* the Hash which this Iterator iterates */
1142     ATTR Hash       *parrot_hash;   /* Underlying implementation of hash */
1143     ATTR HashBucket *bucket;        /* Current bucket */
1144@@ -96,7 +96,7 @@
1145 
1146     VTABLE void init_pmc(PMC *hash) {
1147         Parrot_HashIterator_attributes * const attrs =
1148-            mem_allocate_zeroed_typed(Parrot_HashIterator_attributes);
1149+            (Parrot_HashIterator_attributes *) PMC_data(SELF);
1150 
1151         attrs->pmc_hash         = hash;
1152         attrs->parrot_hash      = (Hash*)VTABLE_get_pointer(INTERP, hash);
1153@@ -106,9 +106,8 @@
1154         /* Will be decreased on initial advance_to_next */
1155         /* XXX Do we really need to support this use-case ? */
1156         attrs->elements         = attrs->parrot_hash->entries + 1;
1157-        PMC_data(SELF)          = attrs;
1158 
1159-        PObj_custom_mark_destroy_SETALL(SELF);
1160+        PObj_custom_mark_SET(SELF);
1161 
1162         /* Initial state of iterator is "before start" */
1163         /* So, advance to first element */
1164@@ -117,21 +116,6 @@
1165 
1166 /*
1167 
1168-=item C<void destroy()>
1169-
1170-destroys this PMC
1171-
1172-=cut
1173-
1174-*/
1175-
1176-    VTABLE void destroy() {
1177-        mem_sys_free(PMC_data(SELF));
1178-        PMC_data(SELF) = NULL;
1179-    }
1180-
1181-/*
1182-
1183 =item C<void mark()>
1184 
1185 Marks the hash as live.
1186Index: src/pmc/fixedpmcarray.pmc
1187===================================================================
1188--- src/pmc/fixedpmcarray.pmc   (.../trunk)     (revision 40501)
1189+++ src/pmc/fixedpmcarray.pmc   (.../branches/auto_attrs)       (revision 40501)
1190@@ -27,7 +27,7 @@
1191 #define PMC_size(x)  ((Parrot_FixedPMCArray_attributes *)PMC_data(x))->size
1192 #define PMC_array(x) ((Parrot_FixedPMCArray_attributes *)PMC_data(x))->pmc_array
1193 
1194-pmclass FixedPMCArray need_ext provides array {
1195+pmclass FixedPMCArray need_ext auto_attrs provides array {
1196     ATTR INTVAL   size;      /* number of elements in the array */
1197     ATTR PMC    **pmc_array; /* pointer to PMC array */
1198 
1199@@ -66,9 +66,7 @@
1200 
1201     VTABLE void init() {
1202         Parrot_FixedPMCArray_attributes *attrs =
1203-            mem_allocate_zeroed_typed(Parrot_FixedPMCArray_attributes);
1204-
1205-        PMC_data(SELF) = attrs;
1206+            (Parrot_FixedPMCArray_attributes *) PMC_data(SELF);
1207         PObj_custom_mark_destroy_SETALL(SELF);
1208     }
1209 
1210@@ -86,8 +84,6 @@
1211         if (PMC_array(SELF)) {
1212             mem_sys_free(PMC_array(SELF));
1213         }
1214-        mem_sys_free(PMC_data(SELF));
1215-        PMC_data(SELF) = NULL;
1216     }
1217 
1218 /*
1219Index: src/pmc/undef.pmc
1220===================================================================
1221--- src/pmc/undef.pmc   (.../trunk)     (revision 40501)
1222+++ src/pmc/undef.pmc   (.../branches/auto_attrs)       (revision 40501)
1223@@ -57,7 +57,6 @@
1224             VTABLE_destroy(interp, clone);
1225 
1226             PObj_is_object_SET(SELF);
1227-            PObj_active_destroy_SET(SELF);
1228 
1229         }
1230     }
1231Index: src/pmc/unmanagedstruct.pmc
1232===================================================================
1233--- src/pmc/unmanagedstruct.pmc (.../trunk)     (revision 40501)
1234+++ src/pmc/unmanagedstruct.pmc (.../branches/auto_attrs)       (revision 40501)
1235@@ -651,7 +651,7 @@
1236     return toff;
1237 }
1238 
1239-pmclass UnManagedStruct need_ext no_ro {
1240+pmclass UnManagedStruct need_ext auto_attrs no_ro {
1241     ATTR void   *ptr;   /* the struct that this UnManagedStruct isn't managing */
1242     ATTR PMC    *init;  /* the initializer used with this UnManagedStruct */
1243     ATTR INTVAL  size;  /* the size of the struct */
1244@@ -664,39 +664,6 @@
1245 
1246 =over 4
1247 
1248-=item C<void init()>
1249-
1250-Initializes the C<struct> with a default value of C<NULL>.
1251-
1252-=cut
1253-
1254-*/
1255-
1256-    VTABLE void init() {
1257-        Parrot_UnManagedStruct_attributes *attrs =
1258-            mem_allocate_zeroed_typed(Parrot_UnManagedStruct_attributes);
1259-        PMC_data(SELF) = attrs;
1260-        PObj_active_destroy_SET(SELF);
1261-    }
1262-
1263-/*
1264-
1265-=item C<void destroy()>
1266-
1267-Destroys the subroutine.
1268-
1269-=cut
1270-
1271-*/
1272-
1273-    VTABLE void destroy() {
1274-        mem_sys_free(PMC_data(SELF));
1275-        PMC_data(SELF) = NULL;
1276-    }
1277-
1278-
1279-/*
1280-
1281 =item C<void init_pmc(PMC *value)>
1282 
1283 Initialize the struct with some data.
1284@@ -724,9 +691,6 @@
1285 */
1286 
1287     VTABLE void init_pmc(PMC *value) {
1288-        Parrot_UnManagedStruct_attributes *attrs =
1289-            mem_allocate_zeroed_typed(Parrot_UnManagedStruct_attributes);
1290-        PMC_data(SELF) = attrs;
1291         SELF.set_pmc(value);
1292     }
1293 
1294Index: src/pmc/float.pmc
1295===================================================================
1296--- src/pmc/float.pmc   (.../trunk)     (revision 40501)
1297+++ src/pmc/float.pmc   (.../branches/auto_attrs)       (revision 40501)
1298@@ -18,7 +18,7 @@
1299 
1300 */
1301 
1302-pmclass Float extends scalar provides float provides scalar {
1303+pmclass Float extends scalar provides float provides scalar auto_attrs {
1304     ATTR FLOATVAL fv;
1305 
1306 /*
1307@@ -32,27 +32,9 @@
1308 */
1309 
1310     VTABLE void init() {
1311-        Parrot_Float_attributes * const fattr = mem_allocate_zeroed_typed(Parrot_Float_attributes);
1312-
1313-        PMC_data(SELF) = fattr;
1314         SET_ATTR_fv(INTERP, SELF, 0.0);
1315-
1316-        PObj_active_destroy_SET(SELF);
1317     }
1318-/*
1319 
1320-=item C<void destroy()>
1321-
1322-Destroy this PMC.
1323-
1324-=cut
1325-
1326-*/
1327-
1328-    VTABLE void destroy() {
1329-        mem_sys_free(PMC_data(SELF));
1330-        PMC_data(SELF) = NULL;
1331-    }
1332 /*
1333 
1334 =item C<PMC *clone()>
1335Index: src/pmc/fixedintegerarray.pmc
1336===================================================================
1337--- src/pmc/fixedintegerarray.pmc       (.../trunk)     (revision 40501)
1338+++ src/pmc/fixedintegerarray.pmc       (.../branches/auto_attrs)       (revision 40501)
1339@@ -19,7 +19,7 @@
1340 
1341 */
1342 
1343-pmclass FixedIntegerArray need_ext provides array {
1344+pmclass FixedIntegerArray need_ext auto_attrs provides array {
1345     ATTR INTVAL   size;  /* number of INTVALs stored in this array */
1346     ATTR INTVAL * int_array; /* INTVALs are stored here */
1347 
1348@@ -40,9 +40,6 @@
1349 */
1350 
1351     VTABLE void init() {
1352-        Parrot_FixedIntegerArray_attributes* attrs =
1353-            mem_allocate_zeroed_typed(Parrot_FixedIntegerArray_attributes);
1354-        PMC_data(SELF) = attrs;
1355         PObj_active_destroy_SET(SELF);
1356     }
1357 
1358@@ -154,8 +151,6 @@
1359         GET_ATTR_int_array(INTERP, SELF, int_array);
1360         if (int_array)
1361             mem_sys_free(int_array);
1362-        mem_sys_free(PMC_data(SELF));
1363-        PMC_data(SELF) = NULL;
1364     }
1365 
1366 /*
1367Index: src/pmc/scheduler.pmc
1368===================================================================
1369--- src/pmc/scheduler.pmc       (.../trunk)     (revision 40501)
1370+++ src/pmc/scheduler.pmc       (.../branches/auto_attrs)       (revision 40501)
1371@@ -20,7 +20,7 @@
1372 
1373 #include "parrot/scheduler_private.h"
1374 
1375-pmclass Scheduler need_ext {
1376+pmclass Scheduler need_ext auto_attrs {
1377 
1378     ATTR INTVAL        id;         /* The scheduler's ID. */
1379     ATTR INTVAL        max_tid;    /* The highest assigned task ID. */
1380@@ -48,14 +48,13 @@
1381 
1382     VTABLE void init() {
1383         Parrot_Scheduler_attributes * const core_struct =
1384-            mem_allocate_zeroed_typed(Parrot_Scheduler_attributes);
1385+            (Parrot_Scheduler_attributes *) PMC_data(SELF);
1386 
1387         /* Set flags for custom GC mark and destroy. */
1388         PObj_custom_mark_SET(SELF);
1389         PObj_active_destroy_SET(SELF);
1390 
1391         /* Set up the core struct. */
1392-        PMC_data(SELF)           = core_struct;
1393         core_struct->id          = 0;
1394         core_struct->max_tid     = 0;
1395         core_struct->task_list   = pmc_new(interp, enum_class_Hash);
1396@@ -248,8 +247,6 @@
1397     VTABLE void destroy() {
1398         Parrot_Scheduler_attributes * const core_struct = PARROT_SCHEDULER(SELF);
1399         MUTEX_DESTROY(core_struct->msg_lock);
1400-        mem_sys_free(core_struct);
1401-        PMC_data(SELF) = NULL;
1402     }
1403 
1404 
1405Index: src/pmc/resizablebooleanarray.pmc
1406===================================================================
1407--- src/pmc/resizablebooleanarray.pmc   (.../trunk)     (revision 40501)
1408+++ src/pmc/resizablebooleanarray.pmc   (.../branches/auto_attrs)       (revision 40501)
1409@@ -30,7 +30,7 @@
1410 /* Convert a size in bits to a size in bytes */
1411 #define BITS_TO_BYTES(size) ((size) / BITS_PER_CHAR)
1412 
1413-pmclass ResizableBooleanArray extends FixedBooleanArray need_ext provides array {
1414+pmclass ResizableBooleanArray extends FixedBooleanArray need_ext auto_attrs provides array {
1415     /* RBA uses the same attributes as FBA, but in RBA they're used as follows:
1416        size:             position of the last element (a.k.a tail_pos)
1417        resize_threshold: position of the first element (a.k.a. head_pos) */
1418Index: src/pmc/exceptionhandler.pmc
1419===================================================================
1420--- src/pmc/exceptionhandler.pmc        (.../trunk)     (revision 40501)
1421+++ src/pmc/exceptionhandler.pmc        (.../branches/auto_attrs)       (revision 40501)
1422@@ -22,7 +22,7 @@
1423 
1424 #include "parrot/oplib/ops.h"
1425 
1426-pmclass ExceptionHandler extends Continuation need_ext {
1427+pmclass ExceptionHandler extends Continuation need_ext auto_attrs {
1428 
1429     ATTR PMC    *handled_types;
1430     ATTR PMC    *handled_types_except;
1431@@ -41,11 +41,10 @@
1432 
1433     VTABLE void init() {
1434         Parrot_ExceptionHandler_attributes * const core_struct =
1435-            mem_allocate_zeroed_typed(Parrot_ExceptionHandler_attributes);
1436+            (Parrot_ExceptionHandler_attributes *)PMC_data(SELF);
1437         Parrot_cont * const cc     = new_continuation(INTERP, NULL);
1438 
1439         cc->invoked                = 0;
1440-        PMC_data(SELF)             = core_struct;
1441         PMC_cont(SELF)             = cc;
1442         core_struct->min_severity  = 0;
1443         core_struct->max_severity  = 0;
1444Index: src/pmc/parrotlibrary.pmc
1445===================================================================
1446--- src/pmc/parrotlibrary.pmc   (.../trunk)     (revision 40501)
1447+++ src/pmc/parrotlibrary.pmc   (.../branches/auto_attrs)       (revision 40501)
1448@@ -31,7 +31,7 @@
1449 #define PMC_dlhandle(x) ((Parrot_ParrotLibrary_attributes*)PMC_data(x))->dl_handle
1450 #define PMC_oplib_init(x) ((Parrot_ParrotLibrary_attributes*)PMC_data(x))->oplib_init
1451 
1452-pmclass ParrotLibrary need_ext provides library {
1453+pmclass ParrotLibrary need_ext auto_attrs provides library {
1454     ATTR void * dl_handle;  /* DLL handle */
1455     ATTR void * oplib_init; /* oplib init function */
1456 
1457@@ -46,9 +46,6 @@
1458 */
1459 
1460     VTABLE void init() {
1461-        Parrot_ParrotLibrary_attributes * const attrs =
1462-            mem_allocate_zeroed_typed(Parrot_ParrotLibrary_attributes);
1463-        PMC_data(SELF) = attrs;
1464         PObj_active_destroy_SET(SELF);
1465     }
1466 
1467@@ -66,8 +63,6 @@
1468         void *dl_handle = PMC_dlhandle(SELF);
1469         if (dl_handle)
1470             Parrot_dlclose(dl_handle);
1471-        mem_sys_free(PMC_data(SELF));
1472-        PMC_data(SELF) = NULL;
1473     }
1474 
1475 
1476Index: src/pmc/managedstruct.pmc
1477===================================================================
1478--- src/pmc/managedstruct.pmc   (.../trunk)     (revision 40501)
1479+++ src/pmc/managedstruct.pmc   (.../branches/auto_attrs)       (revision 40501)
1480@@ -22,7 +22,7 @@
1481 typedef void (*custom_free_func_t)(PARROT_INTERP, void *ptr, void *priv);
1482 typedef PMC * (*custom_clone_func_t)(PARROT_INTERP, PMC *ptr, void *priv);
1483 
1484-pmclass ManagedStruct extends UnManagedStruct need_ext {
1485+pmclass ManagedStruct extends UnManagedStruct need_ext auto_attrs {
1486     /* if custom_free_func and ptr (inherited from UnManagedStruct) are both set,
1487      * custom_free_func is called before the normal destroy() function does any
1488      * work.
1489@@ -46,11 +46,7 @@
1490 */
1491 
1492     VTABLE void init() {
1493-        Parrot_ManagedStruct_attributes *attrs =
1494-            mem_allocate_zeroed_typed(Parrot_ManagedStruct_attributes);
1495         PObj_active_destroy_SET(SELF);
1496-        PMC_data(SELF) = attrs;
1497-
1498     }
1499 
1500 /*
1501@@ -91,8 +87,6 @@
1502             } else
1503                 mem_sys_free(ptr);
1504         }
1505-        mem_sys_free(PMC_data(SELF));
1506-        PMC_data(SELF) = NULL;
1507     }
1508 
1509 /*
1510Index: src/pmc/nci.pmc
1511===================================================================
1512--- src/pmc/nci.pmc     (.../trunk)     (revision 40501)
1513+++ src/pmc/nci.pmc     (.../branches/auto_attrs)       (revision 40501)
1514@@ -94,7 +94,7 @@
1515 }
1516 
1517 
1518-pmclass NCI need_ext {
1519+pmclass NCI need_ext auto_attrs {
1520     ATTR STRING    *signature;              /* The signature. */
1521     ATTR void      *func;                   /* Function pointer to call. */
1522     ATTR void      *orig_func;              /* Function pointer
1523@@ -148,12 +148,9 @@
1524 */
1525 
1526     VTABLE void init() {
1527-        PMC_data(SELF) = mem_allocate_zeroed_typed(Parrot_NCI_attributes);
1528-
1529         /* Mark that we're not a raw NCI. */
1530         PObj_flag_CLEAR(private2, SELF);
1531         PObj_custom_mark_SET(SELF);
1532-        PObj_active_destroy_SET(SELF);
1533     }
1534 
1535 /*
1536@@ -224,25 +221,6 @@
1537 
1538 /*
1539 
1540-=item C<void destroy()>
1541-
1542-Destroys the NCI, freeing any allocated memory.
1543-
1544-=cut
1545-
1546-*/
1547-
1548-    VTABLE void destroy() {
1549-        if (PMC_data(SELF)) {
1550-            Parrot_NCI_attributes * const nci_info = PARROT_NCI(SELF);
1551-
1552-            mem_sys_free(nci_info);
1553-            PMC_data(SELF) = NULL;
1554-        }
1555-    }
1556-
1557-/*
1558-
1559 =item C<PMC *clone()>
1560 
1561 Creates and returns a clone of the NCI.
1562Index: src/pmc/boolean.pmc
1563===================================================================
1564--- src/pmc/boolean.pmc (.../trunk)     (revision 40501)
1565+++ src/pmc/boolean.pmc (.../branches/auto_attrs)       (revision 40501)
1566@@ -21,7 +21,7 @@
1567 
1568 */
1569 
1570-pmclass Boolean extends Integer provides boolean provides scalar {
1571+pmclass Boolean extends Integer provides boolean provides scalar auto_attrs {
1572 
1573 /*
1574 
1575Index: src/pmc/pmcproxy.pmc
1576===================================================================
1577--- src/pmc/pmcproxy.pmc        (.../trunk)     (revision 40501)
1578+++ src/pmc/pmcproxy.pmc        (.../branches/auto_attrs)       (revision 40501)
1579@@ -64,7 +64,7 @@
1580 */
1581 
1582 
1583-pmclass PMCProxy extends Class need_ext {
1584+pmclass PMCProxy extends Class need_ext auto_attrs {
1585 
1586 /*
1587 
1588@@ -77,14 +77,13 @@
1589 */
1590 
1591     VTABLE void init() {
1592-        Parrot_Class_attributes * const _pmc = mem_allocate_zeroed_typed(Parrot_Class_attributes);
1593+        Parrot_Class_attributes * const _pmc =
1594+                (Parrot_Class_attributes *) PMC_data(SELF);
1595         PMC          * const new_attribute   = pmc_new(interp, enum_class_Hash);
1596         STRING       * const name            = CONST_STRING(interp, "proxy");
1597-        PMC_data(SELF)                       = _pmc;
1598 
1599-        /* Set flags for custom GC mark and destroy. */
1600+        /* Set flag for custom GC mark. */
1601         PObj_custom_mark_SET(SELF);
1602-        PObj_active_destroy_SET(SELF);
1603 
1604         /* Set up the object. */
1605         _pmc->id               = 0;
1606Index: src/pmc/stringhandle.pmc
1607===================================================================
1608--- src/pmc/stringhandle.pmc    (.../trunk)     (revision 40501)
1609+++ src/pmc/stringhandle.pmc    (.../branches/auto_attrs)       (revision 40501)
1610@@ -46,7 +46,7 @@
1611         return Parrot_str_equal(interp, s, CONST_STRING(interp, "utf8"));
1612 }
1613 
1614-pmclass StringHandle extends Handle need_ext {
1615+pmclass StringHandle extends Handle need_ext auto_attrs {
1616     ATTR INTVAL  flags;               /* Filehandle flags             */
1617     ATTR STRING *stringhandle;        /* The string data              */
1618     ATTR STRING *mode;                /* The mode string used in open */
1619@@ -70,9 +70,8 @@
1620 
1621     VTABLE void init() {
1622         Parrot_StringHandle_attributes *data_struct =
1623-                mem_allocate_typed(Parrot_StringHandle_attributes);
1624+                (Parrot_StringHandle_attributes *) PMC_data(SELF);
1625 
1626-        PMC_data(SELF)            = data_struct;
1627         data_struct->flags        = 0;
1628         data_struct->stringhandle = NULL;
1629         data_struct->mode         = NULL;
1630@@ -81,7 +80,6 @@
1631         data_struct->read_offset  = 0;
1632 
1633         PObj_custom_mark_SET(SELF);
1634-        PObj_active_destroy_SET(SELF);
1635     }
1636 
1637 /*
1638@@ -134,22 +132,6 @@
1639 
1640 /*
1641 
1642-=item C<void destroy()>
1643-
1644-Free structures.
1645-
1646-=cut
1647-
1648-*/
1649-    VTABLE void destroy() {
1650-        if (PARROT_STRINGHANDLE(SELF)) {
1651-            mem_sys_free(PARROT_STRINGHANDLE(SELF));
1652-            PMC_data(SELF) = NULL;
1653-        }
1654-    }
1655-
1656-/*
1657-
1658 =item C<INTVAL get_bool()>
1659 
1660 Returns whether the StringHandle has reached the end of the file.
1661Index: src/pmc/schedulermessage.pmc
1662===================================================================
1663--- src/pmc/schedulermessage.pmc        (.../trunk)     (revision 40501)
1664+++ src/pmc/schedulermessage.pmc        (.../branches/auto_attrs)       (revision 40501)
1665@@ -1,5 +1,5 @@
1666 /*
1667-Copyright (C) 2001-2008, Parrot Foundation.
1668+Copyright (C) 2001-2009, Parrot Foundation.
1669 $Id$
1670 
1671 =head1 NAME
1672@@ -20,7 +20,7 @@
1673 
1674 #include "parrot/scheduler_private.h"
1675 
1676-pmclass SchedulerMessage need_ext {
1677+pmclass SchedulerMessage need_ext auto_attrs {
1678     ATTR INTVAL  id;        /* The message's ID. */
1679     ATTR STRING *type;      /* The message's type. */
1680     ATTR PMC    *data;      /* Additional data for the message. */
1681@@ -37,14 +37,12 @@
1682 
1683     VTABLE void init() {
1684         Parrot_SchedulerMessage_attributes * const core_struct
1685-            = mem_allocate_zeroed_typed(Parrot_SchedulerMessage_attributes);
1686+            = (Parrot_SchedulerMessage_attributes *) PMC_data(SELF);
1687 
1688-        /* Set flags for custom GC mark and destroy. */
1689+        /* Set flags for custom GC mark. */
1690         PObj_custom_mark_SET(SELF);
1691-        PObj_active_destroy_SET(SELF);
1692 
1693         /* Set up the core struct. */
1694-        PMC_data(SELF)           = core_struct;
1695         core_struct->id          = 0;
1696         core_struct->type        = CONST_STRING(INTERP, "");
1697         core_struct->data        = PMCNULL;
1698@@ -189,20 +187,6 @@
1699 
1700 /*
1701 
1702-=item C<void destroy()>
1703-
1704-Free the scheduler's underlying struct.
1705-
1706-=cut
1707-
1708-*/
1709-    VTABLE void destroy() {
1710-        mem_sys_free(PMC_data(SELF));
1711-        PMC_data(SELF) = NULL;
1712-    }
1713-
1714-/*
1715-
1716 =item C<void mark()>
1717 
1718 Mark any referenced strings and PMCs.
1719Index: src/pmc/default.pmc
1720===================================================================
1721--- src/pmc/default.pmc (.../trunk)     (revision 40501)
1722+++ src/pmc/default.pmc (.../branches/auto_attrs)       (revision 40501)
1723@@ -327,6 +327,19 @@
1724 
1725 /*
1726 
1727+=item C<void destroy()>
1728+
1729+Does nothing.
1730+
1731+=cut
1732+
1733+*/
1734+
1735+    VTABLE void destroy() {
1736+    }
1737+
1738+/*
1739+
1740 =item C<PMC *instantiate(PMC *init)>
1741 
1742 Default fallback. Creates a new PMC of the type of the class SELF and
1743Index: src/pmc/fixedstringarray.pmc
1744===================================================================
1745--- src/pmc/fixedstringarray.pmc        (.../trunk)     (revision 40501)
1746+++ src/pmc/fixedstringarray.pmc        (.../branches/auto_attrs)       (revision 40501)
1747@@ -19,7 +19,7 @@
1748 
1749 */
1750 
1751-pmclass FixedStringArray need_ext provides array {
1752+pmclass FixedStringArray need_ext auto_attrs provides array {
1753     ATTR STRING **str_array; /* where the STRINGs are stored */
1754     ATTR UINTVAL  size;      /* element count */
1755 
1756@@ -40,12 +40,6 @@
1757 */
1758 
1759     VTABLE void init() {
1760-
1761-        Parrot_FixedStringArray_attributes *attrs =
1762-            mem_allocate_zeroed_typed(Parrot_FixedStringArray_attributes);
1763-
1764-        PMC_data(SELF) = attrs;
1765-
1766         PObj_custom_mark_destroy_SETALL(SELF);
1767     }
1768 
1769@@ -67,9 +61,6 @@
1770 
1771         if (str_array)
1772             mem_sys_free(str_array);
1773-
1774-        mem_sys_free(PMC_data(SELF));
1775-        PMC_data(SELF) = NULL;
1776     }
1777 
1778 /*
1779Index: src/pmc/key.pmc
1780===================================================================
1781--- src/pmc/key.pmc     (.../trunk)     (revision 40501)
1782+++ src/pmc/key.pmc     (.../branches/auto_attrs)       (revision 40501)
1783@@ -18,7 +18,7 @@
1784 
1785 */
1786 
1787-pmclass Key need_ext {
1788+pmclass Key need_ext auto_attrs {
1789     ATTR PMC      *next_key; /* Sometimes it's the next key, sometimes it's
1790                                 not.  The Key code is like that. */
1791     ATTR INTVAL    int_key;  /* int value of this key, or something magical if
1792@@ -40,30 +40,11 @@
1793 */
1794 
1795     VTABLE void init() {
1796-
1797-        Parrot_Key_attributes * const attrs =
1798-            mem_allocate_zeroed_typed(Parrot_Key_attributes);
1799-
1800-        PMC_data(SELF) = attrs;
1801-        PObj_custom_mark_destroy_SETALL(SELF);
1802+        PObj_custom_mark_SET(SELF);
1803     }
1804 
1805 /*
1806 
1807-=item C<void destroy()>
1808-
1809-Destroy this Key, but not in the way anyone reading its code would want.
1810-
1811-=cut
1812-
1813-*/
1814-    VTABLE void destroy() {
1815-        mem_sys_free(PMC_data(SELF));
1816-        PMC_data(SELF) = NULL;
1817-    }
1818-
1819-/*
1820-
1821 =item C<PMC *clone()>
1822 
1823 Creates and returns a clone of the key.
1824@@ -77,8 +58,6 @@
1825         PMC *dkey        = dest;
1826         PMC *key         = SELF;
1827 
1828-        PObj_custom_mark_destroy_SETALL(dest);
1829-
1830         for (; key ;) {
1831             switch (PObj_get_FLAGS(key) & KEY_type_FLAGS) {
1832                 case KEY_integer_FLAG:
1833Index: src/pmc/arrayiterator.pmc
1834===================================================================
1835--- src/pmc/arrayiterator.pmc   (.../trunk)     (revision 40501)
1836+++ src/pmc/arrayiterator.pmc   (.../branches/auto_attrs)       (revision 40501)
1837@@ -51,7 +51,7 @@
1838 
1839 */
1840 
1841-pmclass ArrayIterator extends Iterator no_ro {
1842+pmclass ArrayIterator extends Iterator no_ro auto_attrs {
1843     ATTR PMC    *array;     /* the array which this Iterator iterates */
1844     ATTR INTVAL  pos;       /* Current position of iterator for forward iterator */
1845                             /* Previous position of iterator for reverse iterator */
1846@@ -86,12 +86,11 @@
1847 
1848     VTABLE void init_pmc(PMC *array) {
1849         Parrot_ArrayIterator_attributes * const attrs =
1850-            mem_allocate_zeroed_typed(Parrot_ArrayIterator_attributes);
1851+            (Parrot_ArrayIterator_attributes *) PMC_data(SELF);
1852 
1853         attrs->array     = array;
1854-        PMC_data(SELF)   = attrs;
1855 
1856-        PObj_custom_mark_destroy_SETALL(SELF);
1857+        PObj_custom_mark_SET(SELF);
1858 
1859         /* by default, iterate from start */
1860         SELF.set_integer_native(ITERATE_FROM_START);
1861@@ -99,21 +98,6 @@
1862 
1863 /*
1864 
1865-=item C<void destroy()>
1866-
1867-destroys this PMC
1868-
1869-=cut
1870-
1871-*/
1872-
1873-    VTABLE void destroy() {
1874-        mem_sys_free(PMC_data(SELF));
1875-        PMC_data(SELF) = NULL;
1876-    }
1877-
1878-/*
1879-
1880 =item C<void mark()>
1881 
1882 Marks the current idx/key and the aggregate as live.
1883Index: src/pmc/integer.pmc
1884===================================================================
1885--- src/pmc/integer.pmc (.../trunk)     (revision 40501)
1886+++ src/pmc/integer.pmc (.../branches/auto_attrs)       (revision 40501)
1887@@ -43,7 +43,7 @@
1888     return self;
1889 }
1890 
1891-pmclass Integer extends scalar provides integer provides scalar {
1892+pmclass Integer extends scalar provides integer provides scalar auto_attrs {
1893     ATTR INTVAL iv; /* the value of this Integer */
1894 
1895 /*
1896@@ -91,16 +91,13 @@
1897 
1898     VTABLE void init() {
1899         Parrot_Integer_attributes * const attrs =
1900-            mem_allocate_typed(Parrot_Integer_attributes);
1901+            (Parrot_Integer_attributes *)PMC_data(SELF);
1902 
1903         attrs->iv      = 0;
1904-        PMC_data(SELF) = attrs;
1905         PObj_active_destroy_SET(SELF);
1906     }
1907 
1908     VTABLE void destroy() {
1909-        mem_sys_free(PMC_data(SELF));
1910-        PMC_data(SELF) = NULL;
1911     }
1912 
1913 /*
1914Index: src/pmc/fixedbooleanarray.pmc
1915===================================================================
1916--- src/pmc/fixedbooleanarray.pmc       (.../trunk)     (revision 40501)
1917+++ src/pmc/fixedbooleanarray.pmc       (.../branches/auto_attrs)       (revision 40501)
1918@@ -23,7 +23,7 @@
1919 
1920 #define BITS_PER_CHAR 8
1921 
1922-pmclass FixedBooleanArray need_ext provides array {
1923+pmclass FixedBooleanArray need_ext auto_attrs provides array {
1924     ATTR UINTVAL         size;             /* # of bits this fba holds */
1925     ATTR UINTVAL         resize_threshold; /* max capacity before resizing */
1926     ATTR unsigned char * bit_array;        /* where the bits go */
1927@@ -45,10 +45,6 @@
1928 */
1929 
1930     VTABLE void init() {
1931-        Parrot_FixedBooleanArray_attributes* attrs =
1932-            mem_allocate_zeroed_typed(Parrot_FixedBooleanArray_attributes);
1933-
1934-        PMC_data(SELF) = attrs;
1935         PObj_active_destroy_SET(SELF);
1936     }
1937 
1938@@ -67,8 +63,6 @@
1939         GET_ATTR_bit_array(INTERP, SELF, bit_array);
1940         if (bit_array)
1941             mem_sys_free(bit_array);
1942-        mem_sys_free(PMC_data(SELF));
1943-        PMC_data(SELF) = NULL;
1944     }
1945 
1946 /*
1947Index: src/dynpmc/foo.pmc
1948===================================================================
1949--- src/dynpmc/foo.pmc  (.../trunk)     (revision 40501)
1950+++ src/dynpmc/foo.pmc  (.../branches/auto_attrs)       (revision 40501)
1951@@ -8,7 +8,7 @@
1952  * proper inheritance - for testing only
1953  */
1954 
1955-pmclass Foo dynpmc group foo_group provides scalar extends Integer {
1956+pmclass Foo dynpmc group foo_group provides scalar extends Integer auto_attrs {
1957 
1958     VTABLE INTVAL get_integer() {
1959         return 42;
1960Index: src/dynpmc/foo2.pmc
1961===================================================================
1962--- src/dynpmc/foo2.pmc (.../trunk)     (revision 40501)
1963+++ src/dynpmc/foo2.pmc (.../branches/auto_attrs)       (revision 40501)
1964@@ -8,7 +8,7 @@
1965  * proper inheritance - for testing only
1966  */
1967 
1968-pmclass Foo2 dynpmc group foo_group provides scalar extends Foo {
1969+pmclass Foo2 dynpmc group foo_group provides scalar extends Foo auto_attrs {
1970 
1971     VTABLE INTVAL get_integer() {
1972         INTVAL i = SUPER();
1973Index: src/dynpmc/rotest.pmc
1974===================================================================
1975--- src/dynpmc/rotest.pmc       (.../trunk)     (revision 40501)
1976+++ src/dynpmc/rotest.pmc       (.../branches/auto_attrs)       (revision 40501)
1977@@ -8,7 +8,7 @@
1978  * generation.  For testing only.
1979  */
1980 
1981-pmclass ROTest dynpmc provides scalar extends Integer {
1982+pmclass ROTest dynpmc provides scalar extends Integer auto_attrs {
1983     VTABLE void set_integer_native(INTVAL value) :read {
1984     }
1985     VTABLE INTVAL get_integer() :write {
1986Index: lib/Parrot/Vtable.pm
1987===================================================================
1988--- lib/Parrot/Vtable.pm        (.../trunk)     (revision 40501)
1989+++ lib/Parrot/Vtable.pm        (.../branches/auto_attrs)       (revision 40501)
1990@@ -186,6 +186,10 @@
1991         $struct .= "    $entry->[1]_method_t $entry->[1];\n";
1992     }
1993 
1994+    $struct .= <<'EOF';
1995+    UINTVAL attr_size;      /* Size of the attributes struct */
1996+EOF
1997+
1998     $struct .= "} _vtable;\n";
1999 
2000     return $struct;
2001Index: lib/Parrot/Pmc2c/PMCEmitter.pm
2002===================================================================
2003--- lib/Parrot/Pmc2c/PMCEmitter.pm      (.../trunk)     (revision 40501)
2004+++ lib/Parrot/Pmc2c/PMCEmitter.pm      (.../branches/auto_attrs)       (revision 40501)
2005@@ -464,7 +464,8 @@
2006         NULL,       /* mro */
2007         NULL,       /* attribute_defs */
2008         NULL,       /* ro_variant_vtable */
2009-        $methlist
2010+        $methlist,
2011+       0           /* attr size */
2012     };
2013 ENDOFCODE
2014     return $cout;
2015@@ -640,6 +641,7 @@
2016             vt_${k}                 = Parrot_${classname}_${k}_get_vtable(interp);
2017             vt_${k}->base_type      = $enum_name;
2018             vt_${k}->flags          = $k_flags;
2019+
2020             vt_${k}->attribute_defs = attr_defs;
2021 
2022             vt_${k}->base_type           = entry;
2023@@ -761,6 +763,22 @@
2024     my $classname = $self->name;
2025     my $export = $self->is_dynamic ? 'PARROT_DYNEXT_EXPORT ' : 'PARROT_EXPORT';
2026 
2027+    # Sets the attr_size field:
2028+    # If the auto_attrs flag is set, use the current data,
2029+    # else check if this PMC has init or init_pmc vtable functions,
2030+    # setting it to 0 in that case, and keeping the value from the
2031+    # parent otherwise.
2032+    my $set_attr_size = '';
2033+    if ( @{$self->attributes} && $self->{flags}{auto_attrs} ) {
2034+        $set_attr_size .= "sizeof(Parrot_${classname}_attributes)";
2035+    }
2036+    else {
2037+        $set_attr_size .= "0" if exists($self->{has_method}{init}) ||
2038+                                 exists($self->{has_method}{init_pmc});
2039+    }
2040+    $set_attr_size =     "    vt->attr_size = " . $set_attr_size . ";\n"
2041+        if $set_attr_size ne '';
2042+
2043     my $vtable_updates = '';
2044     for my $name ( @{ $self->vtable->names } ) {
2045         if (exists $self->{has_method}{$name}) {
2046@@ -768,6 +786,8 @@
2047         }
2048     }
2049 
2050+    $vtable_updates .= $set_attr_size;
2051+
2052     $cout .= <<"EOC";
2053 
2054 $export
2055@@ -793,6 +813,8 @@
2056         }
2057     }
2058 
2059+    $vtable_updates .= $set_attr_size;
2060+
2061     $cout .= <<"EOC";
2062 
2063 $export