On Dec 14, 2005, at 12:52, Joshua Isom (via RT) wrote:

[ substr related PANIC ]

I've now a rather simple test case: a string reverse_inplace that shows some parts of the problem. (You might ulimit -v yourself to a few 100 Megs before running the program)

.sub main :main
    .local string s
    .local int N
    N = 500000
    s = repeat '0', N
    $S1 = repeat '1', N
    s .= $S1
    $I0 = length s
    print_item 'len'
    print_item $I0
    print_newline
    rev(s)
    print "ok\n"
.end
.sub rev
    .param string str
    .local int i, len
    len = length str
    dec len
    i = 0
beginwhile:
    if i >= len goto endwhile
    $S0 = substr str, i, 1            # (1)
    $S1 = substr str, len, 1
    substr str, i, 1, $S1             # (2)
    substr str, len, 1, $S0
    dec len
    inc i
    goto beginwhile
endwhile:
.end

The C<substr (1)> creates a COW reference pointing inside the B<str>.
This means that the C<PObj_COW_FLAG> is set on both strings, because
they now share the same string body.
The C<string_replace (2)> wants to modify C<str>, finds it COWed and
thus allocates a new string body in C<Parrot_unmake_COW()>.
In above code we'd get C<len/2> reallocations of the string memory.
But as C<$S0> and C<$S1> still hold references to the old buffer, it
can't be reclaimed and we end with a C<PANIC: Out of mem!>.

Why it's actually PANICing isn't totally clear, but I think the reasons is that the GC tries to create some extra storage for increased memory demand, which eventually is too much.

More investigations are ver welcome.

leo

Reply via email to