Count the size of padlist names in CVs (for v5.18 and later).
Nicholas Clark [Wed, 25 Mar 2015 19:35:19 +0000 (20:35 +0100)]
Fixing this for pre-v5.18 involves solving the more general problem of when
to "recurse" into nested structures, currently bodged with "SOME_RECURSION"
and friends. :-(

CHANGES
Size.xs
t/code.t

diff --git a/CHANGES b/CHANGES
index 8db209d..2347977 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -3,6 +3,7 @@ Revision history for Perl extension Devel::Size.
 0.79_53 2015-03-25 nicholas
   * Avoid t/recurse.t failing on earlier versions on 32 bit platforms
     (subroutines are smaller than it assumes)
+  * Count the size of padlist names in CVs (for v5.18 and later - earlier TODO)
 
 0.79_52 2015-03-20 nicholas
     two patches from Zefram:
diff --git a/Size.xs b/Size.xs
index 06d150b..dfd007d 100644 (file)
--- a/Size.xs
+++ b/Size.xs
@@ -769,7 +769,7 @@ padlist_size(pTHX_ struct state *const st, const PADLIST * const padl,
     /* This relies on PADNAMELIST and PAD being typedefed to AV.  If that
        ever changes, this code will need an update. */
     st->total_size += sizeof(PADLIST);
-    sv_size(aTHX_ st, (SV*)PadlistNAMES(padl), recurse);
+    sv_size(aTHX_ st, (SV*)PadlistNAMES(padl), TOTAL_SIZE_RECURSION);
     i = PadlistMAX(padl) + 1;
     st->total_size += sizeof(PAD*) * i;
     while (--i)
index 8b32e37..f57a3fe 100644 (file)
--- a/t/code.t
+++ b/t/code.t
@@ -1,7 +1,7 @@
 #!/usr/bin/perl -w
 
 use strict;
-use Test::More tests => 14;
+use Test::More tests => 18;
 use Devel::Size ':all';
 
 sub zwapp;
@@ -89,3 +89,36 @@ if ($] > 5.017001) {
           total_size(closure_without_eval()) + 256,
           "CvOUTSIDE is set on all cloned closures, so these won't differ by much");
 }
+
+sub two_lex {
+    my $a;
+    my $b;
+}
+
+sub ode {
+    my $We_are_the_music_makers_And_we_are_the_dreamers_of_dreams_Wandering_by_lone_sea_breakers_And_sitting_by_desolate_streams_World_losers_and_world_forsakers_On_whom_the_pale_moon_gleams_Yet_we_are_the_movers_and_shakers_Of_the_world_for_ever_it_seems;
+    my $With_wonderful_deathless_ditties_We_build_up_the_world_s_great_cities_And_out_of_a_fabulous_story_We_fashion_an_empire_s_glory_One_man_with_a_dream_at_pleasure_Shall_go_forth_and_conquer_a_crown_And_three_with_a_new_song_s_measure;
+    # /Ode/, Arthur O'Shaughnessy, published in 1873.
+    # Sadly all but one of the remaining versus are too long for an identifier.
+}
+
+my $two_lex_size = total_size(\&two_lex);
+cmp_ok($two_lex_size, '>', $crunch_size,
+       '&two_lex is bigger than an empty sub');
+cmp_ok($two_lex_size, '<', $crunch_size + 2048,
+       '&two_lex is bigger than an empty sub by less than 2048 bytes');
+
+my $ode_size = total_size(\&ode);
+{
+    # Fixing this for pre-v5.18 involves solving the more general problem of
+    # when to "recurse" into nested structures, currently bodged with
+    # "SOME_RECURSION" and friends. :-(
+    local $::TODO =
+        'Devel::Size has never handled the size of names in the pad correctly'
+        if $] < 5.017004;
+    cmp_ok($ode_size, '>', $two_lex_size + 384,
+           '&ode is bigger than a sub with two lexicals by least 384 bytes');
+}
+
+cmp_ok($ode_size, '<', $two_lex_size + 768,
+       '&ode is bigger than a sub with two lexicals by less than 768 bytes');