Filename | /usr/local/share/perl/5.18.2/Moo.pm |
Statements | Executed 294 statements in 3.30ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
11 | 2 | 1 | 5.37ms | 10.2ms | _accessor_maker_for | Moo::
10 | 2 | 2 | 2.45ms | 22.2ms | _constructor_maker_for (recurses: max depth 1, inclusive time 10.5ms) | Moo::
1 | 1 | 1 | 2.27ms | 16.2ms | BEGIN@4 | Moo::
1 | 1 | 1 | 1.60ms | 2.17ms | around | Moo::
2 | 2 | 2 | 864µs | 1.39ms | import | Moo::
1 | 1 | 1 | 215µs | 294µs | BEGIN@3 | Moo::
7 | 7 | 1 | 211µs | 24.2ms | has | Moo::
12 | 4 | 1 | 67µs | 305µs | _install_tracked | Moo::
9 | 1 | 1 | 21µs | 21µs | _maybe_reset_handlemoose | Moo::
1 | 1 | 1 | 12µs | 25µs | BEGIN@112 | Moo::
1 | 1 | 1 | 9µs | 25µs | BEGIN@76 | Moo::
0 | 0 | 0 | 0s | 0s | __ANON__[:198] | Moo::
0 | 0 | 0 | 0s | 0s | __ANON__[:206] | Moo::
0 | 0 | 0 | 0s | 0s | __ANON__[:36] | Moo::
0 | 0 | 0 | 0s | 0s | __ANON__[:41] | Moo::
0 | 0 | 0 | 0s | 0s | __ANON__[:62] | Moo::
0 | 0 | 0 | 0s | 0s | __ANON__[:68] | Moo::
0 | 0 | 0 | 0s | 0s | _concrete_methods_of | Moo::
0 | 0 | 0 | 0s | 0s | _set_superclasses | Moo::
0 | 0 | 0 | 0s | 0s | after | Moo::
0 | 0 | 0 | 0s | 0s | before | Moo::
0 | 0 | 0 | 0s | 0s | extends | Moo::
0 | 0 | 0 | 0s | 0s | unimport | Moo::
0 | 0 | 0 | 0s | 0s | with | Moo::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | package Moo; | ||||
2 | |||||
3 | 2 | 101µs | 2 | 324µs | # spent 294µs (215+78) within Moo::BEGIN@3 which was called:
# once (215µs+78µs) by String::Markov::BEGIN@8 at line 3 # spent 294µs making 1 call to Moo::BEGIN@3
# spent 31µs making 1 call to Moo::_strictures::import |
4 | 2 | 710µs | 2 | 16.3ms | # spent 16.2ms (2.27+14.0) within Moo::BEGIN@4 which was called:
# once (2.27ms+14.0ms) by String::Markov::BEGIN@8 at line 4 # spent 16.2ms making 1 call to Moo::BEGIN@4
# spent 80µs making 1 call to Exporter::import |
5 | |||||
6 | 1 | 800ns | our $VERSION = '2.001000'; | ||
7 | 1 | 63µs | $VERSION = eval $VERSION; # spent 3µs executing statements in string eval | ||
8 | |||||
9 | 1 | 82µs | require Moo::sification; | ||
10 | 1 | 7µs | 1 | 5µs | Moo::sification->import; # spent 5µs making 1 call to Moo::sification::import |
11 | |||||
12 | 1 | 400ns | our %MAKERS; | ||
13 | |||||
14 | # spent 305µs (67+239) within Moo::_install_tracked which was called 12 times, avg 25µs/call:
# 6 times (28µs+99µs) by Moo::import at line 68, avg 21µs/call
# 2 times (17µs+74µs) by Moo::import at line 36, avg 46µs/call
# 2 times (11µs+34µs) by Moo::import at line 41, avg 23µs/call
# 2 times (10µs+32µs) by Moo::import at line 62, avg 21µs/call | ||||
15 | 12 | 8µs | my ($target, $name, $code) = @_; | ||
16 | 12 | 16µs | $MAKERS{$target}{exports}{$name} = $code; | ||
17 | 12 | 42µs | 12 | 239µs | _install_coderef "${target}::${name}" => "Moo::${name}" => $code; # spent 239µs making 12 calls to Moo::_Utils::_install_coderef, avg 20µs/call |
18 | } | ||||
19 | |||||
20 | # spent 1.39ms (864µs+528µs) within Moo::import which was called 2 times, avg 696µs/call:
# once (770µs+311µs) by String::Markov::BEGIN@8 at line 8 of String/Markov.pm
# once (94µs+216µs) by Method::Generate::Constructor::BEGIN@8 at line 8 of Method/Generate/Constructor.pm | ||||
21 | 2 | 2µs | my $target = caller; | ||
22 | 2 | 1µs | my $class = shift; | ||
23 | 2 | 5µs | 2 | 108µs | _set_loaded(caller); # spent 108µs making 2 calls to Moo::_Utils::_set_loaded, avg 54µs/call |
24 | |||||
25 | 2 | 4µs | 2 | 29µs | strict->import; # spent 29µs making 2 calls to strict::import, avg 14µs/call |
26 | 2 | 4µs | 2 | 12µs | warnings->import; # spent 12µs making 2 calls to warnings::import, avg 6µs/call |
27 | |||||
28 | 2 | 1µs | if ($INC{'Role/Tiny.pm'} and Role::Tiny->is_role($target)) { | ||
29 | die "Cannot import Moo into a role"; | ||||
30 | } | ||||
31 | 2 | 3µs | $MAKERS{$target} ||= {}; | ||
32 | _install_tracked $target => extends => sub { | ||||
33 | $class->_set_superclasses($target, @_); | ||||
34 | $class->_maybe_reset_handlemoose($target); | ||||
35 | return; | ||||
36 | 2 | 11µs | 2 | 91µs | }; # spent 91µs making 2 calls to Moo::_install_tracked, avg 46µs/call |
37 | _install_tracked $target => with => sub { | ||||
38 | require Moo::Role; | ||||
39 | Moo::Role->apply_roles_to_package($target, @_); | ||||
40 | $class->_maybe_reset_handlemoose($target); | ||||
41 | 2 | 9µs | 2 | 45µs | }; # spent 45µs making 2 calls to Moo::_install_tracked, avg 23µs/call |
42 | # spent 24.2ms (211µs+24.0) within Moo::has which was called 7 times, avg 3.45ms/call:
# once (36µs+22.5ms) by main::BEGIN@7 at line 14 of String/Markov.pm
# once (46µs+380µs) by main::BEGIN@7 at line 31 of String/Markov.pm
# once (40µs+344µs) by main::BEGIN@7 at line 25 of String/Markov.pm
# once (25µs+205µs) by main::BEGIN@7 at line 16 of String/Markov.pm
# once (21µs+189µs) by main::BEGIN@7 at line 20 of String/Markov.pm
# once (22µs+186µs) by main::BEGIN@7 at line 17 of String/Markov.pm
# once (24µs+184µs) by main::BEGIN@7 at line 15 of String/Markov.pm | ||||
43 | 7 | 5µs | my $name_proto = shift; | ||
44 | 7 | 9µs | my @name_proto = ref $name_proto eq 'ARRAY' ? @$name_proto : $name_proto; | ||
45 | 7 | 6µs | if (@_ % 2 != 0) { | ||
46 | require Carp; | ||||
47 | Carp::croak("Invalid options for " . join(', ', map "'$_'", @name_proto) | ||||
48 | . " attribute(s): even number of arguments expected, got " . scalar @_) | ||||
49 | } | ||||
50 | 7 | 12µs | my %spec = @_; | ||
51 | 7 | 6µs | foreach my $name (@name_proto) { | ||
52 | # Note that when multiple attributes specified, each attribute | ||||
53 | # needs a separate \%specs hashref | ||||
54 | 9 | 16µs | my $spec_ref = @name_proto > 1 ? +{%spec} : \%spec; | ||
55 | 9 | 34µs | 18 | 22.5ms | $class->_constructor_maker_for($target) # spent 22.2ms making 9 calls to Moo::_constructor_maker_for, avg 2.47ms/call
# spent 246µs making 9 calls to Method::Generate::Constructor::register_attribute_specs, avg 27µs/call |
56 | ->register_attribute_specs($name, $spec_ref); | ||||
57 | 9 | 35µs | 18 | 1.46ms | $class->_accessor_maker_for($target) # spent 1.43ms making 9 calls to Method::Generate::Accessor::generate_method, avg 159µs/call
# spent 26µs making 9 calls to Moo::_accessor_maker_for, avg 3µs/call |
58 | ->generate_method($target, $name, $spec_ref); | ||||
59 | 9 | 27µs | 9 | 21µs | $class->_maybe_reset_handlemoose($target); # spent 21µs making 9 calls to Moo::_maybe_reset_handlemoose, avg 2µs/call |
60 | } | ||||
61 | 7 | 27µs | return; | ||
62 | 2 | 10µs | 2 | 42µs | }; # spent 42µs making 2 calls to Moo::_install_tracked, avg 21µs/call |
63 | 2 | 2µs | foreach my $type (qw(before after around)) { | ||
64 | # spent 2.17ms (1.60+569µs) within Moo::around which was called:
# once (1.60ms+569µs) by main::BEGIN@7 at line 45 of String/Markov.pm | ||||
65 | 1 | 96µs | require Class::Method::Modifiers; | ||
66 | 1 | 5µs | 1 | 265µs | _install_modifier($target, $type, @_); # spent 265µs making 1 call to Moo::_Utils::_install_modifier |
67 | 1 | 3µs | return; | ||
68 | 6 | 24µs | 6 | 128µs | }; # spent 128µs making 6 calls to Moo::_install_tracked, avg 21µs/call |
69 | } | ||||
70 | 2 | 2µs | return if $MAKERS{$target}{is_class}; # already exported into this package | ||
71 | 2 | 4µs | 2 | 6µs | my $stash = _getstash($target); # spent 6µs making 2 calls to Moo::_Utils::_getstash, avg 3µs/call |
72 | 2 | 18µs | my @not_methods = map { *$_{CODE}||() } grep !ref($_), values %$stash; | ||
73 | 2 | 15µs | @{$MAKERS{$target}{not_methods}={}}{@not_methods} = @not_methods; | ||
74 | 2 | 2µs | $MAKERS{$target}{is_class} = 1; | ||
75 | { | ||||
76 | 4 | 355µs | 2 | 40µs | # spent 25µs (9+15) within Moo::BEGIN@76 which was called:
# once (9µs+15µs) by String::Markov::BEGIN@8 at line 76 # spent 25µs making 1 call to Moo::BEGIN@76
# spent 16µs making 1 call to strict::unimport |
77 | @{"${target}::ISA"} = do { | ||||
78 | 4 | 90µs | require Moo::Object; ('Moo::Object'); | ||
79 | 2 | 25µs | } unless @{"${target}::ISA"}; | ||
80 | } | ||||
81 | 2 | 14µs | if ($INC{'Moo/HandleMoose.pm'}) { | ||
82 | Moo::HandleMoose::inject_fake_metaclass_for($target); | ||||
83 | } | ||||
84 | } | ||||
85 | |||||
86 | sub unimport { | ||||
87 | my $target = caller; | ||||
88 | _unimport_coderefs($target, $MAKERS{$target}); | ||||
89 | } | ||||
90 | |||||
91 | sub _set_superclasses { | ||||
92 | my $class = shift; | ||||
93 | my $target = shift; | ||||
94 | foreach my $superclass (@_) { | ||||
95 | _load_module($superclass); | ||||
96 | if ($INC{'Role/Tiny.pm'} && Role::Tiny->is_role($superclass)) { | ||||
97 | require Carp; | ||||
98 | Carp::croak("Can't extend role '$superclass'"); | ||||
99 | } | ||||
100 | } | ||||
101 | # Can't do *{...} = \@_ or 5.10.0's mro.pm stops seeing @ISA | ||||
102 | @{*{_getglob("${target}::ISA")}{ARRAY}} = @_; | ||||
103 | if (my $old = delete $Moo::MAKERS{$target}{constructor}) { | ||||
104 | $old->assert_constructor; | ||||
105 | delete _getstash($target)->{new}; | ||||
106 | Moo->_constructor_maker_for($target) | ||||
107 | ->register_attribute_specs(%{$old->all_attribute_specs}); | ||||
108 | } | ||||
109 | elsif (!$target->isa('Moo::Object')) { | ||||
110 | Moo->_constructor_maker_for($target); | ||||
111 | } | ||||
112 | 2 | 895µs | 2 | 39µs | # spent 25µs (12+13) within Moo::BEGIN@112 which was called:
# once (12µs+13µs) by String::Markov::BEGIN@8 at line 112 # spent 25µs making 1 call to Moo::BEGIN@112
# spent 13µs making 1 call to warnings::unimport |
113 | $Moo::HandleMoose::MOUSE{$target} = [ | ||||
114 | grep defined, map Mouse::Util::find_meta($_), @_ | ||||
115 | ] if Mouse::Util->can('find_meta'); | ||||
116 | } | ||||
117 | |||||
118 | # spent 21µs within Moo::_maybe_reset_handlemoose which was called 9 times, avg 2µs/call:
# 9 times (21µs+0s) by Moo::has at line 59, avg 2µs/call | ||||
119 | 9 | 6µs | my ($class, $target) = @_; | ||
120 | 9 | 23µs | if ($INC{"Moo/HandleMoose.pm"}) { | ||
121 | Moo::HandleMoose::maybe_reinject_fake_metaclass_for($target); | ||||
122 | } | ||||
123 | } | ||||
124 | |||||
125 | sub _accessor_maker_for { | ||||
126 | 11 | 6µs | my ($class, $target) = @_; | ||
127 | 11 | 6µs | return unless $MAKERS{$target}; | ||
128 | 11 | 46µs | $MAKERS{$target}{accessor} ||= do { | ||
129 | 2 | 3µs | my $maker_class = do { | ||
130 | 2 | 2µs | if (my $m = do { | ||
131 | 2 | 800ns | require Sub::Defer; | ||
132 | 2 | 35µs | 4 | 19µs | if (my $defer_target = # spent 11µs making 2 calls to Sub::Defer::defer_info, avg 5µs/call
# spent 8µs making 2 calls to UNIVERSAL::can, avg 4µs/call |
133 | (Sub::Defer::defer_info($target->can('new'))||[])->[0] | ||||
134 | ) { | ||||
135 | my ($pkg) = ($defer_target =~ /^(.*)::[^:]+$/); | ||||
136 | $MAKERS{$pkg} && $MAKERS{$pkg}{accessor}; | ||||
137 | } else { | ||||
138 | 2 | 900ns | undef; | ||
139 | } | ||||
140 | }) { | ||||
141 | ref($m); | ||||
142 | } else { | ||||
143 | 2 | 86µs | require Method::Generate::Accessor; | ||
144 | 2 | 1µs | 'Method::Generate::Accessor' | ||
145 | } | ||||
146 | }; | ||||
147 | 2 | 12µs | 2 | 63µs | $maker_class->new; # spent 63µs making 2 calls to Moo::Object::new, avg 32µs/call |
148 | } | ||||
149 | } | ||||
150 | |||||
151 | # spent 22.2ms (2.45+19.8) within Moo::_constructor_maker_for which was called 10 times, avg 2.22ms/call:
# 9 times (2.34ms+19.9ms) by Moo::has at line 55, avg 2.47ms/call
# once (118µs+-118µs) by Moo::_constructor_maker_for at line 244 of Method/Generate/Constructor.pm | ||||
152 | 10 | 5µs | my ($class, $target) = @_; | ||
153 | 10 | 7µs | return unless $MAKERS{$target}; | ||
154 | 10 | 44µs | $MAKERS{$target}{constructor} ||= do { | ||
155 | 2 | 83µs | require Method::Generate::Constructor; | ||
156 | 2 | 2µs | require Sub::Defer; | ||
157 | |||||
158 | 2 | 29µs | 2 | 10.2ms | my %construct_opts = ( # spent 10.2ms making 2 calls to Moo::_accessor_maker_for, avg 5.10ms/call |
159 | package => $target, | ||||
160 | accessor_generator => $class->_accessor_maker_for($target), | ||||
161 | subconstructor_handler => ( | ||||
162 | ' if ($Moo::MAKERS{$class}) {'."\n" | ||||
163 | .' if ($Moo::MAKERS{$class}{constructor}) {'."\n" | ||||
164 | .' package '.$target.';'."\n" | ||||
165 | .' return $class->SUPER::new(@_);'."\n" | ||||
166 | .' }'."\n" | ||||
167 | .' '.$class.'->_constructor_maker_for($class);'."\n" | ||||
168 | .' return $class->new(@_)'.";\n" | ||||
169 | .' } elsif ($INC{"Moose.pm"} and my $meta = Class::MOP::get_metaclass_by_name($class)) {'."\n" | ||||
170 | .' return $meta->new_object('."\n" | ||||
171 | .' $class->can("BUILDARGS") ? $class->BUILDARGS(@_)'."\n" | ||||
172 | .' : $class->Moo::Object::BUILDARGS(@_)'."\n" | ||||
173 | .' );'."\n" | ||||
174 | .' }'."\n" | ||||
175 | ), | ||||
176 | ); | ||||
177 | |||||
178 | 2 | 900ns | my $con; | ||
179 | 2 | 41µs | 2 | 14µs | my @isa = @{mro::get_linear_isa($target)}; # spent 14µs making 2 calls to mro::get_linear_isa, avg 7µs/call |
180 | 2 | 2µs | shift @isa; | ||
181 | 2 | 16µs | 2 | 8µs | if (my ($parent_new) = grep { *{_getglob($_.'::new')}{CODE} } @isa) { # spent 8µs making 2 calls to Moo::_Utils::_getglob, avg 4µs/call |
182 | 2 | 2µs | if ($parent_new eq 'Moo::Object') { | ||
183 | # no special constructor needed | ||||
184 | } | ||||
185 | elsif (my $makers = $MAKERS{$parent_new}) { | ||||
186 | $con = $makers->{constructor}; | ||||
187 | $construct_opts{construction_string} = $con->construction_string | ||||
188 | if $con; | ||||
189 | } | ||||
190 | elsif ($parent_new->can('BUILDALL')) { | ||||
191 | $construct_opts{construction_builder} = sub { | ||||
192 | my $inv = $target->can('BUILDARGS') ? '' : 'Moo::Object::'; | ||||
193 | 'do {' | ||||
194 | .' my $args = $class->'.$inv.'BUILDARGS(@_);' | ||||
195 | .' $args->{__no_BUILD__} = 1;' | ||||
196 | .' $class->'.$target.'::SUPER::new($args);' | ||||
197 | .'}' | ||||
198 | }; | ||||
199 | } | ||||
200 | else { | ||||
201 | $construct_opts{construction_builder} = sub { | ||||
202 | '$class->'.$target.'::SUPER::new(' | ||||
203 | .($target->can('FOREIGNBUILDARGS') ? | ||||
204 | '$class->FOREIGNBUILDARGS(@_)' : '@_') | ||||
205 | .')' | ||||
206 | }; | ||||
207 | } | ||||
208 | } | ||||
209 | ($con ? ref($con) : 'Method::Generate::Constructor') | ||||
210 | ->new(%construct_opts) | ||||
211 | ->install_delayed | ||||
212 | 2 | 26µs | 6 | 2.01ms | ->register_attribute_specs(%{$con?$con->all_attribute_specs:{}}) # spent 1.70ms making 2 calls to Method::Generate::Constructor::new, avg 850µs/call
# spent 251µs making 2 calls to Method::Generate::Constructor::install_delayed, avg 125µs/call
# spent 55µs making 2 calls to Method::Generate::Constructor::register_attribute_specs, avg 27µs/call |
213 | } | ||||
214 | } | ||||
215 | |||||
216 | sub _concrete_methods_of { | ||||
217 | my ($me, $role) = @_; | ||||
218 | my $makers = $MAKERS{$role}; | ||||
219 | # grab role symbol table | ||||
220 | my $stash = _getstash($role); | ||||
221 | # reverse so our keys become the values (captured coderefs) in case | ||||
222 | # they got copied or re-used since | ||||
223 | my $not_methods = { reverse %{$makers->{not_methods}||{}} }; | ||||
224 | +{ | ||||
225 | # grab all code entries that aren't in the not_methods list | ||||
226 | map { | ||||
227 | my $code = *{$stash->{$_}}{CODE}; | ||||
228 | ( ! $code or exists $not_methods->{$code} ) ? () : ($_ => $code) | ||||
229 | } grep !ref($stash->{$_}), keys %$stash | ||||
230 | }; | ||||
231 | } | ||||
232 | |||||
233 | 1 | 4µs | 1; | ||
234 | __END__ |