Dan Sugalski wrote: > That's because GC_DEBUG is fundamentally broken by design. It's doing > things it shouldn't be doing--the system is such that it shouldn't > ever trigger GC before the memory allocation system is set up. > > If this patch disables the GC only when GC_DEBUG is in place, I'll put it in.
So you're saying that the calls to get memory during interpreter initialization are somehow guaranteed to not require more memory (and thus a dod or collection run)? Currently, this guarantee is not expressed in code, comments, or documentation, from what I can tell. And I personally hate implicit assumptions like these...they're the cause of all that magic voodo, far away from where it's obvious what the problem is. We have no idea of knowing how much is 'enough' for the GC to allocate at startup, aside from the following the code and tracking allocations, which can be a pain. Currently, we alloc_new_block a default-sized block, of size 32768, and then request three blocks of 1024 byes in mem_setup_allocator. So we're okay. But we do stuff like request a PMC header for the stash_hash. Who knows what a PerlSymbolTable PMC will allocate internally? Personally, I think it's a fragile equilibrium at the moment, although admittedly it has a large buffer zone. However, we're still just one greedy allocation away from GPFing parrot during initialization. Having made my case, I'm submitting an ifdef'ed version of the code, so you can choose this one should my argument not convince you. :) Thanks, Mike Lambert
Index: interpreter.c =================================================================== RCS file: /cvs/public/parrot/interpreter.c,v retrieving revision 1.82 diff -u -r1.82 interpreter.c --- interpreter.c 2 Apr 2002 06:24:14 -0000 1.82 +++ interpreter.c 11 Apr 2002 22:48:43 -0000 @@ -497,6 +497,11 @@ interpreter->DOD_block_level = 0; interpreter->GC_block_level = 0; + interpreter->flags = flags; +#ifdef GC_DEBUG + Interp_flags_CLEAR(interpreter,PARROT_ALLOW_GC_FLAG); +#endif + /* Set up the memory allocation system */ mem_setup_allocator(interpreter); @@ -506,8 +511,7 @@ pmc_new(interpreter, enum_class_PerlHash); interpreter->perl_stash->parent_stash = NULL; - /* Initialize interpreter's flags */ - interpreter->flags = flags; + /* Initialize interpreter warnings */ interpreter->warns = mem_sys_allocate(sizeof(struct warnings_t)); memset(interpreter->warns, 0, sizeof(struct warnings_t)); PARROT_WARNINGS_off(interpreter, PARROT_WARNINGS_ALL_FLAG); @@ -557,6 +561,11 @@ interpreter->pmc_reg_base->next = NULL; interpreter->pmc_reg_base->prev = NULL; Parrot_clear_p(interpreter); + +#ifdef GC_DEBUG + /* We've got enough for full interpreter now, so allow gc */ + Interp_flags_SET(interpreter,PARROT_ALLOW_GC_FLAG); +#endif /* Need a user stack */ interpreter->user_stack = new_stack(interpreter); Index: resources.c =================================================================== RCS file: /cvs/public/parrot/resources.c,v retrieving revision 1.41 diff -u -r1.41 resources.c --- resources.c 11 Apr 2002 18:54:33 -0000 1.41 +++ resources.c 11 Apr 2002 22:48:45 -0000 @@ -565,6 +565,13 @@ void Parrot_do_dod_run(struct Parrot_Interp *interpreter) { +#ifdef GC_DEBUG + /* Exit early if we shouldn't be running */ + if(!Interp_flags_TEST(interpreter,PARROT_ALLOW_GC_FLAG)) { + return; + } +#endif + /* First go mark all PMCs as unused */ mark_PMCs_unused(interpreter); @@ -707,6 +714,13 @@ char *cur_spot; /* Where we're currently copying to */ UINTVAL cur_size; /* How big our chunk is going to be */ struct STRING_Arena *cur_arena; /* The string arena we're working on */ + +#ifdef GC_DEBUG + /* Exit early if we shouldn't be running */ + if(!Interp_flags_TEST(interpreter,PARROT_ALLOW_GC_FLAG)) { + return; + } +#endif /* We're collecting */ interpreter->mem_allocs_since_last_collect = 0; Index: include/parrot/interpreter.h =================================================================== RCS file: /cvs/public/parrot/include/parrot/interpreter.h,v retrieving revision 1.40 diff -u -r1.40 interpreter.h --- include/parrot/interpreter.h 3 Apr 2002 04:01:41 -0000 1.40 +++ include/parrot/interpreter.h 11 Apr 2002 22:48:46 -0000 @@ -23,7 +23,8 @@ PARROT_BOUNDS_FLAG = 0x04, /* We're tracking byte code bounds */ PARROT_PROFILE_FLAG = 0x08, /* We're gathering profile information */ PARROT_PREDEREF_FLAG = 0x10, /* We're using the prederef runops */ - PARROT_JIT_FLAG = 0x20 /* We're using the jit runops */ + PARROT_JIT_FLAG = 0x20, /* We're using the jit runops */ + PARROT_ALLOW_GC_FLAG = 0x40 /* Allow dod and collection to occur */ } Interp_flags; #define Interp_flags_SET(interp, flag) (/*@i1@*/ (interp)->flags |= (flag))