Filename | /home/ss5/perl5/perlbrew/perls/perl-5.22.0/lib/site_perl/5.22.0/Moo/HandleMoose.pm |
Statements | Executed 377 statements in 1.31ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
1 | 1 | 1 | 1.03ms | 1.67ms | BEGIN@5 | Moo::HandleMoose::
24 | 2 | 2 | 369µs | 24.3ms | inject_fake_metaclass_for | Moo::HandleMoose::
98 | 2 | 2 | 79µs | 79µs | maybe_reinject_fake_metaclass_for | Moo::HandleMoose::
1 | 1 | 1 | 25µs | 25µs | inject_all | Moo::HandleMoose::
1 | 1 | 1 | 7µs | 16µs | BEGIN@2 | Moo::HandleMoose::
1 | 1 | 1 | 7µs | 12µs | BEGIN@216 | Moo::HandleMoose::
1 | 1 | 1 | 6µs | 12µs | BEGIN@18 | Moo::HandleMoose::
1 | 1 | 1 | 4µs | 45µs | BEGIN@4 | Moo::HandleMoose::
1 | 1 | 1 | 4µs | 10µs | BEGIN@3 | Moo::HandleMoose::
1 | 1 | 1 | 4µs | 29µs | import | Moo::HandleMoose::
0 | 0 | 0 | 0s | 0s | _uninlined_body | Moo::HandleMoose::FakeConstructor::
0 | 0 | 0 | 0s | 0s | __ANON__[:137] | Moo::HandleMoose::
0 | 0 | 0 | 0s | 0s | __ANON__[:149] | Moo::HandleMoose::
0 | 0 | 0 | 0s | 0s | __ANON__[:152] | Moo::HandleMoose::
0 | 0 | 0 | 0s | 0s | inject_real_metaclass_for | Moo::HandleMoose::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | package Moo::HandleMoose; | ||||
2 | 2 | 15µs | 2 | 25µs | # spent 16µs (7+9) within Moo::HandleMoose::BEGIN@2 which was called:
# once (7µs+9µs) by Moo::sification::import at line 2 # spent 16µs making 1 call to Moo::HandleMoose::BEGIN@2
# spent 9µs making 1 call to Moo::_strictures::import |
3 | 2 | 14µs | 2 | 16µs | # spent 10µs (4+6) within Moo::HandleMoose::BEGIN@3 which was called:
# once (4µs+6µs) by Moo::sification::import at line 3 # spent 10µs making 1 call to Moo::HandleMoose::BEGIN@3
# spent 6µs making 1 call to warnings::unimport |
4 | 2 | 17µs | 2 | 85µs | # spent 45µs (4+40) within Moo::HandleMoose::BEGIN@4 which was called:
# once (4µs+40µs) by Moo::sification::import at line 4 # spent 45µs making 1 call to Moo::HandleMoose::BEGIN@4
# spent 40µs making 1 call to Exporter::import |
5 | 2 | 112µs | 2 | 1.69ms | # spent 1.67ms (1.03+642µs) within Moo::HandleMoose::BEGIN@5 which was called:
# once (1.03ms+642µs) by Moo::sification::import at line 5 # spent 1.67ms making 1 call to Moo::HandleMoose::BEGIN@5
# spent 25µs making 1 call to Exporter::import |
6 | |||||
7 | our %TYPE_MAP; | ||||
8 | |||||
9 | our $SETUP_DONE; | ||||
10 | |||||
11 | 3 | 2µs | 1 | 25µs | # spent 29µs (4+25) within Moo::HandleMoose::import which was called:
# once (4µs+25µs) by Moo::sification::import at line 25 of Moo/sification.pm # spent 25µs making 1 call to Moo::HandleMoose::inject_all |
12 | |||||
13 | # spent 25µs within Moo::HandleMoose::inject_all which was called:
# once (25µs+0s) by Moo::HandleMoose::import at line 11 | ||||
14 | 1 | 100ns | die "Can't inflate Moose metaclass with Moo::sification disabled" | ||
15 | if $Moo::sification::disabled; | ||||
16 | 1 | 500ns | require Class::MOP; | ||
17 | inject_fake_metaclass_for($_) | ||||
18 | 4 | 660µs | 2 | 18µs | # spent 12µs (6+6) within Moo::HandleMoose::BEGIN@18 which was called:
# once (6µs+6µs) by Moo::sification::import at line 18 # spent 12µs making 1 call to Moo::HandleMoose::BEGIN@18
# spent 6µs making 1 call to warnings::unimport |
19 | 1 | 400ns | inject_fake_metaclass_for($_) for keys %Moo::Role::INFO; | ||
20 | 1 | 600ns | require Moose::Meta::Method::Constructor; | ||
21 | 1 | 16µs | @Moo::HandleMoose::FakeConstructor::ISA = 'Moose::Meta::Method::Constructor'; | ||
22 | 1 | 9µs | @Moo::HandleMoose::FakeMeta::ISA = 'Moose::Meta::Method::Meta'; | ||
23 | } | ||||
24 | |||||
25 | # spent 79µs within Moo::HandleMoose::maybe_reinject_fake_metaclass_for which was called 98 times, avg 808ns/call:
# 67 times (53µs+0s) by Moo::Role::_maybe_reset_handlemoose at line 116 of Moo/Role.pm, avg 785ns/call
# 31 times (27µs+0s) by Moo::_maybe_reset_handlemoose at line 120 of Moo.pm, avg 858ns/call | ||||
26 | 98 | 15µs | my ($name) = @_; | ||
27 | our %DID_INJECT; | ||||
28 | 98 | 121µs | if (delete $DID_INJECT{$name}) { | ||
29 | unless ($Moo::Role::INFO{$name}) { | ||||
30 | Moo->_constructor_maker_for($name)->install_delayed; | ||||
31 | } | ||||
32 | inject_fake_metaclass_for($name); | ||||
33 | } | ||||
34 | } | ||||
35 | |||||
36 | # spent 24.3ms (369µs+24.0) within Moo::HandleMoose::inject_fake_metaclass_for which was called 24 times, avg 1.01ms/call:
# 12 times (269µs+14.2ms) by Moo::import at line 81 of Moo.pm, avg 1.21ms/call
# 12 times (100µs+9.77ms) by Moo::Role::__ANON__[/home/ss5/perl5/perlbrew/perls/perl-5.22.0/lib/site_perl/5.22.0/Moo/Role.pm:100] at line 97 of Moo/Role.pm, avg 823µs/call | ||||
37 | 24 | 6µs | my ($name) = @_; | ||
38 | 24 | 12µs | require Class::MOP; | ||
39 | 24 | 45µs | require Moo::HandleMoose::FakeMetaClass; | ||
40 | 24 | 58µs | 24 | 37µs | Class::MOP::store_metaclass_by_name( # spent 37µs making 24 calls to Class::MOP::store_metaclass_by_name, avg 2µs/call |
41 | $name, bless({ name => $name }, 'Moo::HandleMoose::FakeMetaClass') | ||||
42 | ); | ||||
43 | 24 | 13µs | require Moose::Util::TypeConstraints; | ||
44 | 24 | 66µs | 12 | 9.75ms | if ($Moo::Role::INFO{$name}) { # spent 9.75ms making 12 calls to Moose::Util::TypeConstraints::find_or_create_does_type_constraint, avg 813µs/call |
45 | Moose::Util::TypeConstraints::find_or_create_does_type_constraint($name); | ||||
46 | } else { | ||||
47 | 12 | 20µs | 12 | 14.2ms | Moose::Util::TypeConstraints::find_or_create_isa_type_constraint($name); # spent 14.2ms making 12 calls to Moose::Util::TypeConstraints::find_or_create_isa_type_constraint, avg 1.18ms/call |
48 | } | ||||
49 | } | ||||
50 | |||||
51 | { | ||||
52 | package Moo::HandleMoose::FakeConstructor; | ||||
53 | |||||
54 | sub _uninlined_body { \&Moose::Object::new } | ||||
55 | } | ||||
56 | |||||
57 | 1 | 400ns | sub inject_real_metaclass_for { | ||
58 | my ($name) = @_; | ||||
59 | our %DID_INJECT; | ||||
60 | return Class::MOP::get_metaclass_by_name($name) if $DID_INJECT{$name}; | ||||
61 | require Moose; require Moo; require Moo::Role; require Scalar::Util; | ||||
62 | Class::MOP::remove_metaclass_by_name($name); | ||||
63 | my ($am_role, $am_class, $meta, $attr_specs, $attr_order) = do { | ||||
64 | if (my $info = $Moo::Role::INFO{$name}) { | ||||
65 | my @attr_info = @{$info->{attributes}||[]}; | ||||
66 | (1, 0, Moose::Meta::Role->initialize($name), | ||||
67 | { @attr_info }, | ||||
68 | [ @attr_info[grep !($_ % 2), 0..$#attr_info] ] | ||||
69 | ) | ||||
70 | } elsif ( my $cmaker = Moo->_constructor_maker_for($name) ) { | ||||
71 | my $specs = $cmaker->all_attribute_specs; | ||||
72 | (0, 1, Moose::Meta::Class->initialize($name), $specs, | ||||
73 | [ sort { $specs->{$a}{index} <=> $specs->{$b}{index} } keys %$specs ] | ||||
74 | ); | ||||
75 | } else { | ||||
76 | # This codepath is used if $name does not exist in $Moo::MAKERS | ||||
77 | (0, 0, Moose::Meta::Class->initialize($name), {}, [] ) | ||||
78 | } | ||||
79 | }; | ||||
80 | |||||
81 | foreach my $spec (values %$attr_specs) { | ||||
82 | if (my $inflators = delete $spec->{moosify}) { | ||||
83 | $_->($spec) for @$inflators; | ||||
84 | } | ||||
85 | } | ||||
86 | |||||
87 | my %methods | ||||
88 | = %{($am_role ? 'Moo::Role' : 'Moo')->_concrete_methods_of($name)}; | ||||
89 | |||||
90 | # if stuff gets added afterwards, _maybe_reset_handlemoose should | ||||
91 | # trigger the recreation of the metaclass but we need to ensure the | ||||
92 | # Moo::Role cache is cleared so we don't confuse Moo itself. | ||||
93 | if (my $info = $Moo::Role::INFO{$name}) { | ||||
94 | delete $info->{methods}; | ||||
95 | } | ||||
96 | |||||
97 | # needed to ensure the method body is stable and get things named | ||||
98 | Sub::Defer::undefer_sub($_) for grep defined, values %methods; | ||||
99 | my @attrs; | ||||
100 | { | ||||
101 | # This local is completely not required for roles but harmless | ||||
102 | local @{_getstash($name)}{keys %methods}; | ||||
103 | my %seen_name; | ||||
104 | foreach my $name (@$attr_order) { | ||||
105 | $seen_name{$name} = 1; | ||||
106 | my %spec = %{$attr_specs->{$name}}; | ||||
107 | my %spec_map = ( | ||||
108 | map { $_->name => $_->init_arg||$_->name } | ||||
109 | ( | ||||
110 | (grep { $_->has_init_arg } | ||||
111 | $meta->attribute_metaclass->meta->get_all_attributes), | ||||
112 | grep { exists($_->{init_arg}) ? defined($_->init_arg) : 1 } | ||||
113 | map { | ||||
114 | my $meta = Moose::Util::resolve_metatrait_alias('Attribute', $_) | ||||
115 | ->meta; | ||||
116 | map $meta->get_attribute($_), $meta->get_attribute_list | ||||
117 | } @{$spec{traits}||[]} | ||||
118 | ) | ||||
119 | ); | ||||
120 | # have to hard code this because Moose's role meta-model is lacking | ||||
121 | $spec_map{traits} ||= 'traits'; | ||||
122 | |||||
123 | $spec{is} = 'ro' if $spec{is} eq 'lazy' or $spec{is} eq 'rwp'; | ||||
124 | my $coerce = $spec{coerce}; | ||||
125 | if (my $isa = $spec{isa}) { | ||||
126 | my $tc = $spec{isa} = do { | ||||
127 | if (my $mapped = $TYPE_MAP{$isa}) { | ||||
128 | my $type = $mapped->(); | ||||
129 | unless ( Scalar::Util::blessed($type) | ||||
130 | && $type->isa("Moose::Meta::TypeConstraint") ) { | ||||
131 | die "error inflating attribute '$name' for package '$_[0]': " | ||||
132 | ."\$TYPE_MAP{$isa} did not return a valid type constraint'"; | ||||
133 | } | ||||
134 | $coerce ? $type->create_child_type(name => $type->name) : $type; | ||||
135 | } else { | ||||
136 | Moose::Meta::TypeConstraint->new( | ||||
137 | constraint => sub { eval { &$isa; 1 } } | ||||
138 | ); | ||||
139 | } | ||||
140 | }; | ||||
141 | if ($coerce) { | ||||
142 | $tc->coercion(Moose::Meta::TypeCoercion->new) | ||||
143 | ->_compiled_type_coercion($coerce); | ||||
144 | $spec{coerce} = 1; | ||||
145 | } | ||||
146 | } elsif ($coerce) { | ||||
147 | my $attr = quotify($name); | ||||
148 | my $tc = Moose::Meta::TypeConstraint->new( | ||||
149 | constraint => sub { die "This is not going to work" }, | ||||
150 | inlined => sub { | ||||
151 | 'my $r = $_[42]{'.$attr.'}; $_[42]{'.$attr.'} = 1; $r' | ||||
152 | }, | ||||
153 | ); | ||||
154 | $tc->coercion(Moose::Meta::TypeCoercion->new) | ||||
155 | ->_compiled_type_coercion($coerce); | ||||
156 | $spec{isa} = $tc; | ||||
157 | $spec{coerce} = 1; | ||||
158 | } | ||||
159 | %spec = | ||||
160 | map { $spec_map{$_} => $spec{$_} } | ||||
161 | grep { exists $spec_map{$_} } | ||||
162 | keys %spec; | ||||
163 | push @attrs, $meta->add_attribute($name => %spec); | ||||
164 | } | ||||
165 | foreach my $mouse (do { our %MOUSE; @{$MOUSE{$name}||[]} }) { | ||||
166 | foreach my $attr ($mouse->get_all_attributes) { | ||||
167 | my %spec = %{$attr}; | ||||
168 | delete @spec{qw( | ||||
169 | associated_class associated_methods __METACLASS__ | ||||
170 | provides curries | ||||
171 | )}; | ||||
172 | my $name = delete $spec{name}; | ||||
173 | next if $seen_name{$name}++; | ||||
174 | push @attrs, $meta->add_attribute($name => %spec); | ||||
175 | } | ||||
176 | } | ||||
177 | } | ||||
178 | foreach my $meth_name (keys %methods) { | ||||
179 | my $meth_code = $methods{$meth_name}; | ||||
180 | $meta->add_method($meth_name, $meth_code) if $meth_code; | ||||
181 | } | ||||
182 | |||||
183 | if ($am_role) { | ||||
184 | my $info = $Moo::Role::INFO{$name}; | ||||
185 | $meta->add_required_methods(@{$info->{requires}}); | ||||
186 | foreach my $modifier (@{$info->{modifiers}}) { | ||||
187 | my ($type, @args) = @$modifier; | ||||
188 | my $code = pop @args; | ||||
189 | $meta->${\"add_${type}_method_modifier"}($_, $code) for @args; | ||||
190 | } | ||||
191 | } | ||||
192 | elsif ($am_class) { | ||||
193 | foreach my $attr (@attrs) { | ||||
194 | foreach my $method (@{$attr->associated_methods}) { | ||||
195 | $method->{body} = $name->can($method->name); | ||||
196 | } | ||||
197 | } | ||||
198 | bless( | ||||
199 | $meta->find_method_by_name('new'), | ||||
200 | 'Moo::HandleMoose::FakeConstructor', | ||||
201 | ); | ||||
202 | my $meta_meth; | ||||
203 | if ( | ||||
204 | $meta_meth = $meta->find_method_by_name('meta') | ||||
205 | and $meta_meth->body == \&Moo::Object::meta | ||||
206 | ) { | ||||
207 | bless($meta_meth, 'Moo::HandleMoose::FakeMeta'); | ||||
208 | } | ||||
209 | # a combination of Moo and Moose may bypass a Moo constructor but still | ||||
210 | # use a Moo DEMOLISHALL. We need to make sure this is loaded before | ||||
211 | # global destruction. | ||||
212 | require Method::Generate::DemolishAll; | ||||
213 | } | ||||
214 | $meta->add_role(Class::MOP::class_of($_)) | ||||
215 | for grep !/\|/ && $_ ne $name, # reject Foo|Bar and same-role-as-self | ||||
216 | 2 | 110µs | 2 | 18µs | # spent 12µs (7+6) within Moo::HandleMoose::BEGIN@216 which was called:
# once (7µs+6µs) by Moo::sification::import at line 216 # spent 12µs making 1 call to Moo::HandleMoose::BEGIN@216
# spent 6µs making 1 call to warnings::unimport |
217 | $DID_INJECT{$name} = 1; | ||||
218 | $meta; | ||||
219 | } | ||||
220 | |||||
221 | 1 | 2µs | 1; |