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--;

Reply via email to