From: Nicholas Clark Date: Fri, 10 Feb 2012 19:48:25 +0000 (+0000) Subject: Refactor t/globs.t to avoid the side effects of a change to strict.pm X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=88d3c90be7333e5f9f8866502380149c9d403a4f;p=p5sagit%2FDevel-Size.git Refactor t/globs.t to avoid the side effects of a change to strict.pm As of blead commit b50b20584a1bbc1a, Implement new 'use 5.xxx' plan, use strict; will write to %^H. Move the eval that creates the subroutine into a different scope, a new subroutine generate_glob(), so that its outside pointer chain doesn't include gv_grew(). This avoids problems with eval ops changing the side of the %^H copies at runtime. --- diff --git a/CHANGES b/CHANGES index 6b3e1e1..ef94d1c 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,9 @@ Revision history for Perl extension Devel::Size. +0.77_50 2012-02-10 nicholas + * t/globs.t was failing on 5.15.6 and later due to side effects of a change + to strict.pm [CPAN #73998] + 0.77 2011-05-16 nicholas [no changes] diff --git a/t/globs.t b/t/globs.t index ae32309..11c0441 100644 --- a/t/globs.t +++ b/t/globs.t @@ -74,12 +74,35 @@ $SIG{__WARN__} = sub { - $shared_gvname, 'GV copies point back to the real GV'); } -sub gv_grew { - my ($sub, $glob, $code, $type) = @_; +# As of blead commit b50b20584a1bbc1a, Implement new 'use 5.xxx' plan, +# use strict; will write to %^H. In turn, this causes the eval $code below +# to have compile with a pp_hintseval with a private copy of %^H in the +# optree. In turn, this private value is copied on op execution and put on +# the stack. The act of copying requires a hash iterator, and the *first* +# time the op is encountered its private HV doesn't have space for one, so +# it's expanded to hold one. Which happens after $cv_was_size is assigned to. +# Which matters, because it means that the total size of anything that can +# reach \&gv_grew will include this extra size. In this case, this means that +# if the code for generate_glob() is within gv_grew() [as it used to be], +# then the generated subroutine's CvOUTSIDE points to an anon sub whose +# CvOUTSIDE points to gv_grew(). Which means that the generated subroutine +# gets "bigger" simply as a side effect of the eval executing. + +# The solution is to put the eval that creates the subroutine into a different +# scope, so that its outside pointer chain doesn't include gv_grew(). Hence +# it's now broken out into generate_glob(): + +sub generate_glob { + my ($sub, $glob) = @_; # unthreaded, this gives us a way of getting to sv_size() from one of the # other *_size() functions, with a GV that has nothing allocated from its # GP: eval "sub $sub { *$glob }; 1" or die $@; +} + +sub gv_grew { + my ($sub, $glob, $code, $type) = @_; + generate_glob($sub, $glob); # Assigning to IoFMT_GV() also provides this, threaded and unthreaded: $~ = $glob;