Simple patch, it looks larger than it should because I renamed new_chunk to next_chunk.
Rather than free the stack chunks as we pop back down the stack, just leave it at its high-water mark so we don't reallocate every time it grows. -Melvin Index: register.c =================================================================== RCS file: /cvs/public/parrot/register.c,v retrieving revision 1.20 diff -u -r1.20 register.c --- register.c 26 Mar 2002 07:42:08 -0000 1.20 +++ register.c 27 Mar 2002 03:26:32 -0000 @@ -28,16 +28,19 @@ } /* Nope, so plan B time. Allocate a new chunk of integer register frames */ else { - struct IRegChunk *new_chunk; - new_chunk = mem_sys_allocate(sizeof(struct IRegChunk)); - memcpy(&new_chunk->IReg[0], + struct IRegChunk *next_chunk; + if(interpreter->int_reg_top->next) + next_chunk = interpreter->int_reg_top->next; + else + next_chunk = mem_sys_allocate(sizeof(struct IRegChunk)); + memcpy(&next_chunk->IReg[0], &interpreter->int_reg, sizeof(struct IReg)); - new_chunk->used = 1; - new_chunk->free = FRAMES_PER_INT_REG_CHUNK - 1; - new_chunk->next = NULL; - new_chunk->prev = interpreter->int_reg_top; - interpreter->int_reg_top->next = new_chunk; - interpreter->int_reg_top = new_chunk; + next_chunk->used = 1; + next_chunk->free = FRAMES_PER_INT_REG_CHUNK - 1; + next_chunk->next = NULL; + next_chunk->prev = interpreter->int_reg_top; + interpreter->int_reg_top->next = next_chunk; + interpreter->int_reg_top = next_chunk; } } @@ -57,11 +60,8 @@ /* Empty? */ if (!top->used) { /* Yep, drop down a frame. Maybe */ - if (top->prev) { - top->prev->next = NULL; + if (top->prev) interpreter->int_reg_top = top->prev; - mem_sys_free(top); - } } } /* Nope. So pitch a fit */ @@ -99,16 +99,19 @@ } /* Nope, so plan B time. Allocate a new chunk of string register frames */ else { - struct SRegChunk *new_chunk; - new_chunk = mem_sys_allocate(sizeof(struct SRegChunk)); - memcpy(&new_chunk->SReg[0], + struct SRegChunk *next_chunk; + if(interpreter->string_reg_top->next) + next_chunk = interpreter->string_reg_top->next; + else + next_chunk = mem_sys_allocate(sizeof(struct SRegChunk)); + memcpy(&next_chunk->SReg[0], &interpreter->string_reg, sizeof(struct SReg)); - new_chunk->used = 1; - new_chunk->free = FRAMES_PER_STR_REG_CHUNK - 1; - new_chunk->next = NULL; - new_chunk->prev = interpreter->string_reg_top; - interpreter->string_reg_top->next = new_chunk; - interpreter->string_reg_top = new_chunk; + next_chunk->used = 1; + next_chunk->free = FRAMES_PER_STR_REG_CHUNK - 1; + next_chunk->next = NULL; + next_chunk->prev = interpreter->string_reg_top; + interpreter->string_reg_top->next = next_chunk; + interpreter->string_reg_top = next_chunk; } } @@ -128,11 +131,8 @@ /* Empty? */ if (!top->used) { /* Yep, drop down a frame. Maybe */ - if (top->prev) { - top->prev->next = NULL; + if (top->prev) interpreter->string_reg_top = top->prev; - mem_sys_free(top); - } } } /* Nope. So pitch a fit */ @@ -169,16 +169,19 @@ } /* Nope, so plan B time. Allocate a new chunk of num register frames */ else { - struct NRegChunk *new_chunk; - new_chunk = mem_sys_allocate(sizeof(struct NRegChunk)); - memcpy(&new_chunk->NReg[0], + struct NRegChunk *next_chunk; + if(interpreter->num_reg_top->next) + next_chunk = interpreter->num_reg_top->next; + else + next_chunk = mem_sys_allocate(sizeof(struct NRegChunk)); + memcpy(&next_chunk->NReg[0], &interpreter->num_reg, sizeof(struct NReg)); - new_chunk->used = 1; - new_chunk->free = FRAMES_PER_NUM_REG_CHUNK - 1; - new_chunk->next = NULL; - new_chunk->prev = interpreter->num_reg_top; - interpreter->num_reg_top->next = new_chunk; - interpreter->num_reg_top = new_chunk; + next_chunk->used = 1; + next_chunk->free = FRAMES_PER_NUM_REG_CHUNK - 1; + next_chunk->next = NULL; + next_chunk->prev = interpreter->num_reg_top; + interpreter->num_reg_top->next = next_chunk; + interpreter->num_reg_top = next_chunk; } } @@ -198,11 +201,8 @@ /* Empty? */ if (!top->used) { /* Yep, drop down a frame. Maybe */ - if (top->prev) { - top->prev->next = NULL; + if (top->prev) interpreter->num_reg_top = top->prev; - mem_sys_free(top); - } } } /* Nope. So pitch a fit */ @@ -239,16 +239,19 @@ } /* Nope, so plan B time. Allocate a new chunk of pmc register frames */ else { - struct PRegChunk *new_chunk; - new_chunk = mem_sys_allocate(sizeof(struct PRegChunk)); - memcpy(&new_chunk->PReg[0], + struct PRegChunk *next_chunk; + if(interpreter->pmc_reg_top->next) + next_chunk = interpreter->pmc_reg_top->next; + else + next_chunk = mem_sys_allocate(sizeof(struct PRegChunk)); + memcpy(&next_chunk->PReg[0], &interpreter->pmc_reg, sizeof(struct PReg)); - new_chunk->used = 1; - new_chunk->free = FRAMES_PER_PMC_REG_CHUNK - 1; - new_chunk->next = NULL; - new_chunk->prev = interpreter->pmc_reg_top; - interpreter->pmc_reg_top->next = new_chunk; - interpreter->pmc_reg_top = new_chunk; + next_chunk->used = 1; + next_chunk->free = FRAMES_PER_PMC_REG_CHUNK - 1; + next_chunk->next = NULL; + next_chunk->prev = interpreter->pmc_reg_top; + interpreter->pmc_reg_top->next = next_chunk; + interpreter->pmc_reg_top = next_chunk; } } @@ -268,11 +271,8 @@ /* Empty? */ if (!top->used) { /* Yep, drop down a frame. Maybe */ - if (top->prev) { - top->prev->next = NULL; + if (top->prev) interpreter->pmc_reg_top = top->prev; - mem_sys_free(top); - } } } /* Nope. So pitch a fit */ Index: resources.c =================================================================== RCS file: /cvs/public/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 27 Mar 2002 03:26:34 -0000 @@ -377,7 +377,8 @@ } } - /* Now walk the pmc stack */ + /* Now walk the pmc stack. Make sure to walk from top down + * since stack may have segments above top that we shouldn't walk. */ for (cur_chunk = interpreter->pmc_reg_top; cur_chunk; cur_chunk = cur_chunk->prev) { for (j = 0; j < cur_chunk->used; j++) { @@ -454,7 +455,8 @@ } } - /* Now walk the string stack */ + /* Now walk the string stack. Make sure to walk from top down + * since stack may have segments above top that we shouldn't walk. */ for (cur_chunk = interpreter->string_reg_top; cur_chunk; cur_chunk = cur_chunk->prev) { for (j = 0; j < cur_chunk->used; j++) {