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);
}
/*