File: code.t

package info (click to toggle)
libdevel-size-perl 0.85-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 388 kB
  • sloc: perl: 737; makefile: 3
file content (160 lines) | stat: -rw-r--r-- 6,265 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#!/usr/bin/perl -w

use strict;
use Test::More tests => 20;
use Devel::Size ':all';

# For me, for some files locally, I'm seeing failures
# Failed test '&two_lex is bigger than an empty sub by less than 2048 bytes'
# Just for some perl versions (5.8.7, 5.10.1, some 5.12.*)
# As ever, the reason is subtle and annoying. As this test is running in package
# main, loading modules at runtime might create entries in %::
# In this case, it's just one key, '_</.../lib/perl5/5.12.4/overload.pm'
# because Test::More is demand loading overload at the first test.
# So the first fix I tried was to "encourage" Test::More to get all this done
# before we start doing things that are sensitive to the size of %::
# with this:
#
# cmp_ok(1, '==', 1, "prompt Test::More to load everything it needs *now*");
#
# which fixed most things, but not 5.8.7, which (*only under make test*) would
# fail '&two_lex is bigger than an empty sub by less than 2048 bytes'
# Turns out that Test::More 0.54 creates an entry in %:: for every test run
# (not sure why, side effect of an eval with a #line directive, maybe?)
# The solution is to measure (and re-measure) the size of things you're
# comparing as contiguous statements, assigning to variables, and then make
# calls to Test::More functions.

sub zwapp;
sub swoosh($$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$);
sub crunch {
}

my $whack_size = total_size(\&whack);
my $zwapp_size = total_size(\&zwapp);
my $swoosh_size = total_size(\&swoosh);
my $crunch_size = total_size(\&crunch);

cmp_ok($whack_size, '>', 0, 'CV generated at runtime has a size');
if("$]" >= 5.017) {
    cmp_ok($zwapp_size, '==', $whack_size,
	   'CV stubbed at compiletime is the same size');
} else {
    cmp_ok($zwapp_size, '>', $whack_size,
	   'CV stubbed at compiletime is larger (CvOUTSIDE is set and followed)');
}
cmp_ok(length prototype \&swoosh, '>', 0, 'prototype has a length');
cmp_ok($swoosh_size, '>', $zwapp_size + length prototype \&swoosh,
       'prototypes add to the size');
cmp_ok($crunch_size, '>', $zwapp_size, 'sub bodies add to the size');

my $anon_proto = sub ($$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$) {};
my $anon_size = total_size(sub {});
my $anon_proto_size = total_size($anon_proto);
cmp_ok($anon_size, '>', 0, 'anonymous subroutines have a size');
cmp_ok(length prototype $anon_proto, '>', 0, 'prototype has a length');
cmp_ok($anon_proto_size, '>', $anon_size + length prototype $anon_proto,
       'prototypes add to the size');

SKIP: {
    use vars '@b';
    my $aelemfast_lex = total_size(sub {my @a; $a[0]});
    my $aelemfast = total_size(sub {my @a; $b[0]});

    # This one is sane even before Dave's lexical aelemfast changes:
    cmp_ok($aelemfast_lex, '>', $anon_size,
	   'aelemfast for a lexical is handled correctly');
    skip('alemfast was extended to lexicals after this perl was released', 1)
      if $] < 5.008004;
    cmp_ok($aelemfast, '>', $aelemfast_lex,
	   'aelemfast for a package variable is larger');
}

my $short_pvop = total_size(sub {goto GLIT});
my $long_pvop = total_size(sub {goto KREEK_KREEK_CLANK_CLANK});
cmp_ok($short_pvop, '>', $anon_size, 'OPc_PVOP can be measured');
is($long_pvop, $short_pvop + 19, 'the only size difference is the label length');

sub bloop {
    my $clunk = shift;
    if (--$clunk > 0) {
	bloop($clunk);
    }
}

my $before_size = total_size(\&bloop);
bloop(42);
my $after_size = total_size(\&bloop);

cmp_ok($after_size, '>', $before_size, 'Recursion increases the PADLIST');

sub closure_with_eval {
    my $a;
    return sub { eval ""; $a };
}

sub closure_without_eval {
    my $a;
    return sub { require ""; $a };
}

if ("$]" > 5.017001 && "$]" < 5.039004 || "$]" > 5.041007) {
    # Again relying too much on the core's implementation, but while that holds,
    # this does test that CvOUTSIDE() is being followed.
    cmp_ok(total_size(closure_with_eval()), '>',
	   total_size(closure_without_eval()) + 256,
	   'CvOUTSIDE is now NULL on cloned closures, unless they have eval');
} else {
    # Seems that they differ by a few bytes on 5.8.x
    cmp_ok(total_size(closure_with_eval()), '<=',
	   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.
}

# Aargh, re-measure it. See comment at the top of the file.
$crunch_size = total_size(\&crunch);
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');

# This is a copy of the simplest multiconcat test from t/opbasic/concat.t
# Like there, this is mostly intended for ASAN to hit:
sub multiconcat {
    my $s = chr 0x100;
    my $t = "\x80" x 1024;
    $s .= "-$t-";
    is(length($s), 1027, "utf8 dest with non-utf8 args");
}

multiconcat();
cmp_ok(total_size(\&multiconcat), '>', 1024,
       "pad constant makes this at least 1K");