Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

5.10.0 -> 5.10.1 Regression in fafafbaf70 (Big slowdown in 5.10 @_ parameter passing) #9943

Closed
p5pRT opened this issue Nov 2, 2009 · 10 comments

Comments

@p5pRT
Copy link

p5pRT commented Nov 2, 2009

Migrated from rt.perl.org#70171 (status was 'resolved')

Searchable as RT70171$

@p5pRT
Copy link
Author

p5pRT commented Nov 2, 2009

From @avar

See the thread on p5p discussing this bug​:
http​://www.nntp.perl.org/group/perl.perl5.porters/2009/10/msg152347.html

When I upgraded from 5.10.0 -> 5.10.1 I discovered a regression in
perl that I traced back to this commit. The code in question can be
reduced to​:

  perl -e 'my $x = get_x(); my %x = %$x; sub get_x { %x=(1..1000);
return \%x; }'
  panic​: attempt to copy freed scalar 253a860 to 2534880 at -e line 1.

On my system it just does that for sufficiently large values of
1..1000. If I change that to 1..10 it doesn't panic but C<my %x> ends
up being​:

  (1 => undef, 3 => undef, 5 => undef, 7 => undef, 9 => undef)

While on 5.10.0 it's the correct​:

  (1 => 2, 3 => 4, 5 => 6, 7 => 8, 9 => 10)

On other perl versions (asking around in #p5p) the results have been​:
* 5.8.8 segfaults
* 5.8.9 relpanic
* 5.10.1 relpanic
* 5.10.0 works fine
* 5.11.0 relpanic

Here's an overview of what might be wrong​:
http​://www.nntp.perl.org/group/perl.perl5.porters/2009/10/msg152369.html

@p5pRT
Copy link
Author

p5pRT commented Nov 3, 2009

From @b2gills

On Mon, Nov 2, 2009 at 10​:52 AM, Ãvar Arnfjörð Bjarmason
<perlbug-followup@​perl.org> wrote​:

# New Ticket Created by  "Ævar Arnfjörð Bjarmason"
# Please include the string​:  [perl #70171]
# in the subject line of all future correspondence about this issue.
# <URL​: http​://rt.perl.org/rt3/Ticket/Display.html?id=70171 >

See the thread on p5p discussing this bug​:
http​://www.nntp.perl.org/group/perl.perl5.porters/2009/10/msg152347.html

When I upgraded from 5.10.0 -> 5.10.1 I discovered a regression in
perl that I traced back to this commit. The code in question can be
reduced to​:

 perl -e 'my $x = get_x(); my %x = %$x; sub get_x { %x=(1..1000);
return \%x; }'
 panic​: attempt to copy freed scalar 253a860 to 2534880 at -e line 1.

On my system it just does that for sufficiently large values of
1..1000. If I change that to 1..10 it doesn't panic but C<my %x> ends
up being​:

   (1 => undef, 3 => undef, 5 => undef, 7 => undef, 9 => undef)

While on 5.10.0 it's the correct​:

   (1 => 2, 3 => 4, 5 => 6, 7 => 8, 9 => 10)

On other perl versions (asking around in #p5p) the results have been​:
 * 5.8.8 segfaults
 * 5.8.9 relpanic
 * 5.10.1 relpanic
 * 5.10.0 works fine
 * 5.11.0 relpanic

Here's an overview of what might be wrong​:
http​://www.nntp.perl.org/group/perl.perl5.porters/2009/10/msg152369.html

What happens when you run

perl -Mstrict -we 'my $x = get_x(); my %x = %$x; sub get_x {
%x=(1..1000); return \%x; }'

on those systems?

@p5pRT
Copy link
Author

p5pRT commented Nov 3, 2009

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Nov 3, 2009

From @avar

On Tue, Nov 3, 2009 at 4​:17 PM, Brad Gilbert <b2gills@​gmail.com> wrote​:

What happens when you run

perl -Mstrict -we 'my $x = get_x(); my %x = %$x; sub get_x {
%x=(1..1000); return \%x; }'

on those systems?

The exact same thing (although I've only tested under 5.10.1).
Strictures have nothing to do with why this happens.

@p5pRT
Copy link
Author

p5pRT commented Dec 7, 2009

From @cpansprout

In this case my %x = %$x assigns a hash to itself. This causes the
hv_clear in pp_aassign to wipe away the hash before it can be copied.
The ‘panic​: attempt to copy freed scalar’ error is triggered by this
line, which copies the value​:
  sv_setsv(tmpstr,*relem); /* value */

The solution is to make sure the OPpASSIGN_COMMON flag is on in such
cases, so that pp_aassign copies everything before doing the assignment.

This fix causes a bus error in sort.t, because it happens to expose
bug #71076. If the patch in that queue is applied first, this one
works with no problems.

@p5pRT
Copy link
Author

p5pRT commented Dec 7, 2009

From @cpansprout

Inline Patch
diff -Nurp blead/op.c bleadcopy/op.c
--- blead/op.c	2009-11-21 10:43:09.000000000 -0800
+++ bleadcopy/op.c	2009-11-27 07:16:44.000000000 -0800
@@ -4266,7 +4266,6 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *le
 		    || left->op_type == OP_PADHV
 		    || left->op_type == OP_PADANY))
 	{
-	    maybe_common_vars = FALSE;
 	    if (left->op_private & OPpPAD_STATE) {
 		/* All single variable list context state assignments, hence
 		   state ($a) = ...
diff -Nurp blead/t/op/array.t bleadcopy/t/op/array.t
--- blead/t/op/array.t	2009-11-19 08:51:40.000000000 -0800
+++ bleadcopy/t/op/array.t	2009-11-27 06:32:22.000000000 -0800
@@ -7,7 +7,7 @@ BEGIN {
 
 require 'test.pl';
 
-plan (125);
+plan (127);
 
 #
 # @foo, @bar, and @ary are also used from tie-stdarray after tie-ing them
@@ -428,5 +428,19 @@ sub test_arylen {
     is("$x $y $z", "1 1 2");
 }
 
+# [perl #70171]
+{
+ my $x = get_x(); my %x = %$x; sub get_x { %x=(1..4); return \%x };
+ is(
+   join(" ", map +($_,$x{$_}), sort keys %x), "1 2 3 4",
+  'bug 70171 (self-assignment via my %x = %$x)'
+ );
+ my $y = get_y(); my @y = @$y; sub get_y { @y=(1..4); return \@y };
+ is(
+  "@y", "1 2 3 4",
+  'bug 70171 (self-assignment via my @x = @$x)'
+ );
+}
+
 
 "We're included by lib/Tie/Array/std.t so we need to return something true";

@p5pRT
Copy link
Author

p5pRT commented Dec 7, 2009

From @rgarcia

2009/12/6 Father Chrysostomos <sprout@​cpan.org>​:

In this case my %x = %$x assigns a hash to itself. This causes the hv_clear
in pp_aassign to wipe away the hash before it can be copied. The ‘panic​:
attempt to copy freed scalar’ error is triggered by this line, which copies
the value​:
                       sv_setsv(tmpstr,*relem);        /* value */

The solution is to make sure the OPpASSIGN_COMMON flag is on in such cases,
so that pp_aassign copies everything before doing the assignment.

Even if you have an OP_PADSV on the left ? I think that in this case
we can leave the optimisation in.

This fix causes a bus error in sort.t, because it happens to expose bug
#71076. If the patch in that queue is applied first, this one works with no
problems.

Ok.

@p5pRT
Copy link
Author

p5pRT commented Dec 14, 2009

@rgs - Status changed from 'open' to 'resolved'

@p5pRT p5pRT closed this as completed Dec 14, 2009
@p5pRT
Copy link
Author

p5pRT commented Dec 14, 2009

From @rgarcia

2009/12/13 Father Chrysostomos <sprout@​cpan.org>​:

On Dec 7, 2009, at 5​:35 AM, Rafael Garcia-Suarez wrote​:

2009/12/6 Father Chrysostomos <sprout@​cpan.org>​:

In this case my %x = %$x assigns a hash to itself. This causes the
hv_clear
in pp_aassign to wipe away the hash before it can be copied. The ‘panic​:
attempt to copy freed scalar’ error is triggered by this line, which
copies
the value​:
                      sv_setsv(tmpstr,*relem);        /* value */

The solution is to make sure the OPpASSIGN_COMMON flag is on in such
cases,
so that pp_aassign copies everything before doing the assignment.

Even if you have an OP_PADSV on the left ? I think that in this case
we can leave the optimisation in.

The optimisation disabled by OPpASSIGN_COMMON is still enabled for OP_PADSV
with this patch, but the maybe_common_vars optimisation is not, so attached
is a replacement patch.

Thanks, applied to bleadperl as 0f907b9.

@p5pRT
Copy link
Author

p5pRT commented Feb 16, 2010

From @avar

On Mon, Dec 14, 2009 at 15​:31, Rafael Garcia-Suarez <rgs@​consttype.org> wrote​:

2009/12/13 Father Chrysostomos <sprout@​cpan.org>​:

On Dec 7, 2009, at 5​:35 AM, Rafael Garcia-Suarez wrote​:

2009/12/6 Father Chrysostomos <sprout@​cpan.org>​:

In this case my %x = %$x assigns a hash to itself. This causes the
hv_clear
in pp_aassign to wipe away the hash before it can be copied. The ‘panic​:
attempt to copy freed scalar’ error is triggered by this line, which
copies
the value​:
                      sv_setsv(tmpstr,*relem);        /* value */

The solution is to make sure the OPpASSIGN_COMMON flag is on in such
cases,
so that pp_aassign copies everything before doing the assignment.

Even if you have an OP_PADSV on the left ? I think that in this case
we can leave the optimisation in.

The optimisation disabled by OPpASSIGN_COMMON is still enabled for OP_PADSV
with this patch, but the maybe_common_vars optimisation is not, so attached
is a replacement patch.

Thanks, applied to bleadperl as 0f907b9.

I added one extra test to that for good measure​:
http​://github.com/avar/perl/commit/26b110cf2c6fe8d8bb6ba625b0905c60392255ee

It can be pulled from the rt-70171-extra-test branch on
git​://github.com/avar/perl.git

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant