Filename | /home/ss5/perl5/perlbrew/perls/perl-5.22.0/lib/site_perl/5.22.0/x86_64-linux/Class/MOP/Method/Wrapped.pm |
Statements | Executed 3410 statements in 16.6ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
43 | 1 | 1 | 7.16ms | 7.39ms | add_around_modifier | Class::MOP::Method::Wrapped::
296 | 1 | 1 | 4.52ms | 5.80ms | _wrapped_get_meta_instance | Class::MOP::Class::Immutable::Class::MOP::Class::
43 | 1 | 1 | 554µs | 1.22ms | wrap | Class::MOP::Method::Wrapped::
246 | 1 | 1 | 320µs | 599µs | _wrapped__method_map | Class::MOP::Class::Immutable::Class::MOP::Class::
86 | 2 | 1 | 158µs | 158µs | __ANON__[:65] | Class::MOP::Method::Wrapped::
43 | 1 | 1 | 153µs | 153µs | __ANON__[:166] | Class::MOP::Method::Wrapped::
43 | 1 | 1 | 136µs | 136µs | _new | Class::MOP::Method::Wrapped::
67 | 1 | 1 | 104µs | 291µs | _wrapped_linearized_isa | Class::MOP::Class::Immutable::Class::MOP::Class::
41 | 1 | 1 | 64µs | 822µs | _wrapped_get_all_attributes | Class::MOP::Class::Immutable::Class::MOP::Class::
23 | 1 | 1 | 41µs | 55µs | _wrapped_is_immutable | Class::MOP::Class::Immutable::Class::MOP::Class::
1 | 1 | 1 | 9µs | 10µs | BEGIN@4 | Class::MOP::Method::Wrapped::
1 | 1 | 1 | 5µs | 17µs | BEGIN@8 | Class::MOP::Method::Wrapped::
1 | 1 | 1 | 4µs | 18µs | BEGIN@10 | Class::MOP::Method::Wrapped::
1 | 1 | 1 | 4µs | 23µs | BEGIN@7 | Class::MOP::Method::Wrapped::
1 | 1 | 1 | 4µs | 7µs | BEGIN@5 | Class::MOP::Method::Wrapped::
0 | 0 | 0 | 0s | 0s | __ANON__[:164] | Class::MOP::Method::Wrapped::
0 | 0 | 0 | 0s | 0s | __ANON__[:39] | Class::MOP::Method::Wrapped::
0 | 0 | 0 | 0s | 0s | __ANON__[:45] | Class::MOP::Method::Wrapped::
0 | 0 | 0 | 0s | 0s | __ANON__[:60] | Class::MOP::Method::Wrapped::
0 | 0 | 0 | 0s | 0s | __ANON__[:96] | Class::MOP::Method::Wrapped::
0 | 0 | 0 | 0s | 0s | _make_compatible_with | Class::MOP::Method::Wrapped::
0 | 0 | 0 | 0s | 0s | add_after_modifier | Class::MOP::Method::Wrapped::
0 | 0 | 0 | 0s | 0s | add_before_modifier | Class::MOP::Method::Wrapped::
0 | 0 | 0 | 0s | 0s | after_modifiers | Class::MOP::Method::Wrapped::
0 | 0 | 0 | 0s | 0s | around_modifiers | Class::MOP::Method::Wrapped::
0 | 0 | 0 | 0s | 0s | before_modifiers | Class::MOP::Method::Wrapped::
0 | 0 | 0 | 0s | 0s | get_original_method | Class::MOP::Method::Wrapped::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | package Class::MOP::Method::Wrapped; | ||||
2 | 1 | 300ns | our $VERSION = '2.1605'; | ||
3 | |||||
4 | 2 | 14µs | 2 | 12µs | # spent 10µs (9+1) within Class::MOP::Method::Wrapped::BEGIN@4 which was called:
# once (9µs+1µs) by Class::MOP::Class::BEGIN@8 at line 4 # spent 10µs making 1 call to Class::MOP::Method::Wrapped::BEGIN@4
# spent 2µs making 1 call to strict::import |
5 | 2 | 13µs | 2 | 9µs | # spent 7µs (4+3) within Class::MOP::Method::Wrapped::BEGIN@5 which was called:
# once (4µs+3µs) by Class::MOP::Class::BEGIN@8 at line 5 # spent 7µs making 1 call to Class::MOP::Method::Wrapped::BEGIN@5
# spent 3µs making 1 call to warnings::import |
6 | |||||
7 | 2 | 15µs | 2 | 42µs | # spent 23µs (4+19) within Class::MOP::Method::Wrapped::BEGIN@7 which was called:
# once (4µs+19µs) by Class::MOP::Class::BEGIN@8 at line 7 # spent 23µs making 1 call to Class::MOP::Method::Wrapped::BEGIN@7
# spent 19µs making 1 call to Exporter::import |
8 | 2 | 15µs | 2 | 30µs | # spent 17µs (5+13) within Class::MOP::Method::Wrapped::BEGIN@8 which was called:
# once (5µs+13µs) by Class::MOP::Class::BEGIN@8 at line 8 # spent 17µs making 1 call to Class::MOP::Method::Wrapped::BEGIN@8
# spent 12µs making 1 call to Exporter::import |
9 | |||||
10 | 2 | 534µs | 2 | 32µs | # spent 18µs (4+14) within Class::MOP::Method::Wrapped::BEGIN@10 which was called:
# once (4µs+14µs) by Class::MOP::Class::BEGIN@8 at line 10 # spent 18µs making 1 call to Class::MOP::Method::Wrapped::BEGIN@10
# spent 14µs making 1 call to parent::import |
11 | |||||
12 | # NOTE: | ||||
13 | # this ugly beast is the result of trying | ||||
14 | # to micro optimize this as much as possible | ||||
15 | # while not completely loosing maintainability. | ||||
16 | # At this point it's "fast enough", after all | ||||
17 | # you can't get something for nothing :) | ||||
18 | # spent 158µs within Class::MOP::Method::Wrapped::__ANON__[/home/ss5/perl5/perlbrew/perls/perl-5.22.0/lib/site_perl/5.22.0/x86_64-linux/Class/MOP/Method/Wrapped.pm:65] which was called 86 times, avg 2µs/call:
# 43 times (84µs+0s) by Class::MOP::Method::Wrapped::wrap at line 86, avg 2µs/call
# 43 times (73µs+0s) by Class::MOP::Method::Wrapped::add_around_modifier at line 176, avg 2µs/call | ||||
19 | 86 | 11µs | my $modifier_table = shift; | ||
20 | my ($before, $after, $around) = ( | ||||
21 | $modifier_table->{before}, | ||||
22 | $modifier_table->{after}, | ||||
23 | $modifier_table->{around}, | ||||
24 | 86 | 37µs | ); | ||
25 | 86 | 162µs | if (@$before && @$after) { | ||
26 | $modifier_table->{cache} = sub { | ||||
27 | for my $c (@$before) { $c->(@_) }; | ||||
28 | my @rval; | ||||
29 | ((defined wantarray) ? | ||||
30 | ((wantarray) ? | ||||
31 | (@rval = $around->{cache}->(@_)) | ||||
32 | : | ||||
33 | ($rval[0] = $around->{cache}->(@_))) | ||||
34 | : | ||||
35 | $around->{cache}->(@_)); | ||||
36 | for my $c (@$after) { $c->(@_) }; | ||||
37 | return unless defined wantarray; | ||||
38 | return wantarray ? @rval : $rval[0]; | ||||
39 | } | ||||
40 | } | ||||
41 | elsif (@$before && !@$after) { | ||||
42 | $modifier_table->{cache} = sub { | ||||
43 | for my $c (@$before) { $c->(@_) }; | ||||
44 | return $around->{cache}->(@_); | ||||
45 | } | ||||
46 | } | ||||
47 | elsif (@$after && !@$before) { | ||||
48 | $modifier_table->{cache} = sub { | ||||
49 | my @rval; | ||||
50 | ((defined wantarray) ? | ||||
51 | ((wantarray) ? | ||||
52 | (@rval = $around->{cache}->(@_)) | ||||
53 | : | ||||
54 | ($rval[0] = $around->{cache}->(@_))) | ||||
55 | : | ||||
56 | $around->{cache}->(@_)); | ||||
57 | for my $c (@$after) { $c->(@_) }; | ||||
58 | return unless defined wantarray; | ||||
59 | return wantarray ? @rval : $rval[0]; | ||||
60 | } | ||||
61 | } | ||||
62 | else { | ||||
63 | 86 | 23µs | $modifier_table->{cache} = $around->{cache}; | ||
64 | } | ||||
65 | 1 | 2µs | }; | ||
66 | |||||
67 | # spent 1.22ms (554µs+663µs) within Class::MOP::Method::Wrapped::wrap which was called 43 times, avg 28µs/call:
# 43 times (554µs+663µs) by Class::MOP::Class::__ANON__[/home/ss5/perl5/perlbrew/perls/perl-5.22.0/lib/site_perl/5.22.0/x86_64-linux/Class/MOP/Class.pm:1082] at line 1068 of Class/MOP/Class.pm, avg 28µs/call | ||||
68 | 43 | 35µs | my ( $class, $code, %params ) = @_; | ||
69 | |||||
70 | 43 | 117µs | 86 | 24µs | (blessed($code) && $code->isa('Class::MOP::Method')) # spent 13µs making 43 calls to Scalar::Util::blessed, avg 307ns/call
# spent 10µs making 43 calls to UNIVERSAL::isa, avg 244ns/call |
71 | || $class->_throw_exception( CanOnlyWrapBlessedCode => params => \%params, | ||||
72 | class => $class, | ||||
73 | code => $code | ||||
74 | ); | ||||
75 | |||||
76 | 43 | 187µs | 86 | 18µs | my $modifier_table = { # spent 18µs making 86 calls to Class::MOP::Method::body, avg 208ns/call |
77 | cache => undef, | ||||
78 | orig => $code->body, | ||||
79 | before => [], | ||||
80 | after => [], | ||||
81 | around => { | ||||
82 | cache => $code->body, | ||||
83 | methods => [], | ||||
84 | }, | ||||
85 | }; | ||||
86 | 43 | 31µs | 43 | 84µs | $_build_wrapped_method->($modifier_table); # spent 84µs making 43 calls to Class::MOP::Method::Wrapped::__ANON__[Class/MOP/Method/Wrapped.pm:65], avg 2µs/call |
87 | |||||
88 | # get these from the original unless explicitly overridden | ||||
89 | 43 | 15µs | my $pkg_name = $params{package_name} || $code->package_name; | ||
90 | 43 | 10µs | my $method_name = $params{name} || $code->name; | ||
91 | |||||
92 | return $class->SUPER::wrap( | ||||
93 | sub { | ||||
94 | 673 | 2.56ms | 673 | 1.66ms | my $wrapped = subname "${pkg_name}::_wrapped_${method_name}" => $modifier_table->{cache}; # spent 1.66ms making 673 calls to Sub::Name::subname, avg 2µs/call |
95 | 673 | 1.00ms | 673 | 7.57ms | return $wrapped->(@_) ; # spent 5.80ms making 296 calls to Class::MOP::Class::Immutable::Class::MOP::Class::_wrapped_get_meta_instance, avg 20µs/call
# spent 822µs making 41 calls to Class::MOP::Class::Immutable::Class::MOP::Class::_wrapped_get_all_attributes, avg 20µs/call
# spent 599µs making 246 calls to Class::MOP::Class::Immutable::Class::MOP::Class::_wrapped__method_map, avg 2µs/call
# spent 291µs making 67 calls to Class::MOP::Class::Immutable::Class::MOP::Class::_wrapped_linearized_isa, avg 4µs/call
# spent 55µs making 23 calls to Class::MOP::Class::Immutable::Class::MOP::Class::_wrapped_is_immutable, avg 2µs/call |
96 | }, | ||||
97 | 43 | 183µs | 43 | 537µs | package_name => $pkg_name, # spent 537µs making 43 calls to Class::MOP::Method::wrap, avg 12µs/call |
98 | name => $method_name, | ||||
99 | original_method => $code, | ||||
100 | modifier_table => $modifier_table, | ||||
101 | ); | ||||
102 | } | ||||
103 | |||||
104 | # spent 136µs within Class::MOP::Method::Wrapped::_new which was called 43 times, avg 3µs/call:
# 43 times (136µs+0s) by Class::MOP::Method::wrap at line 49 of Class/MOP/Method.pm, avg 3µs/call | ||||
105 | 43 | 8µs | my $class = shift; | ||
106 | 43 | 10µs | return Class::MOP::Class->initialize($class)->new_object(@_) | ||
107 | if $class ne __PACKAGE__; | ||||
108 | |||||
109 | 43 | 12µs | my $params = @_ == 1 ? $_[0] : {@_}; | ||
110 | |||||
111 | return bless { | ||||
112 | # inherited from Class::MOP::Method | ||||
113 | 'body' => $params->{body}, | ||||
114 | 'associated_metaclass' => $params->{associated_metaclass}, | ||||
115 | 'package_name' => $params->{package_name}, | ||||
116 | 'name' => $params->{name}, | ||||
117 | 'original_method' => $params->{original_method}, | ||||
118 | |||||
119 | # defined in this class | ||||
120 | 'modifier_table' => $params->{modifier_table} | ||||
121 | 43 | 128µs | } => $class; | ||
122 | } | ||||
123 | |||||
124 | sub get_original_method { | ||||
125 | my $code = shift; | ||||
126 | $code->original_method; | ||||
127 | } | ||||
128 | |||||
129 | sub add_before_modifier { | ||||
130 | my $code = shift; | ||||
131 | my $modifier = shift; | ||||
132 | unshift @{$code->{'modifier_table'}->{before}} => $modifier; | ||||
133 | $_build_wrapped_method->($code->{'modifier_table'}); | ||||
134 | } | ||||
135 | |||||
136 | sub before_modifiers { | ||||
137 | my $code = shift; | ||||
138 | return @{$code->{'modifier_table'}->{before}}; | ||||
139 | } | ||||
140 | |||||
141 | sub add_after_modifier { | ||||
142 | my $code = shift; | ||||
143 | my $modifier = shift; | ||||
144 | push @{$code->{'modifier_table'}->{after}} => $modifier; | ||||
145 | $_build_wrapped_method->($code->{'modifier_table'}); | ||||
146 | } | ||||
147 | |||||
148 | sub after_modifiers { | ||||
149 | my $code = shift; | ||||
150 | return @{$code->{'modifier_table'}->{after}}; | ||||
151 | } | ||||
152 | |||||
153 | { | ||||
154 | # NOTE: | ||||
155 | # this is another possible candidate for | ||||
156 | # optimization as well. There is an overhead | ||||
157 | # associated with the currying that, if | ||||
158 | # eliminated might make around modifiers | ||||
159 | # more manageable. | ||||
160 | # spent 153µs within Class::MOP::Method::Wrapped::__ANON__[/home/ss5/perl5/perlbrew/perls/perl-5.22.0/lib/site_perl/5.22.0/x86_64-linux/Class/MOP/Method/Wrapped.pm:166] which was called 43 times, avg 4µs/call:
# 43 times (153µs+0s) by Class::MOP::Method::Wrapped::add_around_modifier at line 175, avg 4µs/call | ||||
161 | 129 | 22µs | my $f1 = pop; | ||
162 | 86 | 6.99ms | return $f1 unless @_; | ||
163 | 43 | 7µs | my $f2 = pop; | ||
164 | 716 | 4.23ms | 673 | 2.52ms | # spent 5.80ms (4.52+1.28) within Class::MOP::Class::Immutable::Class::MOP::Class::_wrapped_get_meta_instance which was called 296 times, avg 20µs/call:
# 296 times (4.52ms+1.28ms) by Class::MOP::Class::Immutable::Class::MOP::Class::get_meta_instance at line 95, avg 20µs/call
# spent 55µs (41+14) within Class::MOP::Class::Immutable::Class::MOP::Class::_wrapped_is_immutable which was called 23 times, avg 2µs/call:
# 23 times (41µs+14µs) by Class::MOP::Class::Immutable::Class::MOP::Class::is_immutable at line 95, avg 2µs/call
# spent 822µs (64+758) within Class::MOP::Class::Immutable::Class::MOP::Class::_wrapped_get_all_attributes which was called 41 times, avg 20µs/call:
# 41 times (64µs+758µs) by Class::MOP::Class::Immutable::Class::MOP::Class::get_all_attributes at line 95, avg 20µs/call
# spent 291µs (104+188) within Class::MOP::Class::Immutable::Class::MOP::Class::_wrapped_linearized_isa which was called 67 times, avg 4µs/call:
# 67 times (104µs+188µs) by Class::MOP::Class::Immutable::Class::MOP::Class::linearized_isa at line 95, avg 4µs/call
# spent 599µs (320+279) within Class::MOP::Class::Immutable::Class::MOP::Class::_wrapped__method_map which was called 246 times, avg 2µs/call:
# 246 times (320µs+279µs) by Class::MOP::Class::Immutable::Class::MOP::Class::_method_map at line 95, avg 2µs/call # spent 2.52ms making 673 calls to Class::MOP::Class:::around, avg 4µs/call |
165 | 43 | 10µs | redo; | ||
166 | 1 | 1µs | }}; | ||
167 | |||||
168 | # spent 7.39ms (7.16+226µs) within Class::MOP::Method::Wrapped::add_around_modifier which was called 43 times, avg 172µs/call:
# 43 times (7.16ms+226µs) by Class::MOP::Class::add_around_method_modifier at line 1109 of Class/MOP/Class.pm, avg 172µs/call | ||||
169 | 43 | 6µs | my $code = shift; | ||
170 | 43 | 5µs | my $modifier = shift; | ||
171 | 43 | 35µs | unshift @{$code->{'modifier_table'}->{around}->{methods}} => $modifier; | ||
172 | $code->{'modifier_table'}->{around}->{cache} = $compile_around_method->( | ||||
173 | @{$code->{'modifier_table'}->{around}->{methods}}, | ||||
174 | $code->{'modifier_table'}->{orig} | ||||
175 | 43 | 85µs | 43 | 153µs | ); # spent 153µs making 43 calls to Class::MOP::Method::Wrapped::__ANON__[Class/MOP/Method/Wrapped.pm:166], avg 4µs/call |
176 | 43 | 79µs | 43 | 73µs | $_build_wrapped_method->($code->{'modifier_table'}); # spent 73µs making 43 calls to Class::MOP::Method::Wrapped::__ANON__[Class/MOP/Method/Wrapped.pm:65], avg 2µs/call |
177 | } | ||||
178 | } | ||||
179 | |||||
180 | 1 | 200ns | sub around_modifiers { | ||
181 | my $code = shift; | ||||
182 | return @{$code->{'modifier_table'}->{around}->{methods}}; | ||||
183 | } | ||||
184 | |||||
185 | sub _make_compatible_with { | ||||
186 | my $self = shift; | ||||
187 | my ($other) = @_; | ||||
188 | |||||
189 | # XXX: this is pretty gross. the issue here is that CMOP::Method::Wrapped | ||||
190 | # objects are subclasses of CMOP::Method, but when we get to moose, they'll | ||||
191 | # need to be compatible with Moose::Meta::Method, which isn't possible. the | ||||
192 | # right solution here is to make ::Wrapped into a role that gets applied to | ||||
193 | # whatever the method_metaclass happens to be and get rid of | ||||
194 | # wrapped_method_metaclass entirely, but that's not going to happen until | ||||
195 | # we ditch cmop and get roles into the bootstrapping, so. i'm not | ||||
196 | # maintaining the previous behavior of turning them into instances of the | ||||
197 | # new method_metaclass because that's equally broken, and at least this way | ||||
198 | # any issues will at least be detectable and potentially fixable. -doy | ||||
199 | return $self unless $other->_is_compatible_with($self->_real_ref_name); | ||||
200 | |||||
201 | return $self->SUPER::_make_compatible_with(@_); | ||||
202 | } | ||||
203 | |||||
204 | 1 | 3µs | 1; | ||
205 | |||||
206 | # ABSTRACT: Method Meta Object for methods with before/after/around modifiers | ||||
207 | |||||
208 | __END__ |