Profile of Devel/StackTrace.pm

← Index
NYTProf Performance Profile «line view»
For t/optimization.t
Run on Thu Jan 8 22:47:42 2015
Reported on Thu Jan 8 22:48:06 2015

Filename | /home/ss5/perl5/perlbrew/perls/tapper-perl/lib/site_perl/5.16.3/Devel/StackTrace.pm
Statements | Executed 20 statements in 1.43ms

Subroutines
Calls | P | F | Exclusive Time | Inclusive Time | Subroutine
--- | --- | --- | --- | --- | ---
1 | 1 | 1 | 1.88ms | 2.04ms | Devel::StackTrace::::BEGIN@12Devel::StackTrace::BEGIN@12
1 | 1 | 1 | 788µs | 888µs | Devel::StackTrace::::BEGIN@11Devel::StackTrace::BEGIN@11
1 | 1 | 1 | 17µs | 17µs | Devel::StackTrace::::BEGIN@6Devel::StackTrace::BEGIN@6
1 | 1 | 1 | 13µs | 53µs | Devel::StackTrace::::BEGIN@16Devel::StackTrace::BEGIN@16
1 | 1 | 1 | 11µs | 26µs | Devel::StackTrace::::BEGIN@8Devel::StackTrace::BEGIN@8
1 | 1 | 1 | 11µs | 44µs | Devel::StackTrace::::BEGIN@13Devel::StackTrace::BEGIN@13
1 | 1 | 1 | 10µs | 14µs | Devel::StackTrace::::BEGIN@9Devel::StackTrace::BEGIN@9
0 | 0 | 0 | 0s | 0s | Devel::StackTrace::::__ANON__[:105]Devel::StackTrace::__ANON__[:105]
0 | 0 | 0 | 0s | 0s | Devel::StackTrace::::__ANON__[:142]Devel::StackTrace::__ANON__[:142]
0 | 0 | 0 | 0s | 0s | Devel::StackTrace::::_add_frameDevel::StackTrace::_add_frame
0 | 0 | 0 | 0s | 0s | Devel::StackTrace::::_make_frame_filterDevel::StackTrace::_make_frame_filter
0 | 0 | 0 | 0s | 0s | Devel::StackTrace::::_make_framesDevel::StackTrace::_make_frames
0 | 0 | 0 | 0s | 0s | Devel::StackTrace::::_record_caller_dataDevel::StackTrace::_record_caller_data
0 | 0 | 0 | 0s | 0s | Devel::StackTrace::::_ref_to_stringDevel::StackTrace::_ref_to_string
0 | 0 | 0 | 0s | 0s | Devel::StackTrace::::as_stringDevel::StackTrace::as_string
0 | 0 | 0 | 0s | 0s | Devel::StackTrace::::frameDevel::StackTrace::frame
0 | 0 | 0 | 0s | 0s | Devel::StackTrace::::frame_countDevel::StackTrace::frame_count
0 | 0 | 0 | 0s | 0s | Devel::StackTrace::::framesDevel::StackTrace::frames
0 | 0 | 0 | 0s | 0s | Devel::StackTrace::::newDevel::StackTrace::new
0 | 0 | 0 | 0s | 0s | Devel::StackTrace::::next_frameDevel::StackTrace::next_frame
0 | 0 | 0 | 0s | 0s | Devel::StackTrace::::prev_frameDevel::StackTrace::prev_frame
0 | 0 | 0 | 0s | 0s | Devel::StackTrace::::reset_pointerDevel::StackTrace::reset_pointer

Call graph for these subroutines as a Graphviz dot language file.

Line | State ments | Time on line | Calls | Time in subs | Code
--- | --- | --- | --- | --- | ---
1 |  |  |  |  | package Devel::StackTrace;
2 |  |  |  |  | {
3 | 2 | 1µs |  |  | $Devel::StackTrace::VERSION = '1.30';
4 |  |  |  |  | }
5 |  |  |  |  |
6 | 2 | 52µs | 1 | 17µs | # spent 17µs within Devel::StackTrace::BEGIN@6 which was called: # once (17µs+0s) by Exception::Class::Base::BEGIN@10 at line 6 use 5.006; # spent 17µs making 1 call to Devel::StackTrace::BEGIN@6
7 |  |  |  |  |
8 | 2 | 27µs | 2 | 40µs | # spent 26µs (11+14) within Devel::StackTrace::BEGIN@8 which was called: # once (11µs+14µs) by Exception::Class::Base::BEGIN@10 at line 8 use strict; # spent 26µs making 1 call to Devel::StackTrace::BEGIN@8 # spent 14µs making 1 call to strict::import
9 | 2 | 23µs | 2 | 19µs | # spent 14µs (10+5) within Devel::StackTrace::BEGIN@9 which was called: # once (10µs+5µs) by Exception::Class::Base::BEGIN@10 at line 9 use warnings; # spent 14µs making 1 call to Devel::StackTrace::BEGIN@9 # spent 5µs making 1 call to warnings::import
10 |  |  |  |  |
11 | 2 | 111µs | 1 | 888µs | # spent 888µs (788+100) within Devel::StackTrace::BEGIN@11 which was called: # once (788µs+100µs) by Exception::Class::Base::BEGIN@10 at line 11 use Devel::StackTrace::Frame; # spent 888µs making 1 call to Devel::StackTrace::BEGIN@11
12 | 2 | 108µs | 1 | 2.04ms | # spent 2.04ms (1.88+160µs) within Devel::StackTrace::BEGIN@12 which was called: # once (1.88ms+160µs) by Exception::Class::Base::BEGIN@10 at line 12 use File::Spec; # spent 2.04ms making 1 call to Devel::StackTrace::BEGIN@12
13 | 2 | 39µs | 2 | 78µs | # spent 44µs (11+33) within Devel::StackTrace::BEGIN@13 which was called: # once (11µs+33µs) by Exception::Class::Base::BEGIN@10 at line 13 use Scalar::Util qw( blessed ); # spent 44µs making 1 call to Devel::StackTrace::BEGIN@13 # spent 33µs making 1 call to Exporter::import
14 |  |  |  |  |
15 |  |  |  |  | use overload
16 | 1 | 11µs | 1 | 40µs | # spent 53µs (13+40) within Devel::StackTrace::BEGIN@16 which was called: # once (13µs+40µs) by Exception::Class::Base::BEGIN@10 at line 17 '""' => \&as_string, # spent 40µs making 1 call to overload::import
17 | 1 | 1.04ms | 1 | 53µs | fallback => 1; # spent 53µs making 1 call to Devel::StackTrace::BEGIN@16
18 |  |  |  |  |
19 |  |  |  |  | sub new {
20 |  |  |  |  | my $class = shift;
21 |  |  |  |  | my %p = @_;
22 |  |  |  |  |
23 |  |  |  |  | # Backwards compatibility - this parameter was renamed to no_refs
24 |  |  |  |  | # ages ago.
25 |  |  |  |  | $p{no_refs} = delete $p{no_object_refs}
26 |  |  |  |  | if exists $p{no_object_refs};
27 |  |  |  |  |
28 |  |  |  |  | my $self = bless {
29 |  |  |  |  | index => undef,
30 |  |  |  |  | frames => [],
31 |  |  |  |  | raw => [],
32 |  |  |  |  | %p,
33 |  |  |  |  | }, $class;
34 |  |  |  |  |
35 |  |  |  |  | $self->_record_caller_data();
36 |  |  |  |  |
37 |  |  |  |  | return $self;
38 |  |  |  |  | }
39 |  |  |  |  |
40 |  |  |  |  | sub _record_caller_data {
41 |  |  |  |  | my $self = shift;
42 |  |  |  |  |
43 |  |  |  |  | # We exclude this method by starting one frame back.
44 |  |  |  |  | my $x = 1;
45 |  |  |  |  | while (
46 |  |  |  |  | my @c
47 |  |  |  |  | = $self->{no_args}
48 |  |  |  |  | ? caller( $x++ )
49 |  |  |  |  | : do {
50 |  |  |  |  | package # the newline keeps dzil from adding a version here
51 |  |  |  |  | DB;
52 |  |  |  |  |
- - |  |  |  |  |
55 |  |  |  |  | ) {
56 |  |  |  |  |
57 |  |  |  |  | my @args;
58 |  |  |  |  |
59 |  |  |  |  | unless ( $self->{no_args} ) {
60 |  |  |  |  | @args = @DB::args;
61 |  |  |  |  |
62 |  |  |  |  | if ( $self->{no_refs} ) {
63 |  |  |  |  | @args = map { ref $_ ? $self->_ref_to_string($_) : $_ } @args;
64 |  |  |  |  | }
65 |  |  |  |  | }
66 |  |  |  |  |
67 |  |  |  |  | push @{ $self->{raw} },
68 |  |  |  |  | {
69 |  |  |  |  | caller => \@c,
70 |  |  |  |  | args => \@args,
71 |  |  |  |  | };
72 |  |  |  |  | }
73 |  |  |  |  | }
74 |  |  |  |  |
75 |  |  |  |  | sub _ref_to_string {
76 |  |  |  |  | my $self = shift;
77 |  |  |  |  | my $ref = shift;
78 |  |  |  |  |
79 |  |  |  |  | return overload::AddrRef($ref)
80 |  |  |  |  | if blessed $ref && $ref->isa('Exception::Class::Base');
81 |  |  |  |  |
82 |  |  |  |  | return overload::AddrRef($ref) unless $self->{respect_overload};
83 |  |  |  |  |
84 |  |  |  |  | local $@;
85 |  |  |  |  | local $SIG{__DIE__};
86 |  |  |  |  |
87 |  |  |  |  | my $str = eval { $ref . '' };
88 |  |  |  |  |
89 |  |  |  |  | return $@ ? overload::AddrRef($ref) : $str;
90 |  |  |  |  | }
91 |  |  |  |  |
92 |  |  |  |  | sub _make_frames {
93 |  |  |  |  | my $self = shift;
94 |  |  |  |  |
95 |  |  |  |  | my $filter = $self->_make_frame_filter;
96 |  |  |  |  |
97 |  |  |  |  | my $raw = delete $self->{raw};
98 |  |  |  |  | for my $r ( @{$raw} ) {
99 |  |  |  |  | next unless $filter->($r);
100 |  |  |  |  |
101 |  |  |  |  | $self->_add_frame( $r->{caller}, $r->{args} );
102 |  |  |  |  | }
103 |  |  |  |  | }
104 |  |  |  |  |
105 | 1 | 2µs |  |  | my $default_filter = sub { 1 };
106 |  |  |  |  |
107 |  |  |  |  | sub _make_frame_filter {
108 |  |  |  |  | my $self = shift;
109 |  |  |  |  |
110 |  |  |  |  | my ( @i_pack_re, %i_class );
111 |  |  |  |  | if ( $self->{ignore_package} ) {
112 |  |  |  |  | local $@;
113 |  |  |  |  | local $SIG{__DIE__};
114 |  |  |  |  |
115 |  |  |  |  | $self->{ignore_package} = [ $self->{ignore_package} ]
116 |  |  |  |  | unless eval { @{ $self->{ignore_package} } };
117 |  |  |  |  |
118 |  |  |  |  | @i_pack_re
119 |  |  |  |  | = map { ref $_ ? $_ : qr/^\Q$_\E$/ } @{ $self->{ignore_package} };
120 |  |  |  |  | }
121 |  |  |  |  |
122 |  |  |  |  | my $p = __PACKAGE__;
123 |  |  |  |  | push @i_pack_re, qr/^\Q$p\E$/;
124 |  |  |  |  |
125 |  |  |  |  | if ( $self->{ignore_class} ) {
126 |  |  |  |  | $self->{ignore_class} = [ $self->{ignore_class} ]
127 |  |  |  |  | unless ref $self->{ignore_class};
128 |  |  |  |  | %i_class = map { $_ => 1 } @{ $self->{ignore_class} };
129 |  |  |  |  | }
130 |  |  |  |  |
131 |  |  |  |  | my $user_filter = $self->{frame_filter};
132 |  |  |  |  |
133 |  |  |  |  | return sub {
134 |  |  |  |  | return 0 if grep { $_[0]{caller}[0] =~ /$_/ } @i_pack_re;
135 |  |  |  |  | return 0 if grep { $_[0]{caller}[0]->isa($_) } keys %i_class;
136 |  |  |  |  |
137 |  |  |  |  | if ($user_filter) {
138 |  |  |  |  | return $user_filter->( $_[0] );
139 |  |  |  |  | }
140 |  |  |  |  |
141 |  |  |  |  | return 1;
142 |  |  |  |  | };
143 |  |  |  |  | }
144 |  |  |  |  |
145 |  |  |  |  | sub _add_frame {
146 |  |  |  |  | my $self = shift;
147 |  |  |  |  | my $c = shift;
148 |  |  |  |  | my $p = shift;
149 |  |  |  |  |
150 |  |  |  |  | # eval and is_require are only returned when applicable under 5.00503.
151 |  |  |  |  | push @$c, ( undef, undef ) if scalar @$c == 6;
152 |  |  |  |  |
153 |  |  |  |  | push @{ $self->{frames} },
154 |  |  |  |  | Devel::StackTrace::Frame->new(
155 |  |  |  |  | $c,
156 |  |  |  |  | $p,
157 |  |  |  |  | $self->{respect_overload},
158 |  |  |  |  | $self->{max_arg_length},
159 |  |  |  |  | $self->{message},
160 |  |  |  |  | $self->{indent}
161 |  |  |  |  | );
162 |  |  |  |  | }
163 |  |  |  |  |
164 |  |  |  |  | sub next_frame {
165 |  |  |  |  | my $self = shift;
166 |  |  |  |  |
167 |  |  |  |  | # reset to top if necessary.
168 |  |  |  |  | $self->{index} = -1 unless defined $self->{index};
169 |  |  |  |  |
170 |  |  |  |  | my @f = $self->frames();
171 |  |  |  |  | if ( defined $f[ $self->{index} + 1 ] ) {
172 |  |  |  |  | return $f[ ++$self->{index} ];
173 |  |  |  |  | }
174 |  |  |  |  | else {
175 |  |  |  |  | $self->{index} = undef;
176 |  |  |  |  | return undef;
177 |  |  |  |  | }
178 |  |  |  |  | }
179 |  |  |  |  |
180 |  |  |  |  | sub prev_frame {
181 |  |  |  |  | my $self = shift;
182 |  |  |  |  |
183 |  |  |  |  | my @f = $self->frames();
184 |  |  |  |  |
185 |  |  |  |  | # reset to top if necessary.
186 |  |  |  |  | $self->{index} = scalar @f unless defined $self->{index};
187 |  |  |  |  |
188 |  |  |  |  | if ( defined $f[ $self->{index} - 1 ] && $self->{index} >= 1 ) {
189 |  |  |  |  | return $f[ --$self->{index} ];
190 |  |  |  |  | }
191 |  |  |  |  | else {
192 |  |  |  |  | $self->{index} = undef;
193 |  |  |  |  | return undef;
194 |  |  |  |  | }
195 |  |  |  |  | }
196 |  |  |  |  |
197 |  |  |  |  | sub reset_pointer {
198 |  |  |  |  | my $self = shift;
199 |  |  |  |  |
200 |  |  |  |  | $self->{index} = undef;
201 |  |  |  |  | }
202 |  |  |  |  |
203 |  |  |  |  | sub frames {
204 |  |  |  |  | my $self = shift;
205 |  |  |  |  |
206 |  |  |  |  | if (@_) {
207 |  |  |  |  | die
208 |  |  |  |  | "Devel::StackTrace->frames() can only take Devel::StackTrace::Frame args\n"
209 |  |  |  |  | if grep { !$_->isa('Devel::StackTrace::Frame') } @_;
210 |  |  |  |  |
211 |  |  |  |  | $self->{frames} = \@_;
212 |  |  |  |  | }
213 |  |  |  |  | else {
214 |  |  |  |  | $self->_make_frames() if $self->{raw};
215 |  |  |  |  | }
216 |  |  |  |  |
217 |  |  |  |  | return @{ $self->{frames} };
218 |  |  |  |  | }
219 |  |  |  |  |
220 |  |  |  |  | sub frame {
221 |  |  |  |  | my $self = shift;
222 |  |  |  |  | my $i = shift;
223 |  |  |  |  |
224 |  |  |  |  | return unless defined $i;
225 |  |  |  |  |
226 |  |  |  |  | return ( $self->frames() )[$i];
227 |  |  |  |  | }
228 |  |  |  |  |
229 |  |  |  |  | sub frame_count {
230 |  |  |  |  | my $self = shift;
231 |  |  |  |  |
232 |  |  |  |  | return scalar( $self->frames() );
233 |  |  |  |  | }
234 |  |  |  |  |
235 |  |  |  |  | sub as_string {
236 |  |  |  |  | my $self = shift;
237 |  |  |  |  | my $p = shift;
238 |  |  |  |  |
239 |  |  |  |  | my $st = '';
240 |  |  |  |  | my $first = 1;
241 |  |  |  |  | foreach my $f ( $self->frames() ) {
242 |  |  |  |  | $st .= $f->as_string( $first, $p ) . "\n";
243 |  |  |  |  | $first = 0;
244 |  |  |  |  | }
245 |  |  |  |  |
246 |  |  |  |  | return $st;
247 |  |  |  |  | }
248 |  |  |  |  |
249 |  |  |  |  | {
250 | 1 | 300ns |  |  | package
251 |  |  |  |  | Devel::StackTraceFrame;
252 |  |  |  |  |
253 | 1 | 7µs |  |  | our @ISA = 'Devel::StackTrace::Frame';
254 |  |  |  |  | }
255 |  |  |  |  |
256 | 1 | 6µs |  |  | 1;
257 |  |  |  |  |
258 |  |  |  |  | # ABSTRACT: An object representing a stack trace
259 |  |  |  |  |
260 |  |  |  |  | __END__