"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