Dan Sugalski wrote:

> I've committed this. 


Thanks you.

> ...It fails two of intlist.t's tests, but only with 
> the new allocator, so there's code in for folks to poke at and abuse.


Actually intlist's intlist_extend is wrong as the attached tests shows.
(If then there are still failures, we'll have to look closer - I don't 
have them)

- This patch corrects this makes it faster and looking nicer
- adds a testcase.
And additionally, for + 10 % more generations in life.pasm
- tossed one instruction in the fast path of Buffer_headers
- improves strcmp & substr for ASCII

leo






--- parrot/headers.c    Sat Oct  5 13:30:19 2002
+++ parrot-leo/headers.c        Sat Oct  5 13:34:05 2002
@@ -97,7 +97,6 @@
     ((Buffer *)buffer)->flags = BUFFER_on_free_list_FLAG;
     /* Use the right length */
     ((Buffer *)buffer)->buflen = 0;
-    ((Buffer *)buffer)->bufstart = 0;
 
     /* Copied from add_free_object */
     *(void **)buffer = pool->free_list;
--- parrot/string.c     Sat Oct  5 13:30:26 2002
+++ parrot-leo/string.c Sat Oct  5 13:36:06 2002
@@ -241,6 +241,9 @@
     return s ? s->strlen : 0;
 }
 
+/* while we have no inlines, do something */
+#define string_length(s) (s) ? (s)->strlen : 0
+
 /*=for api string string_index
  * return the character (or glyph, depending upon the string's encoding)
  * This is to abstract the process of finding the Nth character in a (possibly
@@ -517,6 +520,13 @@
         true_length = (UINTVAL)(src->strlen - true_offset);
     }
 
+    /* do in-place i.e. make a COW string */
+    dest = make_COW_reference(interpreter,  src);
+    if (src->encoding->index == enum_encoding_singlebyte) {
+        dest->strstart = (char *)dest->bufstart + true_offset;
+        dest->bufused = true_length;
+    }
+    else {
     substart_off = (const char *)src->encoding->skip_forward(src->strstart,
                                                        true_offset) -
         (char *)src->strstart;
@@ -531,10 +541,9 @@
                            "subend somehow is less than substart");
     }
 
-    /* do in-place if possible */
-    dest = make_COW_reference(interpreter,  src);
     dest->strstart = (char *)dest->strstart + substart_off;
     dest->bufused = subend_off - substart_off;
+    }
     dest->strlen = true_length;
 
     if (d != NULL) {
@@ -715,6 +724,7 @@
     const char *s2start;
     const char *s2end;
     INTVAL cmp = 0;
+    size_t minlen;
 
     if (s1 && !s2) {
         return (string_length(s1) != 0);
@@ -743,6 +753,13 @@
     s2start = s2->strstart;
     s2end = s2start + s2->bufused;
 
+    if (s1->encoding->index == enum_encoding_singlebyte) {
+        cmp = memcmp(s1start, s2start,
+                minlen = s1->bufused > s2->bufused ? s2->bufused:s1->bufused);
+        s1start += minlen;
+        s2start += minlen;
+    }
+    else {
     while (cmp == 0 && s1start < s1end && s2start < s2end) {
         INTVAL c1 = s1->encoding->decode(s1start);
         INTVAL c2 = s2->encoding->decode(s2start);
@@ -752,11 +769,14 @@
         s1start = s1->encoding->skip_forward(s1start, 1);
         s2start = s2->encoding->skip_forward(s2start, 1);
     }
+    }
 
-    if (cmp == 0 && s1start < s1end)
+    if (cmp == 0) {
+        if (s1start < s1end)
         cmp = 1;
-    if (cmp == 0 && s2start < s2end)
+        else if (s2start < s2end)
         cmp = -1;
+    }
 
     return cmp;
 }
--- parrot/intlist.c    Sat Sep 28 10:34:35 2002
+++ parrot-leo/intlist.c        Sat Oct  5 13:42:18 2002
@@ -189,7 +189,7 @@
     IntList_Chunk* lastChunk = list->prev;
     size_t len = 0;
     /* allocate a new chunk_list buffer, old one my have moved
-     * firsr, count chunks */
+     * first, count chunks */
     while (1) {
         len++;
         if (chunk == lastChunk) break;
@@ -394,26 +394,14 @@
 intlist_extend(Interp* interpreter, IntList* list, INTVAL length)
 {
     IntList_Chunk* chunk = list->prev;
-    INTVAL to_add = length - list->length;
-
-    while (to_add > 0) {
-        INTVAL available = INTLIST_CHUNK_SIZE - chunk->end;
-        INTVAL end;
-
-        /* Zero out all newly added elements */
-        end = (to_add <= available) ? chunk->end + to_add : INTLIST_CHUNK_SIZE;
-        memset(&((INTVAL*)chunk->buffer.bufstart)[chunk->end],
-               0,
-               sizeof(INTVAL) * (end - chunk->end));
-        to_add -= end - chunk->end;
-        chunk->end = end;
-
-        if (to_add > 0) push_chunk(interpreter, list);
-
+    INTVAL idx = length - list->length + chunk->end;
+    INTVAL chunks_to_add = idx / INTLIST_CHUNK_SIZE;
+    for (; chunks_to_add ; chunks_to_add--) {
+        chunk->end = INTLIST_CHUNK_SIZE;
+        push_chunk(interpreter, list);
         chunk = chunk->next;
     }
-
-    assert(length >= list->length);
+    chunk->end = idx % INTLIST_CHUNK_SIZE;
     list->length = length;
 }
 
--- parrot/t/pmc/intlist.t      Thu Sep 26 18:30:36 2002
+++ parrot-leo/t/pmc/intlist.t  Fri Oct  4 08:16:18 2002
@@ -1,6 +1,6 @@
 #! perl -w
 
-use Parrot::Test tests => 4;
+use Parrot::Test tests => 5;
 use Test::More;
 
 output_is(<<'CODE', <<'OUTPUT', "creation");
@@ -227,5 +227,70 @@
 CODE
 ok 1
 ok 2
+OUTPUT
+
+output_is(<<'CODE', <<'OUTPUT', "direct access 2");
+        new P0, .IntList
+       set I10, 1100000
+       set I0, 1
+lp1:
+       add I1, I0, 5
+       set P0[I0], I1
+       add I3, I1, I0
+       push P0, I3
+       shl I0, I0, 1
+       inc I0
+       le I0, I10, lp1
+
+       set I0, 1
+lp2:
+       add I1, I0, 5
+       # check at I0
+       set I2, P0[I0]
+       ne I2, I1, err
+       add I4, I0, 1
+       # and pushed value at I0+1
+       set I4, P0[I4]
+       add I3, I1, I0
+       ne I3, I4, err
+       # test if all zero between
+       add I5, I0, 2
+       shl I6, I0, 1
+       # but not beyond eol
+       ge I6, I10, cont
+lp3:
+       ge I5, I6, cont
+        set I7, P0[I5]
+       ne I7, 0, err
+       inc I5
+       branch lp3
+cont:
+       shl I0, I0, 1
+       inc I0
+       le I0, I10, lp2
+       print "ok\n"
+       end
+err:
+       print "not ok "
+       print I0
+       print " "
+       print I1
+       print " "
+       print I2
+       print " "
+       print I3
+       print " "
+       print I4
+       print " "
+       print I5
+       print " "
+       print I6
+       print " "
+       print I7
+       print "\n"
+
+       end
+CODE
+ok
 OUTPUT
 

Reply via email to