Author: leo
Date: Thu Oct 27 12:43:43 2005
New Revision: 9599

Modified:
   trunk/ast/ast_main.c
   trunk/classes/coroutine.pmc
   trunk/classes/eval.pmc
   trunk/classes/sub.pmc
   trunk/imcc/main.c
   trunk/imcc/parser_util.c
   trunk/imcc/pbc.c
   trunk/include/parrot/packfile.h
   trunk/include/parrot/sub.h
   trunk/src/embed.c
   trunk/src/packfile.c
Log:
Better handling of evaled code WRT GC
* sub and coroutines have now a new field eval_pmc
* if set, this marks the eval container being alive
* create a Eval.mark() method that marks all the contained subs
Evaled subroutines shouldn't vanish during GC anymore.
Thanks to pmichaud for the hint how to handle this.


Modified: trunk/ast/ast_main.c
==============================================================================
--- trunk/ast/ast_main.c        (original)
+++ trunk/ast/ast_main.c        Thu Oct 27 12:43:43 2005
@@ -76,7 +76,8 @@ ast_compile_past(Parrot_Interp interp, c
     imc_compile_all_units_for_ast(interp);
     imc_compile_all_units(interp);
 
-    PackFile_fixup_subs(interp, PBC_MAIN);
+    sub = pmc_new(interp, enum_class_Eval);
+    PackFile_fixup_subs(interp, PBC_MAIN, sub);
     if (old_cs) {
         /* restore old byte_code, */
         (void)Parrot_switch_to_cs(interp, old_cs, 0);
@@ -84,7 +85,6 @@ ast_compile_past(Parrot_Interp interp, c
     /*
      * create sub PMC
      */
-    sub = pmc_new(interp, enum_class_Eval);
     sub_data = PMC_sub(sub);
     sub_data->seg = new_cs;
     sub_data->address = new_cs->base.data;

Modified: trunk/classes/coroutine.pmc
==============================================================================
--- trunk/classes/coroutine.pmc (original)
+++ trunk/classes/coroutine.pmc Thu Oct 27 12:43:43 2005
@@ -205,13 +205,9 @@ Marks the coroutine as live.
 
     void mark () {
         struct Parrot_coro *c = PMC_coro(SELF);
-#if 0
-        mark_stack(INTERP, c->co_control_stack);
-        mark_stack(INTERP, c->co_control_base);
-        mark_stack(INTERP, c->co_pad_stack);
-#endif
         if (c && c->ctx)
             mark_context(INTERP, c->ctx);
+        SUPER();
     }
 }
 

Modified: trunk/classes/eval.pmc
==============================================================================
--- trunk/classes/eval.pmc      (original)
+++ trunk/classes/eval.pmc      Thu Oct 27 12:43:43 2005
@@ -51,6 +51,34 @@ clear_fixups(Interp* interpreter, PMC* s
     }
 }
 
+static void
+mark_subs(Interp* interpreter, PMC* self)
+{
+    opcode_t i, ci;
+    struct PackFile_ByteCode *seg;
+    struct PackFile_FixupTable *ft;
+    struct PackFile_ConstTable *ct;
+    PMC *sub;
+
+    seg = PMC_sub(self)->seg;
+    if (!seg)
+        return;
+    ft = seg->fixups;
+    if (!ft)
+        return;
+    ct = seg->const_table;
+    if (!ct)
+        return;
+    for (i = 0; i < ft->fixup_count; i++) {
+        switch (ft->fixups[i]->type) {
+            case enum_fixup_sub:
+                ci = ft->fixups[i]->offset;
+                sub = ct->constants[ci]->u.key;
+                pobject_lives(interpreter, (PObj*)sub);
+        }
+    }
+}
+
 pmclass Eval extends Closure need_ext {
 
     void init() {
@@ -103,6 +131,10 @@ pmclass Eval extends Closure need_ext {
         PMC_sub_ASSIGN(SELF, NULL);
     }
 
+    void mark() {
+        mark_subs(INTERP, SELF);
+    }
+
 /*
 
 =item C<STRING* get_string>
@@ -204,7 +236,7 @@ Final code fixup after thawing.
         if (!PackFile_unpack(INTERP, pf, packed->strstart, packed->strlen))
             real_exception(INTERP, NULL, E_IOError,
                     "couldn't unpack packfile");
-        fixup_subs(INTERP, pf->cur_cs, PBC_PBC);
+        fixup_subs(INTERP, pf->cur_cs, PBC_PBC, SELF);
         for (i = 0; i < pf->directory.num_segments; ++i) {
             seg = pf->directory.segments[i];
             if (seg->type == PF_BYTEC_SEG) {

Modified: trunk/classes/sub.pmc
==============================================================================
--- trunk/classes/sub.pmc       (original)
+++ trunk/classes/sub.pmc       Thu Oct 27 12:43:43 2005
@@ -384,7 +384,7 @@ Creates and returns a clone of the subro
 
 =item C<void mark()>
 
-Marks the continuation as live.
+Marks the sub as live.
 
 =cut
 
@@ -400,6 +400,8 @@ Marks the continuation as live.
             pobject_lives(INTERP, (PObj *) sub->namespace);
         if (!PMC_IS_NULL(sub->multi_signature))
             pobject_lives(INTERP, (PObj *) sub->multi_signature);
+        if (!PMC_IS_NULL(sub->eval_pmc))
+            pobject_lives(INTERP, (PObj *) sub->eval_pmc);
     }
 /*
 

Modified: trunk/imcc/main.c
==============================================================================
--- trunk/imcc/main.c   (original)
+++ trunk/imcc/main.c   Thu Oct 27 12:43:43 2005
@@ -608,7 +608,7 @@ main(int argc, char * argv[])
         free(packed);
         /* TODO */
         if (run_pbc != 2)
-            PackFile_fixup_subs(interp, PBC_POSTCOMP);
+            PackFile_fixup_subs(interp, PBC_POSTCOMP, NULL);
     }
 
     /* If necessary, load the file written above */
@@ -638,7 +638,7 @@ main(int argc, char * argv[])
         else
             IMCC_info(interp, 1, "Running...\n");
         if (!load_pbc)
-            PackFile_fixup_subs(interp, PBC_MAIN);
+            PackFile_fixup_subs(interp, PBC_MAIN, NULL);
         Parrot_runcode(interp, argc, argv);
         /* XXX no return value :-( */
     }

Modified: trunk/imcc/parser_util.c
==============================================================================
--- trunk/imcc/parser_util.c    (original)
+++ trunk/imcc/parser_util.c    Thu Oct 27 12:43:43 2005
@@ -700,7 +700,8 @@ imcc_compile(Parrot_Interp interp, const
 
     compile_string(interp, const_cast(s));
 
-    PackFile_fixup_subs(interp, PBC_MAIN);
+    sub = pmc_new(interp, enum_class_Eval);
+    PackFile_fixup_subs(interp, PBC_MAIN, sub);
     if (old_cs) {
         /* restore old byte_code, */
         (void)Parrot_switch_to_cs(interp, old_cs, 0);
@@ -711,7 +712,6 @@ imcc_compile(Parrot_Interp interp, const
      *
      * TODO if a sub was denoted :main return that instead
      */
-    sub = pmc_new(interp, enum_class_Eval);
     sub_data = PMC_sub(sub);
     sub_data->seg = new_cs;
     sub_data->address = new_cs->base.data;

Modified: trunk/imcc/pbc.c
==============================================================================
--- trunk/imcc/pbc.c    (original)
+++ trunk/imcc/pbc.c    Thu Oct 27 12:43:43 2005
@@ -1028,7 +1028,7 @@ e_pbc_end_sub(Interp *interpreter, void 
     if (pragma & P_IMMEDIATE) {
         IMCC_debug(interpreter, DEBUG_PBC, "immediate sub '%s'",
                 ins->r[0]->name);
-        PackFile_fixup_subs(interpreter, PBC_IMMEDIATE);
+        PackFile_fixup_subs(interpreter, PBC_IMMEDIATE, NULL);
     }
     return 0;
 }

Modified: trunk/include/parrot/packfile.h
==============================================================================
--- trunk/include/parrot/packfile.h     (original)
+++ trunk/include/parrot/packfile.h     Thu Oct 27 12:43:43 2005
@@ -257,8 +257,8 @@ typedef enum {
     PBC_POSTCOMP  = 16
 } pbc_action_enum_t;
 
-void PackFile_fixup_subs(Interp *interpreter, pbc_action_enum_t);
-void fixup_subs(Interp *interpreter, struct PackFile_ByteCode *self, int 
action);
+void PackFile_fixup_subs(Interp *, pbc_action_enum_t, PMC *eval_pmc);
+void fixup_subs(Interp *, struct PackFile_ByteCode *, int, PMC *eval_pmc);
 /*
  * directory functions
  */

Modified: trunk/include/parrot/sub.h
==============================================================================
--- trunk/include/parrot/sub.h  (original)
+++ trunk/include/parrot/sub.h  Thu Oct 27 12:43:43 2005
@@ -63,6 +63,7 @@ typedef struct Parrot_sub {
     INTVAL   n_regs_used[4];   /* INSP in PBC */
 
     PMC      *lexicals;         /* OrderedHash of Lexicals */
+    PMC      *eval_pmc;         /* eval container / NULL */
 
     /* - end common */
 
@@ -87,6 +88,7 @@ typedef struct Parrot_coro {
     INTVAL   n_regs_used[4];   /* INSP in PBC */
 
     PMC      *lexicals;         /* OrderedHash of Lexicals */
+    PMC      *eval_pmc;         /* eval container / NULL */
 
     /* - end common */
 

Modified: trunk/src/embed.c
==============================================================================
--- trunk/src/embed.c   (original)
+++ trunk/src/embed.c   Thu Oct 27 12:43:43 2005
@@ -410,7 +410,7 @@ again:
     /*
      * fixup constant subroutine objects
      */
-    fixup_subs(interpreter, pf->cur_cs, PBC_PBC);
+    fixup_subs(interpreter, pf->cur_cs, PBC_PBC, NULL);
     /*
      * JITting and/or prederefing the sub/the bytecode is done
      * in switch_to_cs before actual usage of the segment

Modified: trunk/src/packfile.c
==============================================================================
--- trunk/src/packfile.c        (original)
+++ trunk/src/packfile.c        Thu Oct 27 12:43:43 2005
@@ -431,17 +431,19 @@ mark_const_subs(Parrot_Interp interprete
 
 =item C<static void
 fixup_subs(Interp *interpreter, struct PackFile_Bytecode *self,
-   int action)>
+   int action, PMC *eval_pmc)>
 
 Fixes up the constant subroutine objects. B<action> is one of
-B<PBC_PBC>, B<PBC_LOADED>, or B<PBC_MAIN>.
+B<PBC_PBC>, B<PBC_LOADED>, or B<PBC_MAIN>. Also store the C<eval_pmc>
+in the sub structure, so that the eval PMC is kept alive be living subs.
 
 =cut
 
 */
 
 void
-fixup_subs(Interp *interpreter, struct PackFile_ByteCode *self, int action)
+fixup_subs(Interp *interpreter, struct PackFile_ByteCode *self, 
+        int action, PMC *eval_pmc)
 {
     opcode_t i, ci;
     struct PackFile_FixupTable *ft;
@@ -471,6 +473,7 @@ fixup_subs(Interp *interpreter, struct P
                     case enum_class_Sub:
                     case enum_class_Closure:
                     case enum_class_Coroutine:
+                        PMC_sub(sub_pmc)->eval_pmc = eval_pmc;
                         VTABLE_thawfinish(interpreter, sub_pmc, NULL);
                         if (PObj_get_FLAGS(sub_pmc) & SUB_FLAG_PF_MASK) {
                             /*
@@ -3398,7 +3401,7 @@ Parrot_load_bytecode(Interp *interpreter
         cs = IMCC_compile_file(interpreter, filename);
 #endif
         if (cs) {
-            fixup_subs(interpreter, cs, PBC_LOADED);
+            fixup_subs(interpreter, cs, PBC_LOADED, NULL);
         }
         else
             internal_exception(1, "compiler returned NULL ByteCode");
@@ -3417,9 +3420,9 @@ I<What does this do?>
 */
 
 void
-PackFile_fixup_subs(Interp *interpreter, pbc_action_enum_t what)
+PackFile_fixup_subs(Interp *interpreter, pbc_action_enum_t what, PMC *eval)
 {
-    fixup_subs(interpreter, interpreter->code, what);
+    fixup_subs(interpreter, interpreter->code, what, eval);
 }
 
 /*

Reply via email to