I don't know, if this is a possible way to go, nor how portable the malloc code really is - anyway I did hack together parrot with malloc.c from http://gee.cs.oswego.edu/dl/html/malloc.html. s also http://www.cs.utexas.edu/users/oops/papers.html.
The whole resource.c is replaced by calls to calloc/realloc (res.c), add_free_buffer does free(). Some results and comments: First life.pasm: CVS: 5000 generations in 15.906771 seconds. 314.331552 generations/sec LEA: 5000 generations in 10.821385 seconds. 462.048064 generations/sec make test shows currently gc_2-4 broken (no statistics) and 2 tests from src/intlist.t, which is proably my fault. perl6 --test -r shows: t/compiler/8.te 6 5 83,33% 1, 3-6 t/rx/call.test 2 2 100,00% 1-2 t/rx/special.te 2 2 100,00% 1-2 2 subtests skipped. Failed 3/17 test scripts, 82.35% okay. 9/72 subtests failed, 87.50% okay. I didn't look into these further, but this is probably due to more broken string/COW code + continuations in 8.t. string_substr / unmake_COW currently does highliy illegal (WRT malloc) things, which might or might not cause problems for the current GC implementation. s. patch. There are probably more things like this. I didn't look further into memory usage or such, though top seems to show ~double the footprint of CVS. If we consider to use this allocator, we could look more deeply. (I invested ~5 hours to get it to current state ;-) Have fun & comments welcome leo
--- parrot/res.c Tue Sep 24 17:06:21 2002 +++ parrot-leo/res.c Tue Sep 24 15:44:25 2002 @@ -0,0 +1,63 @@ +/* resources */ +#include <assert.h> +#include "parrot/parrot.h" +void +Parrot_go_collect(struct Parrot_Interp *interpreter) +{ +} +void * +Parrot_reallocate(struct Parrot_Interp *interpreter, void *from, size_t size) +{ + Buffer * buffer = from; + /* XXX clear */ + void *p; + size_t oldlen = buffer->buflen; + // size = (size + STRING_ALIGNMENT-1) & ~(STRING_ALIGNMENT-1); + p = realloc(buffer->bufstart, size); + if (size > buffer->buflen) + memset(p + oldlen, 0, size - oldlen); + buffer->buflen = size; + buffer->bufstart = p; + return buffer; +} +void * +Parrot_reallocate_string(struct Parrot_Interp *interpreter, STRING *str, + size_t size) +{ + void *p; + size = (size + STRING_ALIGNMENT-1) & ~(STRING_ALIGNMENT-1); + p = realloc(str->bufstart, size); + str->strstart = str->bufstart = p; + str->buflen = size; + return p; +} +void * +Parrot_allocate_string(struct Parrot_Interp *interpreter, STRING *str, + size_t size) +{ + str->bufstart = 0; + return Parrot_reallocate_string(interpreter, str, size); +} +void * +Parrot_allocate(struct Parrot_Interp *interpreter, void *buffer, size_t size) +{ + Buffer * b = buffer; + b->bufstart = calloc(1, size); + b->buflen = size; + return b; +} + +void +Parrot_initialize_memory_pools(struct Parrot_Interp *interpreter) +{ +} + +/* + * Local variables: + * c-indentation-style: bsd + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + * + * vim: expandtab shiftwidth=4: +*/ --- parrot/headers.c Mon Sep 9 11:42:19 2002 +++ parrot-leo/headers.c Tue Sep 24 15:55:51 2002 @@ -73,11 +73,17 @@ void add_free_buffer(struct Parrot_Interp *interpreter, - struct Small_Object_Pool *pool, void *buffer) + struct Small_Object_Pool *pool, void *buff) { - ((Buffer *)buffer)->flags = BUFFER_on_free_list_FLAG; /* Use the right length */ - ((Buffer *)buffer)->buflen = 0; + Buffer * buffer = buff; + if (buffer->buflen && !(buffer->flags & + (BUFFER_COW_FLAG|BUFFER_constant_FLAG))) { + free(buffer->bufstart); + buffer->bufstart = 0; + } + buffer->flags = BUFFER_on_free_list_FLAG; + buffer->buflen = 0; /* Copied from add_free_object */ *(void **)buffer = pool->free_list; --- parrot/string.c Sun Sep 15 15:30:59 2002 +++ parrot-leo/string.c Tue Sep 24 16:31:55 2002 @@ -32,17 +32,25 @@ else #endif if (s->flags & (BUFFER_COW_FLAG|BUFFER_constant_FLAG)) { + STRING *dest; interpreter->GC_block_level++; interpreter->DOD_block_level++; /* Make the copy point to only the portion of the string that * we are actually using. */ +#if 1 + dest = string_make(interpreter, s->strstart, s->bufused, + s->encoding, 0, s->type); + s->strstart = s->bufstart = dest->bufstart; + s->buflen = dest->buflen; +#else s->bufstart = s->strstart; s->buflen = s->bufused; /* Create new pool data for this header to use, * independant of the original COW data */ Parrot_reallocate_string(interpreter, s, s->buflen); +#endif s->flags &= ~(UINTVAL)(BUFFER_COW_FLAG | BUFFER_constant_FLAG); interpreter->GC_block_level--; interpreter->DOD_block_level--;