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