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