"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