> My first thoughts on this are that we should go the whole way, and have > Parrot_allocate take a Buffer* and a requested size, and let it fill in the > bufstart and buflen parameters (as in the not-yet-implemented > Parrot_reallocate patch).
Heh, I thought the exact same thing when I first saw your realloc patch. Below is a cvs-relative patch (meaning it 'includes' Peter's patch as well, since it is unapplied), that builds off of his Parrot_reallocate to rename it to be Parrot_reallocate_buffer and adds a new function, Parrot_allocate_buffer. I did this over the weekend, but this looks like an opportune time to submit it. :) This patch also cleans up parrot code to use the defined memory interface in memory.c and resources.c (mem_sys_realloc versus realloc, etc). There's one small bug I noticed and fixed in the GC manager, that I came upon while fixing up array.pmc and perlarray.pmc: - for (i = 0; i < trace_buf->buflen; i++) { + for (i = 0; i < trace_buf->buflen / sizeof(PMC *); i++) { Finally, array.pmc and perlarray.pmc still remain to be cleaned up. I originally did them, but then the keyed patch got submitted, and I was unable to make a clean merge there. I'll do that later. For now, this should be cleaner than what is in there now. This patch cannot be applied cleanly on TOP of Peter's patch, due to my renaming of the function he implemented. It can be used instead of his however, as it just builds additional cleanup functionality on what he submitted. If someone commits his (I believe it was already approved) before this one gets approval, I will resubmit the patch as a diff relative to his. Mike Lambert
Index: embed.c =================================================================== RCS file: /cvs/public/parrot/embed.c,v retrieving revision 1.20 diff -u -r1.20 embed.c --- embed.c 2 Apr 2002 20:35:52 -0000 1.20 +++ embed.c 3 Apr 2002 10:10:04 -0000 @@ -68,7 +68,7 @@ program_size = 0; - program_code = (char *)malloc((unsigned)program_size + 1024); + program_code = (char *)mem_sys_allocate((unsigned)program_size + 1024); if (NULL == program_code) { fprintf(stderr, "Parrot VM: Could not allocate buffer to read packfile from stdin.\n"); @@ -79,7 +79,7 @@ while ((read_result = read(0, cursor, 1024)) > 0) { program_size += read_result; program_code = - realloc(program_code, (unsigned)program_size + 1024); + mem_sys_realloc(program_code, (unsigned)program_size + 1024); if (NULL == program_code) { fprintf(stderr, Index: interpreter.c =================================================================== RCS file: /cvs/public/parrot/interpreter.c,v retrieving revision 1.82 diff -u -r1.82 interpreter.c --- interpreter.c 2 Apr 2002 06:24:14 -0000 1.82 +++ interpreter.c 3 Apr 2002 10:10:05 -0000 @@ -442,7 +442,7 @@ if (!interpreter->prederef_code) { size_t N = interpreter->code->byte_code_size; size_t i; - void **temp = (void **)malloc(N * sizeof(void *)); + void **temp = (void **)mem_sys_allocate(N * sizeof(void *)); for (i = 0; i < N; i++) { temp[i] = (void *)(ptrcast_t)prederef; Index: io.ops =================================================================== RCS file: /cvs/public/parrot/io.ops,v retrieving revision 1.6 diff -u -r1.6 io.ops --- io.ops 26 Mar 2002 04:39:33 -0000 1.6 +++ io.ops 3 Apr 2002 10:10:05 -0000 @@ -51,16 +51,20 @@ inline op open(out PMC, in STR, in STR) { ParrotIO * io; - char * path, * mode; - /* We probably need to make this into a String API */ - path = Parrot_allocate(interpreter, ($2)->bufused + 1); - memcpy(path, ($2)->bufstart, ($2)->bufused); - *(path + ($2)->bufused) = 0; - mode = Parrot_allocate(interpreter, ($3)->bufused + 1); - memcpy(mode, ($3)->bufstart, ($3)->bufused); - *(mode + ($3)->bufused) = 0; + STRING *path, *mode, *nullstr; - io = PIO_open(interpreter, path, mode); + /* Not sure if we actually want usascii. It depends upon how + * new_io_pmc interfaces with the native system. */ + const CHARTYPE *usascii = chartype_lookup("usascii"); + char nullchar = '\0'; + + nullstr = string_make(interpreter, &nullchar, 1, NULL, 0, usascii); + path = string_transcode(interpreter, ($2), NULL, usascii, NULL); + mode = string_transcode(interpreter, ($3), NULL, usascii, NULL); + path = string_concat(interpreter, path, nullstr, 0); + mode = string_concat(interpreter, mode, nullstr, 0); + + io = PIO_open(interpreter, (char*)path->bufstart, (char*)mode->bufstart); if(!io) { /* FIXME: Handle error */ } Index: jit.c =================================================================== RCS file: /cvs/public/parrot/jit.c,v retrieving revision 1.16 diff -u -r1.16 jit.c --- jit.c 8 Mar 2002 04:14:42 -0000 1.16 +++ jit.c 3 Apr 2002 10:10:05 -0000 @@ -50,11 +50,11 @@ /* how should I allocate memory? */ op_address = - (INTVAL *)malloc((code_end - code_start + START_SIZE + 3) * + mem_sys_allocate((code_end - code_start + START_SIZE + 3) * sizeof(INTVAL)); op_real_address = - (INTVAL *)malloc((code_end - code_start + START_SIZE + 3) * + mem_sys_allocate((code_end - code_start + START_SIZE + 3) * sizeof(INTVAL)); /* intval constants */ @@ -86,7 +86,7 @@ } bytecode_position = 0; - arena_start = arena = malloc((unsigned int)size); + arena_start = arena = mem_sys_allocate((unsigned int)size); pc = code_start; Index: key.c =================================================================== RCS file: /cvs/public/parrot/key.c,v retrieving revision 1.24 diff -u -r1.24 key.c --- key.c 2 Apr 2002 20:35:52 -0000 1.24 +++ key.c 3 Apr 2002 10:10:05 -0000 @@ -196,7 +196,7 @@ } if (size > key->size) { KEY_PAIR *pair = - (KEY_PAIR *)realloc(key->keys, sizeof(KEY_PAIR *) * size); + (KEY_PAIR *)mem_sys_realloc(key->keys, sizeof(KEY_PAIR *) * size); if (pair != NULL) { INTVAL i; key->keys = pair; @@ -215,7 +215,7 @@ /* Memory leak in the making */ } key->keys = - (KEY_PAIR *)realloc(key->keys, sizeof(KEY_PAIR *) * size); + (KEY_PAIR *)mem_sys_realloc(key->keys, sizeof(KEY_PAIR *) * size); } key->size = size; } @@ -430,7 +430,7 @@ /* Memory leak in the making */ key->size--; key->keys = - (KEY_PAIR *)realloc(key->keys, + (KEY_PAIR *)mem_sys_realloc(key->keys, sizeof(KEY_PAIR *) * key->size); } else if (key->size == 0) { Index: memory.c =================================================================== RCS file: /cvs/public/parrot/memory.c,v retrieving revision 1.30 diff -u -r1.30 memory.c --- memory.c 29 Mar 2002 19:13:08 -0000 1.30 +++ memory.c 3 Apr 2002 10:10:05 -0000 @@ -110,31 +110,31 @@ /* Init the string header pool */ interpreter->arena_base->string_header_pool = mem_sys_allocate(sizeof(struct free_pool)); - interpreter->arena_base->string_header_pool->pool_buffer.bufstart = - Parrot_allocate(interpreter, 1024); + Parrot_allocate_buffer(interpreter, + &interpreter->arena_base->string_header_pool->pool_buffer, + 1024); interpreter->arena_base->string_header_pool->pool_buffer.flags = BUFFER_live_FLAG; - interpreter->arena_base->string_header_pool->pool_buffer.buflen = 1024; interpreter->arena_base->string_header_pool->entries_in_pool = 0; /* Init the buffer header pool */ interpreter->arena_base->buffer_header_pool = mem_sys_allocate(sizeof(struct free_pool)); - interpreter->arena_base->buffer_header_pool->pool_buffer.bufstart = - Parrot_allocate(interpreter, 1024); + Parrot_allocate_buffer(interpreter, + &interpreter->arena_base->buffer_header_pool->pool_buffer, + 1024); interpreter->arena_base->buffer_header_pool->pool_buffer.flags = BUFFER_live_FLAG; - interpreter->arena_base->buffer_header_pool->pool_buffer.buflen = 1024; interpreter->arena_base->buffer_header_pool->entries_in_pool = 0; /* Init the PMC header pool */ interpreter->arena_base->pmc_pool = mem_sys_allocate(sizeof(struct free_pool)); - interpreter->arena_base->pmc_pool->pool_buffer.bufstart = - Parrot_allocate(interpreter, 1024); + Parrot_allocate_buffer(interpreter, + &interpreter->arena_base->pmc_pool->pool_buffer, + 1024); interpreter->arena_base->pmc_pool->pool_buffer.flags = BUFFER_live_FLAG; - interpreter->arena_base->pmc_pool->pool_buffer.buflen = 1024; interpreter->arena_base->pmc_pool->entries_in_pool = 0; Parrot_new_pmc_header_arena(interpreter); } Index: resources.c =================================================================== RCS file: /cvs/public/parrot/resources.c,v retrieving revision 1.39 diff -u -r1.39 resources.c --- resources.c 1 Apr 2002 04:35:14 -0000 1.39 +++ resources.c 3 Apr 2002 10:10:06 -0000 @@ -17,22 +17,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 string header 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_buffer(interpreter, &pool->pool_buffer, new_size); } #ifdef GC_DEBUG Parrot_go_collect(interpreter); @@ -285,12 +281,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_buffer(interpreter, &pool->pool_buffer, new_size); } #ifdef GC_DEBUG Parrot_go_collect(interpreter); @@ -452,7 +444,7 @@ /* The only thing left is "buffer of PMCs" */ Buffer *trace_buf = current->data; PMC **cur_pmc = trace_buf->bufstart; - for (i = 0; i < trace_buf->buflen; i++) { + for (i = 0; i < trace_buf->buflen / sizeof(PMC *); i++) { if (cur_pmc[i]) { last = mark_used(cur_pmc[i], last); } @@ -902,6 +894,37 @@ } } 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_allocate_buffer(struct Parrot_Interp *interpreter, Buffer *buffer, size_t +new_size) { + buffer->bufstart = Parrot_allocate( interpreter, new_size ); + buffer->buflen = new_size; +} + +/* Change the size of a buffer/string created by Parrot_allocate_buffer + Input parameter is a pointer to a Buffer-like 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_buffer(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 Index: string.c =================================================================== RCS file: /cvs/public/parrot/string.c,v retrieving revision 1.65 diff -u -r1.65 string.c --- string.c 30 Mar 2002 03:04:37 -0000 1.65 +++ string.c 3 Apr 2002 10:10:06 -0000 @@ -47,13 +47,12 @@ } s = new_string_header(interpreter); - s->bufstart = Parrot_allocate(interpreter, buflen); + Parrot_allocate_buffer(interpreter, (Buffer *)s, buflen); s->encoding = encoding; /* Make sure we maintain the flags we might already have on the * string header we just fetched */ s->flags |= flags; s->type = type; - s->buflen = buflen; if (buffer) { mem_sys_memcopy(s->bufstart, buffer, buflen); @@ -79,10 +78,7 @@ if(copysize <= 0) return s; /* Don't check buflen, if we are here, we already checked. */ - newbuf = Parrot_allocate(interpreter, s->buflen + addlen); - mem_sys_memcopy(newbuf, s->bufstart, (UINTVAL)copysize); - s->bufstart = newbuf; - s->buflen += addlen; + Parrot_reallocate_buffer(interpreter, (Buffer *)s, s->buflen + addlen); return s; } @@ -166,8 +162,7 @@ { STRING *d; d = new_string_header(interpreter); - d->bufstart = Parrot_allocate(interpreter, s->buflen); - d->buflen = s->buflen; + Parrot_allocate_buffer(interpreter, (Buffer *)d, s->buflen); d->flags = s->flags & (~(unsigned int)BUFFER_constant_FLAG); d->bufused = s->bufused; d->strlen = s->strlen; Index: include/parrot/resources.h =================================================================== RCS file: /cvs/public/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 3 Apr 2002 10:10:08 -0000 @@ -31,6 +31,8 @@ void *Parrot_allocate(struct Parrot_Interp *, size_t size); void *Parrot_alloc_new_block(struct Parrot_Interp *, size_t, UINTVAL); +void Parrot_reallocate_buffer(struct Parrot_Interp *, Buffer *, size_t); +void Parrot_allocate_buffer(struct Parrot_Interp *, Buffer *, size_t); void Parrot_new_pmc_header_arena(struct Parrot_Interp *interpreter);