When you call pmc_new, the init() routine is run before the PMC is
anchored to the root set. This is a problem for things like
aggregates, because they are likely to want to allocate a big Buffer
during initialization. And disabling GC entirely just feels wrong --
especially with pmc_new_sized, it is very believable that this is a
very good time to be collecting garbage.

In short, it feels special-casey enough to me to warrant the following
patch, which adds a new item to the root set for just this purpose. It
could probably be better named. Dan, whaddaya think?

-- 
Gimme a job! http://foxglove.dnsalias.org/~sfink/job.html
C, perl, networking, performance optimization, Java, XML.

Index: include/parrot/interpreter.h
===================================================================
RCS file: /home/perlcvs/parrot/include/parrot/interpreter.h,v
retrieving revision 1.38
diff -u -r1.38 interpreter.h
--- include/parrot/interpreter.h        22 Mar 2002 20:24:05 -0000      1.38
+++ include/parrot/interpreter.h        29 Mar 2002 06:04:38 -0000
@@ -49,7 +49,6 @@
     FLOATVAL time;
 } ProfData;
 
-
 typedef struct Parrot_Interp {
     struct IReg int_reg;
     struct NReg num_reg;
@@ -83,6 +82,9 @@
 #if 0
     str_func_t *string_funcs;
 #endif
+
+    PMC* creating_pmc;          /* A PMC while it's being created, to avoid
+                                   getting garbage collected during its init */
 
     Interp_flags flags;         /* Various interpreter flags that
                                  * signal that runops should do
Index: pmc.c
===================================================================
RCS file: /home/perlcvs/parrot/pmc.c,v
retrieving revision 1.11
diff -u -r1.11 pmc.c
--- pmc.c       10 Mar 2002 21:19:46 -0000      1.11
+++ pmc.c       29 Mar 2002 06:28:43 -0000
@@ -39,6 +39,7 @@
         return NULL;
     }
 
+    interpreter->creating_pmc = pmc;
     pmc->flags = 0;
     pmc->data = 0;
 
@@ -53,6 +54,7 @@
     }
 
     pmc->vtable->init(interpreter, pmc, 0);
+    interpreter->creating_pmc = NULL;
     return pmc;
 }
 
@@ -67,6 +69,7 @@
         return NULL;
     }
 
+    interpreter->creating_pmc = pmc;
     pmc->flags = 0;
     pmc->data = 0;
 
@@ -81,6 +84,7 @@
     }
 
     pmc->vtable->init(interpreter, pmc, size);
+    interpreter->creating_pmc = NULL;
     return pmc;
 }
 
Index: resources.c
===================================================================
RCS file: /home/perlcvs/parrot/resources.c,v
retrieving revision 1.35
diff -u -r1.35 resources.c
--- resources.c 26 Mar 2002 16:33:01 -0000      1.35
+++ resources.c 29 Mar 2002 06:04:28 -0000
@@ -377,6 +377,10 @@
         }
     }
 
+    /* Mark a PMC while it is being created */
+    if (interpreter->creating_pmc)
+        last = mark_used(interpreter->creating_pmc, last);
+
     /* Now walk the pmc stack */
     for (cur_chunk = interpreter->pmc_reg_top; cur_chunk;
          cur_chunk = cur_chunk->prev) {

Reply via email to