This seems like a good time to send in this patch:
It allocates the stack content memory using a buffer. This makes the stack chunks and the memory used to hold stack contents visible to the garbage collector. One can incrementally add to this to support copy-on-write semantics for the chunk contents, which I understand is going to be useful in taking continuations. This could be done by making the stack chunks themselves buffer headers or perhaps PMCs, which would be cool for introspection. Index: debug.c =================================================================== RCS file: /cvs/public/parrot/debug.c,v retrieving revision 1.6 diff -u -p -r1.6 debug.c --- debug.c 4 Jun 2002 14:44:52 -0000 1.6 +++ debug.c 6 Jun 2002 14:37:25 -0000 @@ -1204,7 +1204,7 @@ PDB_print_user_stack(struct Parrot_Inter valid_chunk(chunk, command, depth, STACK_CHUNK_DEPTH, i); - entry = &chunk->entry[depth]; + entry = (Stack_entry *)(chunk->buffer->bufstart) + depth; switch (entry->entry_type) { case STACK_ENTRY_INT: Index: resources.c =================================================================== RCS file: /cvs/public/parrot/resources.c,v retrieving revision 1.61 diff -u -p -r1.61 resources.c --- resources.c 4 Jun 2002 19:36:58 -0000 1.61 +++ resources.c 6 Jun 2002 14:37:27 -0000 @@ -302,6 +302,7 @@ trace_active_PMCs(struct Parrot_Interp * unsigned int i, j, chunks_traced; Stack_chunk *cur_stack, *start_stack; struct PRegChunk *cur_chunk; + Stack_entry *entry; /* We have to start somewhere, and the global stash is a good * place */ @@ -336,10 +337,15 @@ trace_active_PMCs(struct Parrot_Interp * chunks_traced = 0; /* The general stack's circular, so we need to be careful */ while (cur_stack && ((start_stack != cur_stack) || (chunks_traced == 0))) { - for (i = 0; i < cur_stack->used; i++) { - if (STACK_ENTRY_PMC == cur_stack->entry[i].entry_type && - cur_stack->entry[i].entry.pmc_val) { - last = mark_used(cur_stack->entry[i].entry.pmc_val, last); + if(cur_stack->buffer){ + buffer_lives(cur_stack->buffer); + + entry = (Stack_entry *)(cur_stack->buffer->bufstart); + for (i = 0; i < cur_stack->used; i++) { + if (STACK_ENTRY_PMC == entry[i].entry_type && + entry[i].entry.pmc_val) { + last = mark_used(entry[i].entry.pmc_val, last); + } } } @@ -398,6 +404,7 @@ trace_active_buffers(struct Parrot_Inter UINTVAL i, j, chunks_traced; Stack_chunk *cur_stack, *start_stack; struct SRegChunk *cur_chunk; + Stack_entry *entry; /* First mark the current set. We assume that all pointers in S * registers are pointing to valid buffers. This is not a good @@ -426,10 +433,14 @@ trace_active_buffers(struct Parrot_Inter chunks_traced = 0; /* The general stack's circular, so we need to be careful */ while (cur_stack && ((start_stack != cur_stack) || (chunks_traced == 0))) { - for (i = 0; i < cur_stack->used; i++) { - if (STACK_ENTRY_STRING == cur_stack->entry[i].entry_type && - cur_stack->entry[i].entry.string_val) { - buffer_lives((Buffer *)cur_stack->entry[i].entry.string_val); + if(cur_stack->buffer){ + buffer_lives(cur_stack->buffer); + entry = (Stack_entry *)(cur_stack->buffer->bufstart); + for (i = 0; i < cur_stack->used; i++) { + if (STACK_ENTRY_STRING == entry[i].entry_type && + entry[i].entry.string_val) { + buffer_lives((Buffer *)entry[i].entry.string_val); + } } } Index: stacks.c =================================================================== RCS file: /cvs/public/parrot/stacks.c,v retrieving revision 1.30 diff -u -p -r1.30 stacks.c --- stacks.c 17 May 2002 21:38:20 -0000 1.30 +++ stacks.c 6 Jun 2002 14:37:27 -0000 @@ -21,15 +21,22 @@ new_stack(Interp *interpreter) { #ifdef TIDY int i; + Stack_entry *entry; #endif + Stack_chunk *stack = mem_allocate_aligned(sizeof(Stack_chunk)); stack->used = 0; stack->next = stack; stack->prev = stack; + stack->buffer = new_buffer_header(interpreter); + Parrot_allocate(interpreter, stack->buffer, + sizeof(Stack_entry) * STACK_CHUNK_DEPTH); + #ifdef TIDY + entry = (Stack_entry *)stack->buffer->bufstart; for (i = 0; i < STACK_CHUNK_DEPTH; i++) - stack->entry[i].flags = NO_STACK_ENTRY_FLAGS; + entry[i].flags = NO_STACK_ENTRY_FLAGS; #endif return stack; } @@ -56,7 +63,7 @@ Stack_entry * stack_entry(Interp *interpreter, Stack_chunk *stack_base, Intval depth) { Stack_chunk *chunk; - Stack_entry *entry = NULL; + Stack_entry *entry; size_t offset = (size_t)depth; /* For negative depths, look from the bottom of the stack up. */ @@ -68,7 +75,7 @@ stack_entry(Interp *interpreter, Stack_c chunk = chunk->next; } if (offset < chunk->used) { - entry = &chunk->entry[offset - 1]; + entry = (Stack_entry *)chunk->buffer->bufstart + offset - 1; } } else { @@ -78,7 +85,8 @@ stack_entry(Interp *interpreter, Stack_c chunk = chunk->prev; } if (offset < chunk->used) { - entry = &chunk->entry[chunk->used - offset - 1]; + entry = (Stack_entry *)chunk->buffer->bufstart + + chunk->used - offset - 1; } } return entry; @@ -152,15 +160,23 @@ stack_push(Interp *interpreter, Stack_ch if (chunk->used == STACK_CHUNK_DEPTH) { /* Need to add a new chunk */ Stack_chunk *new_chunk = mem_allocate_aligned(sizeof(Stack_chunk)); + new_chunk->used = 0; new_chunk->next = stack_base; new_chunk->prev = chunk; chunk->next = new_chunk; stack_base->prev = new_chunk; chunk = new_chunk; + + /* Need to initialize this pointer before the collector sees it */ + chunk->buffer = NULL; + chunk->buffer = new_buffer_header(interpreter); + + Parrot_allocate(interpreter, chunk->buffer, + sizeof(Stack_entry) * STACK_CHUNK_DEPTH); } - entry = &chunk->entry[chunk->used]; + entry = (Stack_entry *)(chunk->buffer->bufstart) + chunk->used; /* Remember the type */ entry->entry_type = type; @@ -227,7 +243,7 @@ stack_pop(Interp *interpreter, Stack_chu /* Now decrement the SP */ chunk->used--; - entry = &chunk->entry[chunk->used]; + entry = (Stack_entry *)(chunk->buffer->bufstart) + chunk->used; /* Types of 0 mean we don't care */ if (type && entry->entry_type != type) { Index: include/parrot/stacks.h =================================================================== RCS file: /cvs/public/parrot/include/parrot/stacks.h,v retrieving revision 1.19 diff -u -p -r1.19 stacks.h --- include/parrot/stacks.h 22 Mar 2002 20:24:05 -0000 1.19 +++ include/parrot/stacks.h 6 Jun 2002 14:37:27 -0000 @@ -50,7 +50,7 @@ typedef struct stack_chunk { size_t used; struct stack_chunk *next; struct stack_chunk *prev; - struct stack_entry entry[STACK_CHUNK_DEPTH]; + Buffer *buffer; } Stack_chunk; typedef void (*Stack_cleanup_method)(Stack_entry *);