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