| Filename | /usr/share/perl5/JSON.pm | 
| Statements | Executed 106 statements in 2.31ms | 
| Calls | P | F | Exclusive Time | Inclusive Time | Subroutine | 
|---|---|---|---|---|---|
| 1 | 1 | 1 | 8.42ms | 16.5ms | JSON::_load_pp | 
| 4 | 4 | 1 | 306µs | 445µs | JSON::Boolean::_overrride_overload | 
| 3 | 3 | 3 | 92µs | 671µs | JSON::import | 
| 1 | 1 | 1 | 75µs | 596µs | JSON::_load_xs | 
| 1 | 1 | 1 | 52µs | 52µs | JSON::_set_module | 
| 1 | 1 | 1 | 50µs | 50µs | JSON::Backend::PP::init | 
| 1 | 1 | 1 | 18µs | 22µs | JSON::BEGIN@4 | 
| 1 | 1 | 1 | 15µs | 39µs | JSON::BEGIN@284 | 
| 1 | 1 | 1 | 13µs | 97µs | JSON::BEGIN@6 | 
| 1 | 1 | 1 | 9µs | 23µs | JSON::Backend::PP::BEGIN@349 | 
| 1 | 1 | 1 | 5µs | 5µs | JSON::BEGIN@9 | 
| 1 | 1 | 1 | 4µs | 4µs | JSON::BEGIN@5 | 
| 0 | 0 | 0 | 0s | 0s | JSON::Backend::PP::__ANON__[:352] | 
| 0 | 0 | 0 | 0s | 0s | JSON::Backend::PP::__ANON__[:353] | 
| 0 | 0 | 0 | 0s | 0s | JSON::__ANON__[:298] | 
| 0 | 0 | 0 | 0s | 0s | JSON::backend | 
| 0 | 0 | 0 | 0s | 0s | JSON::false | 
| 0 | 0 | 0 | 0s | 0s | JSON::from_json | 
| 0 | 0 | 0 | 0s | 0s | JSON::is_pp | 
| 0 | 0 | 0 | 0s | 0s | JSON::is_xs | 
| 0 | 0 | 0 | 0s | 0s | JSON::jsonToObj | 
| 0 | 0 | 0 | 0s | 0s | JSON::null | 
| 0 | 0 | 0 | 0s | 0s | JSON::objToJson | 
| 0 | 0 | 0 | 0s | 0s | JSON::property | 
| 0 | 0 | 0 | 0s | 0s | JSON::pureperl_only_methods | 
| 0 | 0 | 0 | 0s | 0s | JSON::require_xs_version | 
| 0 | 0 | 0 | 0s | 0s | JSON::to_json | 
| 0 | 0 | 0 | 0s | 0s | JSON::true | 
| Line | State ments | Time on line | Calls | Time in subs | Code | 
|---|---|---|---|---|---|
| 1 | package JSON; | ||||
| 2 | |||||
| 3 | |||||
| 4 | 3 | 26µs | 2 | 27µs | # spent 22µs (18+5) within JSON::BEGIN@4 which was called:
#    once (18µs+5µs) by C4::Auth::BEGIN@23 at line 4 # spent    22µs making 1 call to JSON::BEGIN@4
# spent     5µs making 1 call to strict::import | 
| 5 | 3 | 24µs | 1 | 4µs | # spent 4µs within JSON::BEGIN@5 which was called:
#    once (4µs+0s) by C4::Auth::BEGIN@23 at line 5 # spent     4µs making 1 call to JSON::BEGIN@5 | 
| 6 | 3 | 67µs | 2 | 180µs | # spent 97µs (13+84) within JSON::BEGIN@6 which was called:
#    once (13µs+84µs) by C4::Auth::BEGIN@23 at line 6 # spent    97µs making 1 call to JSON::BEGIN@6
# spent    84µs making 1 call to base::import | 
| 7 | 1 | 2µs | @JSON::EXPORT = qw(from_json to_json jsonToObj objToJson encode_json decode_json); | ||
| 8 | |||||
| 9 | # spent 5µs within JSON::BEGIN@9 which was called:
#    once (5µs+0s) by C4::Auth::BEGIN@23 at line 12 | ||||
| 10 | 2 | 5µs | $JSON::VERSION = '2.21'; | ||
| 11 | $JSON::DEBUG = 0 unless (defined $JSON::DEBUG); | ||||
| 12 | 1 | 1.14ms | 1 | 5µs | } # spent     5µs making 1 call to JSON::BEGIN@9 | 
| 13 | |||||
| 14 | 1 | 600ns | my $Module_XS = 'JSON::XS'; | ||
| 15 | 1 | 400ns | my $Module_PP = 'JSON::PP'; | ||
| 16 | 1 | 300ns | my $XS_Version = '2.27'; | ||
| 17 | |||||
| 18 | |||||
| 19 | # XS and PP common methods | ||||
| 20 | |||||
| 21 | 1 | 4µs | my @PublicMethods = qw/ | ||
| 22 | ascii latin1 utf8 pretty indent space_before space_after relaxed canonical allow_nonref | ||||
| 23 | allow_blessed convert_blessed filter_json_object filter_json_single_key_object | ||||
| 24 | shrink max_depth max_size encode decode decode_prefix allow_unknown | ||||
| 25 | /; | ||||
| 26 | |||||
| 27 | 1 | 2µs | my @Properties = qw/ | ||
| 28 | ascii latin1 utf8 indent space_before space_after relaxed canonical allow_nonref | ||||
| 29 | allow_blessed convert_blessed shrink max_depth max_size allow_unknown | ||||
| 30 | /; | ||||
| 31 | |||||
| 32 | 1 | 300ns | my @XSOnlyMethods = qw//; # Currently nothing | ||
| 33 | |||||
| 34 | 1 | 2µs | my @PPOnlyMethods = qw/ | ||
| 35 | indent_length sort_by | ||||
| 36 | allow_singlequote allow_bignum loose allow_barekey escape_slash as_nonblessed | ||||
| 37 | /; # JSON::PP specific | ||||
| 38 | |||||
| 39 | |||||
| 40 | # used in _load_xs and _load_pp ($INSTALL_ONLY is not used currently) | ||||
| 41 | 1 | 300ns | my $_INSTALL_DONT_DIE = 1; # When _load_xs fails to load XS, don't die. | ||
| 42 | 1 | 200ns | my $_INSTALL_ONLY = 2; # Don't call _set_methods() | ||
| 43 | 1 | 200ns | my $_ALLOW_UNSUPPORTED = 0; | ||
| 44 | 1 | 200ns | my $_UNIV_CONV_BLESSED = 0; | ||
| 45 | |||||
| 46 | |||||
| 47 | # Check the environment variable to decide worker module. | ||||
| 48 | |||||
| 49 | 4 | 13µs | unless ($JSON::Backend) { | ||
| 50 | $JSON::DEBUG and Carp::carp("Check used worker module..."); | ||||
| 51 | |||||
| 52 | my $backend = exists $ENV{PERL_JSON_BACKEND} ? $ENV{PERL_JSON_BACKEND} : 1; | ||||
| 53 | |||||
| 54 | 2 | 17.1ms | if ($backend eq '1' or $backend =~ /JSON::XS\s*,\s*JSON::PP/) {     # spent  16.5ms making 1 call to JSON::_load_pp
    # spent   596µs making 1 call to JSON::_load_xs | ||
| 55 | _load_xs($_INSTALL_DONT_DIE) or _load_pp(); | ||||
| 56 | } | ||||
| 57 | elsif ($backend eq '0' or $backend eq 'JSON::PP') { | ||||
| 58 | _load_pp(); | ||||
| 59 | } | ||||
| 60 | elsif ($backend eq '2' or $backend eq 'JSON::XS') { | ||||
| 61 | _load_xs(); | ||||
| 62 | } | ||||
| 63 | else { | ||||
| 64 | Carp::croak "The value of environmental variable 'PERL_JSON_BACKEND' is invalid."; | ||||
| 65 | } | ||||
| 66 | } | ||||
| 67 | |||||
| 68 | |||||
| 69 | # spent 671µs (92+578) within JSON::import which was called 3 times, avg 224µs/call:
#    once (29µs+246µs) by C4::Auth::BEGIN@23 at line 23 of /usr/share/koha/lib/C4/Auth.pm
#    once (40µs+216µs) by OpenILS::QueryParser::BEGIN@5 at line 5 of /usr/share/koha/lib/OpenILS/QueryParser.pm
#    once (24µs+116µs) by main::BEGIN@58 at line 58 of /usr/share/koha/opac/cgi-bin/opac/opac-search.pl | ||||
| 70 | 18 | 63µs | my $pkg = shift; | ||
| 71 | my @what_to_export; | ||||
| 72 | my $no_export; | ||||
| 73 | |||||
| 74 | for my $tag (@_) { | ||||
| 75 | 8 | 10µs | if ($tag eq '-support_by_pp') { | ||
| 76 | if (!$_ALLOW_UNSUPPORTED++) { | ||||
| 77 | JSON::Backend::XS | ||||
| 78 | ->support_by_pp(@PPOnlyMethods) if ($JSON::Backend eq $Module_XS); | ||||
| 79 | } | ||||
| 80 | next; | ||||
| 81 | } | ||||
| 82 | elsif ($tag eq '-no_export') { | ||||
| 83 | $no_export++, next; | ||||
| 84 | } | ||||
| 85 | elsif ( $tag eq '-convert_blessed_universally' ) { | ||||
| 86 | eval q| | ||||
| 87 | require B; | ||||
| 88 | *UNIVERSAL::TO_JSON = sub { | ||||
| 89 | my $b_obj = B::svref_2object( $_[0] ); | ||||
| 90 | return $b_obj->isa('B::HV') ? { %{ $_[0] } } | ||||
| 91 | : $b_obj->isa('B::AV') ? [ @{ $_[0] } ] | ||||
| 92 | : undef | ||||
| 93 | ; | ||||
| 94 | } | ||||
| 95 | | if ( !$_UNIV_CONV_BLESSED++ ); | ||||
| 96 | next; | ||||
| 97 | } | ||||
| 98 | push @what_to_export, $tag; | ||||
| 99 | } | ||||
| 100 | |||||
| 101 | return if ($no_export); | ||||
| 102 | |||||
| 103 | 3 | 119µs | __PACKAGE__->export_to_level(1, $pkg, @what_to_export);     # spent   119µs making 3 calls to Exporter::export_to_level, avg 40µs/call | ||
| 104 | } | ||||
| 105 | |||||
| 106 | |||||
| 107 | # OBSOLETED | ||||
| 108 | |||||
| 109 | sub jsonToObj { | ||||
| 110 | my $alternative = 'from_json'; | ||||
| 111 | if (defined $_[0] and UNIVERSAL::isa($_[0], 'JSON')) { | ||||
| 112 | shift @_; $alternative = 'decode'; | ||||
| 113 | } | ||||
| 114 | Carp::carp "'jsonToObj' will be obsoleted. Please use '$alternative' instead."; | ||||
| 115 | return JSON::from_json(@_); | ||||
| 116 | }; | ||||
| 117 | |||||
| 118 | sub objToJson { | ||||
| 119 | my $alternative = 'to_json'; | ||||
| 120 | if (defined $_[0] and UNIVERSAL::isa($_[0], 'JSON')) { | ||||
| 121 | shift @_; $alternative = 'encode'; | ||||
| 122 | } | ||||
| 123 | Carp::carp "'objToJson' will be obsoleted. Please use '$alternative' instead."; | ||||
| 124 | JSON::to_json(@_); | ||||
| 125 | }; | ||||
| 126 | |||||
| 127 | |||||
| 128 | # INTERFACES | ||||
| 129 | |||||
| 130 | sub to_json ($@) { | ||||
| 131 | my $json = new JSON; | ||||
| 132 | |||||
| 133 | if (@_ == 2 and ref $_[1] eq 'HASH') { | ||||
| 134 | my $opt = $_[1]; | ||||
| 135 | for my $method (keys %$opt) { | ||||
| 136 | $json->$method( $opt->{$method} ); | ||||
| 137 | } | ||||
| 138 | } | ||||
| 139 | |||||
| 140 | $json->encode($_[0]); | ||||
| 141 | } | ||||
| 142 | |||||
| 143 | |||||
| 144 | sub from_json ($@) { | ||||
| 145 | my $json = new JSON; | ||||
| 146 | |||||
| 147 | if (@_ == 2 and ref $_[1] eq 'HASH') { | ||||
| 148 | my $opt = $_[1]; | ||||
| 149 | for my $method (keys %$opt) { | ||||
| 150 | $json->$method( $opt->{$method} ); | ||||
| 151 | } | ||||
| 152 | } | ||||
| 153 | |||||
| 154 | return $json->decode( $_[0] ); | ||||
| 155 | } | ||||
| 156 | |||||
| 157 | |||||
| 158 | sub true { $JSON::true } | ||||
| 159 | |||||
| 160 | sub false { $JSON::false } | ||||
| 161 | |||||
| 162 | sub null { undef; } | ||||
| 163 | |||||
| 164 | |||||
| 165 | sub require_xs_version { $XS_Version; } | ||||
| 166 | |||||
| 167 | sub backend { | ||||
| 168 | my $proto = shift; | ||||
| 169 | $JSON::Backend; | ||||
| 170 | } | ||||
| 171 | |||||
| 172 | #*module = *backend; | ||||
| 173 | |||||
| 174 | |||||
| 175 | sub is_xs { | ||||
| 176 | return $_[0]->module eq $Module_XS; | ||||
| 177 | } | ||||
| 178 | |||||
| 179 | |||||
| 180 | sub is_pp { | ||||
| 181 | return $_[0]->module eq $Module_PP; | ||||
| 182 | } | ||||
| 183 | |||||
| 184 | |||||
| 185 | sub pureperl_only_methods { @PPOnlyMethods; } | ||||
| 186 | |||||
| 187 | |||||
| 188 | sub property { | ||||
| 189 | my ($self, $name, $value) = @_; | ||||
| 190 | |||||
| 191 | if (@_ == 1) { | ||||
| 192 | my %props; | ||||
| 193 | for $name (@Properties) { | ||||
| 194 | my $method = 'get_' . $name; | ||||
| 195 | if ($name eq 'max_size') { | ||||
| 196 | my $value = $self->$method(); | ||||
| 197 | $props{$name} = $value == 1 ? 0 : $value; | ||||
| 198 | next; | ||||
| 199 | } | ||||
| 200 | $props{$name} = $self->$method(); | ||||
| 201 | } | ||||
| 202 | return \%props; | ||||
| 203 | } | ||||
| 204 | elsif (@_ > 3) { | ||||
| 205 | Carp::croak('property() can take only the option within 2 arguments.'); | ||||
| 206 | } | ||||
| 207 | elsif (@_ == 2) { | ||||
| 208 | if ( my $method = $self->can('get_' . $name) ) { | ||||
| 209 | if ($name eq 'max_size') { | ||||
| 210 | my $value = $self->$method(); | ||||
| 211 | return $value == 1 ? 0 : $value; | ||||
| 212 | } | ||||
| 213 | $self->$method(); | ||||
| 214 | } | ||||
| 215 | } | ||||
| 216 | else { | ||||
| 217 | $self->$name($value); | ||||
| 218 | } | ||||
| 219 | |||||
| 220 | } | ||||
| 221 | |||||
| - - | |||||
| 224 | # INTERNAL | ||||
| 225 | |||||
| 226 | # spent 596µs (75+521) within JSON::_load_xs which was called:
#    once (75µs+521µs) by C4::Auth::BEGIN@23 at line 54 | ||||
| 227 | 6 | 39µs | my $opt = shift; | ||
| 228 | |||||
| 229 | $JSON::DEBUG and Carp::carp "Load $Module_XS."; | ||||
| 230 | |||||
| 231 | # if called after install module, overload is disable.... why? | ||||
| 232 | 1 | 240µs | JSON::Boolean::_overrride_overload($Module_XS);     # spent   240µs making 1 call to JSON::Boolean::_overrride_overload | ||
| 233 | 1 | 202µs | JSON::Boolean::_overrride_overload($Module_PP);     # spent   202µs making 1 call to JSON::Boolean::_overrride_overload | ||
| 234 | |||||
| 235 | eval qq|     # spent   106µs executing statements in string eval # includes 79µs spent executing 1 call to 1 sub defined therein. | ||||
| 236 | use $Module_XS $XS_Version (); | ||||
| 237 | |; | ||||
| 238 | |||||
| 239 | 1 | 900ns | if ($@) { | ||
| 240 | 2 | 6µs | if (defined $opt and $opt & $_INSTALL_DONT_DIE) { | ||
| 241 | $JSON::DEBUG and Carp::carp "Can't load $Module_XS...($@)"; | ||||
| 242 | return 0; | ||||
| 243 | } | ||||
| 244 | Carp::croak $@; | ||||
| 245 | } | ||||
| 246 | |||||
| 247 | unless (defined $opt and $opt & $_INSTALL_ONLY) { | ||||
| 248 | _set_module( $JSON::Backend = $Module_XS ); | ||||
| 249 | my $data = join("", <DATA>); # this code is from Jcode 2.xx. | ||||
| 250 | close(DATA); | ||||
| 251 | eval $data; | ||||
| 252 | JSON::Backend::XS->init; | ||||
| 253 | } | ||||
| 254 | |||||
| 255 | return 1; | ||||
| 256 | }; | ||||
| 257 | |||||
| 258 | |||||
| 259 | # spent 16.5ms (8.42+8.06) within JSON::_load_pp which was called:
#    once (8.42ms+8.06ms) by C4::Auth::BEGIN@23 at line 54 | ||||
| 260 | 7 | 36µs | my $opt = shift; | ||
| 261 | |||||
| 262 | $JSON::DEBUG and Carp::carp "Load $Module_PP."; | ||||
| 263 | |||||
| 264 | # if called after install module, overload is disable.... why? | ||||
| 265 | 1 | 2µs | JSON::Boolean::_overrride_overload($Module_XS);     # spent     2µs making 1 call to JSON::Boolean::_overrride_overload | ||
| 266 | 1 | 1µs | JSON::Boolean::_overrride_overload($Module_PP);     # spent     1µs making 1 call to JSON::Boolean::_overrride_overload | ||
| 267 | |||||
| 268 | eval qq| require $Module_PP |;     # spent    93µs executing statements in string eval | ||||
| 269 | if ($@) { | ||||
| 270 | Carp::croak $@; | ||||
| 271 | } | ||||
| 272 | |||||
| 273 | 2 | 12µs | unless (defined $opt and $opt & $_INSTALL_ONLY) { | ||
| 274 | 1 | 52µs | _set_module( $JSON::Backend = $Module_PP );         # spent    52µs making 1 call to JSON::_set_module | ||
| 275 | 1 | 50µs | JSON::Backend::PP->init;         # spent    50µs making 1 call to JSON::Backend::PP::init | ||
| 276 | } | ||||
| 277 | }; | ||||
| 278 | |||||
| 279 | |||||
| 280 | # spent 52µs within JSON::_set_module which was called:
#    once (52µs+0s) by JSON::_load_pp at line 274 | ||||
| 281 | 9 | 56µs | my $module = shift; | ||
| 282 | |||||
| 283 | local $^W; | ||||
| 284 | 3 | 262µs | 2 | 63µs | # spent 39µs (15+24) within JSON::BEGIN@284 which was called:
#    once (15µs+24µs) by C4::Auth::BEGIN@23 at line 284     # spent    39µs making 1 call to JSON::BEGIN@284
    # spent    24µs making 1 call to strict::unimport | 
| 285 | |||||
| 286 | $JSON::true = ${"$module\::true"}; | ||||
| 287 | $JSON::false = ${"$module\::false"}; | ||||
| 288 | |||||
| 289 | push @JSON::ISA, $module; | ||||
| 290 | push @{"$module\::Boolean::ISA"}, qw(JSON::Boolean); | ||||
| 291 | |||||
| 292 | *{"JSON::is_bool"} = \&{"$module\::is_bool"}; | ||||
| 293 | |||||
| 294 | for my $method ($module eq $Module_XS ? @PPOnlyMethods : @XSOnlyMethods) { | ||||
| 295 | *{"JSON::$method"} = sub { | ||||
| 296 | Carp::carp("$method is not supported in $module."); | ||||
| 297 | $_[0]; | ||||
| 298 | }; | ||||
| 299 | } | ||||
| 300 | |||||
| 301 | return 1; | ||||
| 302 | } | ||||
| 303 | |||||
| - - | |||||
| 306 | # | ||||
| 307 | # JSON Boolean | ||||
| 308 | # | ||||
| 309 | |||||
| 310 | package JSON::Boolean; | ||||
| 311 | |||||
| 312 | 1 | 500ns | my %Installed; | ||
| 313 | |||||
| 314 | sub _overrride_overload { | ||||
| 315 | 12 | 307µs | return if ($Installed{ $_[0] }++); | ||
| 316 | |||||
| 317 | my $boolean = $_[0] . '::Boolean'; | ||||
| 318 | |||||
| 319 | eval sprintf(q|     # spent    26µs executing statements in string eval # includes 29µs spent executing 1 call to 3 subs defined therein. # spent 18µs executing statements in string eval # includes 16µs spent executing 1 call to 3 subs defined therein. | ||||
| 320 | package %s; | ||||
| 321 | use overload ( | ||||
| 322 | '""' => sub { ${$_[0]} == 1 ? 'true' : 'false' }, | ||||
| 323 | 'eq' => sub { | ||||
| 324 | my ($obj, $op) = ref ($_[0]) ? ($_[0], $_[1]) : ($_[1], $_[0]); | ||||
| 325 | if ($op eq 'true' or $op eq 'false') { | ||||
| 326 | return "$obj" eq 'true' ? 'true' eq $op : 'false' eq $op; | ||||
| 327 | } | ||||
| 328 | else { | ||||
| 329 | return $obj ? 1 == $op : 0 == $op; | ||||
| 330 | } | ||||
| 331 | }, | ||||
| 332 | ); | ||||
| 333 | |, $boolean); | ||||
| 334 | |||||
| 335 | if ($@) { Carp::croak $@; } | ||||
| 336 | |||||
| 337 | return 1; | ||||
| 338 | } | ||||
| 339 | |||||
| 340 | |||||
| 341 | # | ||||
| 342 | # Helper classes for Backend Module (PP) | ||||
| 343 | # | ||||
| 344 | |||||
| 345 | package JSON::Backend::PP; | ||||
| 346 | |||||
| 347 | # spent 50µs within JSON::Backend::PP::init which was called:
#    once (50µs+0s) by JSON::_load_pp at line 275 | ||||
| 348 | 6 | 53µs | local $^W; | ||
| 349 | 3 | 131µs | 2 | 36µs | # spent 23µs (9+13) within JSON::Backend::PP::BEGIN@349 which was called:
#    once (9µs+13µs) by C4::Auth::BEGIN@23 at line 349     # spent    23µs making 1 call to JSON::Backend::PP::BEGIN@349
    # spent    13µs making 1 call to strict::unimport | 
| 350 | *{"JSON::decode_json"} = \&{"JSON::PP::decode_json"}; | ||||
| 351 | *{"JSON::encode_json"} = \&{"JSON::PP::encode_json"}; | ||||
| 352 | *{"JSON::PP::is_xs"} = sub { 0 }; | ||||
| 353 | *{"JSON::PP::is_pp"} = sub { 1 }; | ||||
| 354 | return 1; | ||||
| 355 | } | ||||
| 356 | |||||
| 357 | # | ||||
| 358 | # To save memory, the below lines are read only when XS backend is used. | ||||
| 359 | # | ||||
| 360 | |||||
| 361 | package JSON; | ||||
| 362 | |||||
| 363 | 1 | 44µs | 1; | ||
| 364 | __DATA__ |