From: Nicholas Clark Date: Wed, 26 Mar 2003 23:01:46 +0000 (+0000) Subject: Better version of change #19069 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=bc44a8a2ef6444a7379feaa886439b1a4b82d7b2;p=p5sagit%2Fp5-mst-13.2.git Better version of change #19069 Subject: [PATCH] Re: [PATCH] Re: [perl #21614] 5.8.0 Unbalanced string table refcount Message-ID: <20030326230145.GC279@Bagpuss.unfortu.net> p4raw-link: @19069 on //depot/perl: 10bcdfd6e8d70ea5a2c02616001cf97fce7f3e17 p4raw-id: //depot/perl@19071 --- diff --git a/pp_hot.c b/pp_hot.c index 15ba94c..a622c53 100644 --- a/pp_hot.c +++ b/pp_hot.c @@ -1509,7 +1509,7 @@ Perl_do_readline(pTHX) sv_unref(sv); (void)SvUPGRADE(sv, SVt_PV); tmplen = SvLEN(sv); /* remember if already alloced */ - if (!tmplen) + if (!tmplen && !SvREADONLY(sv)) Sv_Grow(sv, 80); /* try short-buffering it */ offset = 0; if (type == OP_RCATLINE && SvOK(sv)) { diff --git a/sv.c b/sv.c index a1b44cf..1fdd0c2 100644 --- a/sv.c +++ b/sv.c @@ -1585,15 +1585,8 @@ Perl_sv_grow(pTHX_ register SV *sv, register STRLEN newlen) newlen = 0xFFFF; #endif } - else { - /* This is annoying, because sv_force_normal_flags will fix the flags, - recurse into sv_grow to malloc a buffer of SvCUR(sv) + 1, then - return back to us, only for us to potentially realloc the buffer. - */ - if (SvIsCOW(sv)) - sv_force_normal_flags(sv, 0); + else s = SvPVX(sv); - } if (newlen > SvLEN(sv)) { /* need more room? */ if (SvLEN(sv) && s) { @@ -6296,7 +6289,8 @@ Perl_sv_gets(pTHX_ register SV *sv, register PerlIO *fp, I32 append) I32 rspara = 0; I32 recsize; - SV_CHECK_THINKFIRST_COW_DROP(sv); + if (SvTHINKFIRST(sv)) + sv_force_normal_flags(sv, append ? 0 : SV_COW_DROP_PV); /* XXX. If you make this PVIV, then copy on write can copy scalars read from <>. However, perlbench says it's slower, because the existing swipe code diff --git a/t/op/readline.t b/t/op/readline.t index 8936022..d127d58 100644 --- a/t/op/readline.t +++ b/t/op/readline.t @@ -6,7 +6,7 @@ BEGIN { require './test.pl'; } -plan tests => 5; +plan tests => 11; eval { for (\2) { $_ = } }; like($@, 'Modification of a read-only value attempted', '[perl #19566]'); @@ -27,3 +27,34 @@ foreach my $k ('k', 'k'x82) { ); is ($result, "end", '[perl #21614] for length ' . length $k); } + + +foreach my $k ('perl', 'perl'x21) { + my $result + = runperl (switches => '-l', stdin => ' rules', stderr => 1, + prog => "%a = qw($k v); foreach (keys %a) {\$_ .= <>; print}", + ); + is ($result, "$k rules", 'rcatline to shared sv for length ' . length $k); +} + +foreach my $l (1, 82) { + my $k = $l; + $k = 'k' x $k; + my $copy = $k; + $k = ; + is ($k, "moo\n", 'catline to COW sv for length ' . length $copy); +} + + +foreach my $l (1, 21) { + my $k = $l; + $k = 'perl' x $k; + my $perl = $k; + $k .= ; + is ($k, "$perl rules\n", 'rcatline to COW sv for length ' . length $perl); +} +__DATA__ +moo +moo + rules + rules