"Dan Sugalski" <[EMAIL PROTECTED]> wrote

> With the recent stack and GC patches, are we pretty much solid now?
> If so, a 0.0.5 bugfix release may well be in order.

The one outstanding issue that I know of is the mem_realloc problem in
add_pmc_to_free and add_header_to_free. Since the problem is actually
endemic to mem_realloc, the best solution seems to be a replacement for
mem_realloc that takes a Buffer*, so that an intervening GC run still leaves
it knowing where the source is.
In line with a previous suggestion, I propose that such a routine be called
Parrot_reallocate.
A patch to create such a function and use it within add_pmc_to_free and
add_header_to_free follows; since all uses of mem_realloc are potentially at
risk, it might be a good idea to change any such places also.

--
Peter Gibbs
EmKel Systems

Index: include/parrot/resources.h
===================================================================
RCS file: /home/perlcvs/parrot/include/parrot/resources.h,v
retrieving revision 1.25
diff -u -r1.25 resources.h
--- include/parrot/resources.h  18 Mar 2002 22:09:10 -0000  1.25
+++ include/parrot/resources.h  30 Mar 2002 14:58:26 -0000
@@ -31,6 +31,7 @@

 void *Parrot_allocate(struct Parrot_Interp *, size_t size);
 void *Parrot_alloc_new_block(struct Parrot_Interp *, size_t, UINTVAL);
+void Parrot_reallocate(struct Parrot_Interp *, Buffer *, size_t);

 void Parrot_new_pmc_header_arena(struct Parrot_Interp *interpreter);

Index: resources.c
===================================================================
RCS file: /home/perlcvs/parrot/resources.c,v
retrieving revision 1.37
diff -u -r1.37 resources.c
--- resources.c 30 Mar 2002 05:57:32 -0000 1.37
+++ resources.c 30 Mar 2002 14:57:38 -0000
@@ -18,22 +18,18 @@
 static void add_header_to_free(struct Parrot_Interp *interpreter,
                                struct free_pool *pool, void *to_add);

-/* Add a string header to the free string header pool */
+/* Add a PMC header to the free pool */
 static void add_pmc_to_free(struct Parrot_Interp *interpreter,
                             struct free_pool *pool, void
                             *to_add) {
   PMC **temp_ptr;
   /* First, check and see if there's enough space in the free pool. If
-   we're within the size of a STRING pointer, we make it bigger */
+   we're within the size of a pointer, we make it bigger */
   if (pool->entries_in_pool * sizeof(PMC *) >=
       pool->pool_buffer.buflen - sizeof(PMC *)) {
     /* If not, make the free pool bigger. We enlarge it by 20% */
-    pool->pool_buffer.bufstart = mem_realloc(interpreter,
-                                             pool->pool_buffer.bufstart,
-                                             pool->pool_buffer.buflen,
-
(UINTVAL)(pool->pool_buffer.buflen * 1.2));
-    pool->pool_buffer.buflen = (UINTVAL)(pool->pool_buffer.buflen * 1.2);
-
+    size_t new_size = pool->pool_buffer.buflen * 1.2;
+    Parrot_reallocate(interpreter, &pool->pool_buffer, new_size);
   }

   /* Okay, so there's space. Add the header on */
@@ -273,12 +269,8 @@
   if (pool->entries_in_pool * sizeof(STRING *) >=
       pool->pool_buffer.buflen - sizeof(STRING *)) {
     /* If not, make the free pool bigger. We enlarge it by 20% */
-    pool->pool_buffer.bufstart = mem_realloc(interpreter,
-                                             pool->pool_buffer.bufstart,
-                                             pool->pool_buffer.buflen,
-
(UINTVAL)(pool->pool_buffer.buflen * 1.2));
-    pool->pool_buffer.buflen = (UINTVAL)(pool->pool_buffer.buflen * 1.2);
-
+    size_t new_size = pool->pool_buffer.buflen * 1.2;
+    Parrot_reallocate(interpreter, &pool->pool_buffer, new_size);
   }

   /* Okay, so there's space. Add the header on */
@@ -879,6 +871,25 @@
     }
   }
   return (void *)return_val;
+}
+
+/* Change the size of a buffer/string created by Parrot_allocate
+   Input parameter is a pointer to the Buffer or String structure
+   bufstart is updated to point to the new memory
+   buflen is updated to the new length
+   min(buflen,new_size) bytes are copied from old location to new location
+*/
+void
+Parrot_reallocate(struct Parrot_Interp *interpreter, Buffer *buffer, size_t
new_size) {
+    size_t copysize = (buffer->buflen > new_size ? new_size :
buffer->buflen);
+    void *new_ptr = Parrot_allocate(interpreter, new_size);
+    if (!new_ptr) {
+        internal_exception(ALLOCATION_ERROR,
+                           "Out of memory during buffer reallocation");
+    }
+    memcpy(new_ptr, buffer->bufstart, copysize);
+    buffer->bufstart = new_ptr;
+    buffer->buflen = new_size;
 }

 /* Tag a buffer header as alive. Used by the GC system when tracing


Reply via email to