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


Reply via email to