Revision: 1269
Author: [email protected]
Date: Sat Jun 5 15:40:22 2010
Log: This now, finally, seems to do-the-right-thing for e.g. anon-subs that
get merged
when the string evals that create them get merged.
NYTProf data model hacking is beyond painful!
On the plus side, a profile of perlcritic is now usable because the
thousands
of string evals defining anon subs in PPI::Node::_wanted, now get collapsed
into
just a few different evals that have distinct source code (4196->4 in my
case),
and the thousands of anon subs also get collapsed (to 4 in my case).
http://code.google.com/p/perl-devel-nytprof/source/detail?r=1269
Modified:
/trunk/bin/nytprofhtml
/trunk/lib/Devel/NYTProf/Data.pm
/trunk/lib/Devel/NYTProf/FileInfo.pm
/trunk/lib/Devel/NYTProf/SubInfo.pm
/trunk/t/test13.rdt
/trunk/t/test22-strevala.rdt
/trunk/t/test24-strevalc.rdt
/trunk/t/test50-disable.rdt
/trunk/t/test51-enable.rdt
/trunk/t/test61-submerge.rdt
/trunk/t/test62-subcaller1.rdt
=======================================
--- /trunk/bin/nytprofhtml Sun May 30 01:30:17 2010
+++ /trunk/bin/nytprofhtml Sat Jun 5 15:40:22 2010
@@ -446,14 +446,14 @@
push @callers, [$fid, $_, @{$fid_line_info->{$_}}] for
keys %$fid_line_info;
}
my $total_calls = sum(my @caller_calls = map { $_->[2] } @callers);
- my $max_calls = max(@caller_calls);
- my $avg_per_call = fmt_time($sub_info->incl_time / $total_calls);
-
- push @prologue, sprintf "# spent %s within %s which was called%s",
+
+ push @prologue, sprintf "# spent %s within %s which was called%s:",
fmt_incl_excl_time($sub_info->incl_time, $sub_info->excl_time),
- $sub_info->subname, ($total_calls <= 1)
- ? ""
- : " $total_calls times, avg ${avg_per_call}/call:";
+ $sub_info->subname,
+ ($total_calls <= 1) ? ""
+ : sprintf(" %d times, avg %s/call",
+ $total_calls, fmt_time($sub_info->incl_time /
$total_calls));
+ my $max_calls = max(@caller_calls);
# order by most frequent caller first, then by time
@callers = sort { $b->[2] <=> $a->[2] || $b->[3] <=> $a->[3] }
@callers;
@@ -461,16 +461,23 @@
for my $caller (@callers) {
my ($fid, $line, $count, $incl_time, $excl_time, undef, undef,
undef, undef, $calling_subs) = @$caller;
- my $caller_fi = $profile->fileinfo_of($fid);
-
- my @subnames = sort keys %$calling_subs;
+
+ my @subnames = sort keys %{$calling_subs || {}};
ref $_ and $_ = sprintf "%s (merge of %d subs)", $_->[0],
scalar @$_
for @subnames;
my $subname = (@subnames) ? " by " . join(" or ",
@subnames) : "";
- my $avg_time =
- ($count <= 1)
- ? ""
- : sprintf ", avg %s/call", fmt_time($incl_time / $count);
+
+ my $caller_fi = $profile->fileinfo_of($fid);
+ if (!$caller_fi) { # should never happen
+ warn sprintf "Caller of %s, from fid %d line %d has no
fileinfo (%s)",
+ $sub_info, $fid, $line, $subname;
+ die 2;
+ next;
+ }
+
+ my $avg_time = "";
+ $avg_time = sprintf ", avg %s/call", fmt_time($incl_time /
$count)
+ if $count > 1;
my $times = sprintf " (%s+%s)", fmt_time($excl_time),
fmt_time($incl_time - $excl_time);
=======================================
--- /trunk/lib/Devel/NYTProf/Data.pm Tue Jun 1 13:59:18 2010
+++ /trunk/lib/Devel/NYTProf/Data.pm Sat Jun 5 15:40:22 2010
@@ -43,7 +43,7 @@
use warnings;
use strict;
-use Carp;
+use Carp qw(carp croak cluck);
use Cwd qw(getcwd);
use Scalar::Util qw(blessed);
@@ -101,13 +101,13 @@
$_ and bless $_ => $sub_class for values %$sub_subinfo;
- # find called subs that have no file for
+ # find subs that have calls but no fid
my @homeless_subs = grep { $_->calls and not $_->fid }
values %$sub_subinfo;
if (@homeless_subs) { # give them a home...
# currently just the first existing fileinfo
# XXX ought to create a new dummy fileinfo for them
my $new_fi = $profile->fileinfo_of(1);
- $_->alter_fileinfo(undef, $new_fi) for @homeless_subs;
+ $_->_alter_fileinfo(undef, $new_fi) for @homeless_subs;
}
@@ -200,6 +200,18 @@
return { %{ shift->{sub_subinfo} } }; # shallow copy
}
+sub _disconnect_subinfo {
+ my ($self, $si) = @_;
+ my $subname = $si->subname;
+ my $si2 = delete $self->{sub_subinfo}{$subname};
+ # sanity check
+ carp sprintf "disconnect_subinfo: deleted entry %s %s doesn't match
argument %s %s",
+ ($si2) ? ($si2, $si2->subname) : ('undef', 'undef'),
+ $si, $subname
+ if $si2 != $si or $si2->subname ne $subname;
+ # do more?
+}
+
# package_tree_subinfo_map is like package_subinfo_map but returns
# nested data instead of flattened.
@@ -331,12 +343,12 @@
my ($self, $subname) = @_;
if (not defined $subname) {
- carp "Can't resolve subinfo of undef value";
+ cluck "Can't resolve subinfo of undef value";
return undef;
}
my $si = $self->{sub_subinfo}{$subname}
- or warn carp "Can't resolve subinfo of '$subname'";
+ or cluck "Can't resolve subinfo of '$subname'";
return $si;
}
=======================================
--- /trunk/lib/Devel/NYTProf/FileInfo.pm Tue Jun 1 13:59:18 2010
+++ /trunk/lib/Devel/NYTProf/FileInfo.pm Sat Jun 5 15:40:22 2010
@@ -2,6 +2,7 @@
use strict;
+use Carp;
use List::Util qw(sum max);
use Devel::NYTProf::Util qw(strip_prefix_from_paths);
@@ -74,21 +75,6 @@
}
-sub _delete_eval {
- my ($self, $eval_fi) = @_;
-
- my $eval_fis = $self->[NYTP_FIDi_HAS_EVALS()]
- or return;
- my $count = @$eval_fis;
- @$eval_fis = grep { $_ != $eval_fi } @$eval_fis;
- warn "_delete_eval missed" if @$eval_fis == $count;
-
- # XXX needs to update NYTP_FIDi_SUBS_DEFINED NYTP_FIDi_SUBS_CALLED
- # by moving relevant data up to the parent
-
- return;
-}
-
# return subs defined as list of SubInfo objects
sub subs_defined {
@@ -106,23 +92,23 @@
}
sub _remove_sub_defined {
- my ($self, $subinfo) = @_;
- delete $self->[NYTP_FIDi_SUBS_DEFINED()]->{$subinfo->subname};
+ my ($self, $si) = @_;
+ my $subname = $si->subname;
+ delete $self->[NYTP_FIDi_SUBS_DEFINED()]->{$subname}
+ or carp sprintf "_remove_sub_defined: sub %s wasn't defined
in %d %s",
+ $subname, $self->fid, $self->filename;
}
sub _add_new_sub_defined {
my ($self, $subinfo) = @_;
- my $subs_defined = $self->[NYTP_FIDi_SUBS_DEFINED()];
- if (my $existing_si = $subs_defined->{$subinfo->subname}) {
- warn sprintf "Merging %s sub into existing sub with same name
in %s\n",
- $subinfo->subname, $self->filename;
- $existing_si->merge_in($subinfo);
- @$subinfo = (); # zap!
- }
- else {
- $subs_defined->{$subinfo->subname} = $subinfo;
- }
-
+ my $subname = $subinfo->subname;
+ my $subs_defined = $self->[NYTP_FIDi_SUBS_DEFINED()] ||= {};
+ my $existing_si = $subs_defined->{$subname};
+ croak sprintf "sub %s already defined in fid %d %s",
+ $subname, $self->fid, $self->filename
+ if $existing_si;
+
+ $subs_defined->{$subname} = $subinfo;
}
@@ -149,8 +135,8 @@
{
42 => {
- 'pkg1::foo' => [ 1, 0.02093 ],
- 'pkg1::bar' => [ 1, 0.00154 ],
+ 'pkg1::foo' => [ 1, 0.02093 ],
+ 'pkg1::bar' => [ 1, 0.00154 ],
},
}
@@ -271,19 +257,22 @@
sub collapse_sibling_evals {
- my ($self, $survivor, @donors) = @_;
+ my ($self, $survivor_fi, @donors) = @_;
my $profile = $self->profile;
die "Can't collapse_sibling_evals of non-sibling evals"
- if grep { $_->eval_fid != $survivor->eval_fid or
- $_->eval_line != $survivor->eval_line
+ if grep { $_->eval_fid != $survivor_fi->eval_fid or
+ $_->eval_line != $survivor_fi->eval_line
} @donors;
- my $s_ltd = $survivor->line_time_data; # XXX line only
- my $s_scl = $survivor->sub_call_lines;
+ my $s_ltd = $survivor_fi->line_time_data; # XXX line only
+ my $s_scl = $survivor_fi->sub_call_lines;
for my $donor_fi (@donors) {
- # copy data from donor to survivor then delete donor
+ # copy data from donor to survivor_fi then delete donor
+ warn sprintf "collapse_sibling_evals: processing donor
fid %d: %s\n",
+ $donor_fi->fid, $donor_fi->filename
+ if $trace;
# XXX nested evals not handled yet
warn sprintf "collapse_sibling_evals: nested evals in %s not
handled",
@@ -291,49 +280,37 @@
if $donor_fi->has_evals;
if (my @subs_defined = $donor_fi->subs_defined) {
- warn "collapse_sibling_evals: subs defined not fully handled"
- if $trace;
for my $si (@subs_defined) {
- warn sprintf "Moving fid %d sub %s\n",
- $donor_fi->fid, $si->subname
+ warn sprintf " - moving from fid %d: sub %s\n",
+ $donor_fi->fid, $si->subname
if $trace;
- $donor_fi->_remove_sub_defined($si);
- $survivor->_add_new_sub_defined($si);
- $si->_move_to_fileinfo($survivor);
+ $si->_alter_fileinfo($donor_fi, $survivor_fi);
+ warn sprintf " - moving done\n"
+ if $trace;
}
}
- # '1' => { 'main::foo' => [ 1, '1.38e-05', '1.24e-05', ...,
{ 'main::RUNTIME' => undef } ] }
+ # 1 => { 'main::foo' => [ 1, '1.38e-05', '1.24e-05', ...,
{ 'main::RUNTIME' => undef } ] }
if (my $sub_call_lines = $donor_fi->sub_call_lines) {
- my %subnames_called;
+ my %subnames_called_by_donor;
# merge details of subs called from $donor_fi
while ( my ($line, $sc_hash) = each %$sub_call_lines ) {
my $s_sc_hash = $s_scl->{$line} ||= {};
- while ( my ($subname, $sc_info) = each %$sc_hash ) {
+ for my $subname (keys %$sc_hash ) {
my $s_sc_info = $s_sc_hash->{$subname} ||= [];
- $subnames_called{$subname}++;
-
- if (@$s_sc_info) { # need to merge
- $s_sc_info->[$_] += $sc_info->[$_]
- for 0..5; # XXX
- $s_sc_info->[$_] = max($s_sc_info->[$_],
$sc_info->[$_])
- for (NYTP_SCi_REC_DEPTH);
- $s_sc_info->[NYTP_SCi_CALLING_SUB]->{$_} = undef
- for keys %{ $sc_info->[NYTP_SCi_CALLING_SUB] };
- }
- else {
- @$s_sc_info = @$sc_info;
- }
+
+
Devel::NYTProf::SubInfo::_merge_in_caller_info($s_sc_info, delete
$sc_hash->{$subname}, "eval"); # XXX
+ $subnames_called_by_donor{$subname}++;
}
}
%$sub_call_lines = (); # zap
# update subinfo
- $profile->subinfo_of($_)->alter_fileinfo($donor_fi, $survivor)
- for keys %subnames_called;
+ $profile->subinfo_of($_)->_alter_called_by_fileinfo($donor_fi,
$survivor_fi)
+ for keys %subnames_called_by_donor;
}
@@ -344,17 +321,77 @@
my $s_tld_l = $s_ltd->[$line] ||= [];
$s_tld_l->[$_] += $d_tld_l->[$_] for (0...@$d_tld_l-1);
warn sprintf "%d:%d: @$s_tld_l from @$d_tld_l fid:%d\n",
- $survivor->fid, $line, $donor_fi->fid if 0;
+ $survivor_fi->fid, $line, $donor_fi->fid if 0;
}
- push @{ $survivor->meta->{merged_fids} }, $donor_fi->fid;
- ++$survivor->meta->{merged_fids_src_varied}
- if $donor_fi->src_digest ne $survivor->src_digest;
-
- $self->_delete_eval($donor_fi);
+ push @{ $survivor_fi->meta->{merged_fids} }, $donor_fi->fid;
+ ++$survivor_fi->meta->{merged_fids_src_varied}
+ if $donor_fi->src_digest ne $survivor_fi->src_digest;
+
+ # remove eval from NYTP_FIDi_HAS_EVALS
+ if (my $eval_fis = $self->[NYTP_FIDi_HAS_EVALS()]) {
+ my $count = @$eval_fis;
+ @$eval_fis = grep { $_ != $donor_fi } @$eval_fis;
+ warn "_delete_eval missed" if @$eval_fis == $count;
+ # XXX needs to update NYTP_FIDi_SUBS_DEFINED
NYTP_FIDi_SUBS_CALLED ?
+ }
+
$donor_fi->_nullify;
}
- return $survivor;
+
+ # look for any anon subs that are effectively duplicates
+ # (ie have the same name except for eval seqn)
+ # if more than one for any given name we merge them
+ if (my @subs_defined = $survivor_fi->subs_defined_sorted) {
+ # bucket by normalized name
+ my %newname;
+ for my $si (@subs_defined) {
+ next unless $si->is_anon;
+ (my $newname = $si->subname) =~ s/ \( ((?:re_)?) eval \s \d+
\) /(${1}eval 0)/xg;
+ push @{ $newname{$newname} }, $si;
+ }
+
+ while ( my ($newname, $to_merge) = each %newname ) {
+ my $survivor_si = shift @$to_merge;
+ next unless @$to_merge; # nothing to do
+
+ my $survivor_subname = $survivor_si->subname;
+ warn sprintf "collapse_sibling_evals: merging %d subs
into %s: %s\n",
+ scalar @$to_merge, $survivor_subname,
+ join ", ", map { $_->subname } @$to_merge
+ if $trace;
+
+ for my $delete_si (@$to_merge) {
+ my $delete_subname = $delete_si->subname;
+
+ # for every file that called this sub, find the lines that
made the calls
+ # and change the name to the new sub
+ for my $caller_fid ($delete_si->caller_fids) {
+ my $caller_fi = $profile->fileinfo_of($caller_fid);
+ # sub_call_lines ==> { line => { sub => ... } }
+ for my $subs_called_on_line (values %{
$caller_fi->sub_call_lines }) {
+ my $sc_info = delete
$subs_called_on_line->{$delete_subname}
+ or next;
+ if (my $s_sc_info =
$subs_called_on_line->{$survivor_subname}) {
+
Devel::NYTProf::SubInfo::_merge_in_caller_info($s_sc_info, $sc_info); # XXX
+ }
+ else {
+ $subs_called_on_line->{$survivor_subname} =
$sc_info;
+ }
+ }
+ }
+
+ $survivor_si->merge_in($delete_si);
+ $survivor_fi->_remove_sub_defined($delete_si);
+ $profile->_disconnect_subinfo($delete_si);
+ }
+ }
+ }
+
+ warn sprintf "collapse_sibling_evals done\n"
+ if $trace;
+
+ return $survivor_fi;
}
@@ -487,10 +524,12 @@
if (not $opts->{skip_internal_details}) {
for my $si ($self->subs_defined_sorted) {
+ my ($fl, $ll) = ($si->first_line, $si->last_line);
+ defined $_ or $_ = 'undef' for ($fl, $ll);
printf $fh "%s%s%s%s%s%s-%s\n",
$prefix, 'sub', $separator,
$si->subname(' and '), $separator,
- $si->first_line, $si->last_line;
+ $fl, $ll;
}
# { line => { subname => [...] }, ... }
=======================================
--- /trunk/lib/Devel/NYTProf/SubInfo.pm Tue Jun 1 13:59:18 2010
+++ /trunk/lib/Devel/NYTProf/SubInfo.pm Sat Jun 5 15:40:22 2010
@@ -12,11 +12,21 @@
NYTP_SIi_CALL_COUNT NYTP_SIi_INCL_RTIME NYTP_SIi_EXCL_RTIME
NYTP_SIi_SUB_NAME NYTP_SIi_PROFILE
NYTP_SIi_REC_DEPTH NYTP_SIi_RECI_RTIME NYTP_SIi_CALLED_BY
-
+ NYTP_SIi_elements
+
+ NYTP_SCi_CALL_COUNT
NYTP_SCi_INCL_RTIME NYTP_SCi_EXCL_RTIME NYTP_SCi_RECI_RTIME
- NYTP_SCi_CALLING_SUB
+ NYTP_SCi_REC_DEPTH NYTP_SCi_CALLING_SUB
+ NYTP_SCi_elements
);
+# extra constants for private elements
+use constant {
+ NYTP_SIi_meta => NYTP_SIi_elements + 1,
+ NYTP_SIi_cache => NYTP_SIi_elements + 2,
+};
+
+
my $trace = (($ENV{NYTPROF}||'') =~ m/\b trace=(\d+) /x) && $1; # XXX a
hack
sub fid { shift->[NYTP_SIi_FID] || 0 }
@@ -54,6 +64,13 @@
sub recur_max_depth { shift->[NYTP_SIi_REC_DEPTH] }
sub recur_incl_time { shift->[NYTP_SIi_RECI_RTIME] }
+
+
+# general purpose hash - mainly a hack to help kill off Reader.pm
+sub meta { shift->[NYTP_SIi_meta()] ||= {} }
+# general purpose cache
+sub cache { shift->[NYTP_SIi_cache()] ||= {} }
+
# { fid => { line => [ count, incl_time ] } }
sub caller_fid_line_places {
@@ -95,6 +112,10 @@
return 1 if $self->subname =~ m/(?:^CORE::|::CORE:)\w+$/;
return 0;
}
+
+sub is_anon {
+ shift->subname =~ m/::__ANON__\b/;
+}
sub kind {
my $self = shift;
@@ -111,11 +132,6 @@
}
$self->profile->fileinfo_of($fid);
}
-
-sub _move_to_fileinfo {
- my ($self, $fi) = @_;
- $self->[NYTP_SIi_FID] = $fi->fid;
-}
sub clone { # shallow
my $self = shift;
@@ -141,14 +157,24 @@
}
-sub alter_fileinfo {
+sub _alter_fileinfo {
my ($self, $remove_fi, $new_fi) = @_;
my $remove_fid = ($remove_fi) ? $remove_fi->fid : 0;
my $new_fid = ( $new_fi) ? $new_fi->fid : 0;
- warn sprintf "Altering fileinfo of %s from %d to %d\n",
- $self->subname, $remove_fid, $new_fid
- if $trace;
+ if ($self->fid == $remove_fid) {
+ $self->[NYTP_SIi_FID] = $new_fid;
+
+ $remove_fi->_remove_sub_defined($self) if $remove_fi;
+ $new_fi->_add_new_sub_defined($self) if $new_fi;
+ }
+}
+
+
+sub _alter_called_by_fileinfo {
+ my ($self, $remove_fi, $new_fi) = @_;
+ my $remove_fid = ($remove_fi) ? $remove_fi->fid : 0;
+ my $new_fid = ( $new_fi) ? $new_fi->fid : 0;
# remove mentions of $remove_fid from called-by details
# { fid => { line => [ count, incl, excl, ... ] } }
@@ -156,11 +182,16 @@
my $cb = delete $called_by->{$remove_fid};
if ($cb && $new_fid) {
+
+ warn sprintf "Altering %s to change calls from fid %d to be
from fid %d\n",
+ $self->subname, $remove_fid, $new_fid
+ if $trace;
+
if (my $new_cb = $called_by->{$new_fid}) {
# need to merge $cb into $new_cb
while ( my ($line, $cb_li) = each %$cb ) {
my $dst_line_info = $new_cb->{$line} ||= [];
- _merge_in_caller_info($dst_line_info, $cb->{$line});
+ _merge_in_caller_info($dst_line_info, delete
$cb->{$line}, $self->subname);
}
}
else {
@@ -169,32 +200,9 @@
}
}
- if ($self->fid == $remove_fid) {
- $self->[NYTP_SIi_FID] = $new_fid;
- }
-
- if ($remove_fi and $remove_fi->_remove_sub_defined($self)) {
- $new_fi->_add_new_sub_defined($self);
- }
}
-sub _rename {
- my ($self, $newname) = @_;
-
- my $oldname = $self->[NYTP_SIi_SUB_NAME];
- return if $newname eq $oldname;
-
- $self->[NYTP_SIi_SUB_NAME] = $newname;
-
- $self->fileinfo->_rename_subinfo($self, $newname);
-
- my $callers = $self->caller_fid_line_places || {};
- for my $sc (map { values %$_ } values %$callers) {
- my $caller_subnames = $sc->[NYTP_SCi_CALLING_SUB];
- }
-
-}
# merge details of another sub into this one
@@ -202,75 +210,97 @@
# it's meant for merging things like anon-subs in evals
# e.g., "PPI::Node::__ANON__[(eval 286)[PPI/Node.pm:642]:4]"
sub merge_in {
- my $self = shift;
- my $new = shift;
+ my ($self, $donor, %opts) = @_;
+ my $self_subname = $self->subname;
+ my $donor_subname = $donor->subname;
+
+ warn sprintf "Merging sub %s into %s (%s)\n",
+ $donor_subname, $self_subname, join(" ", %opts)
+ if $trace;
# see also "case NYTP_TAG_SUB_CALLERS:" in
load_profile_data_from_stream()
-
- if ($new->[NYTP_SIi_SUB_NAME] ne $self->[NYTP_SIi_SUB_NAME]) {
- $self->[NYTP_SIi_SUB_NAME] = [ $self->[NYTP_SIi_SUB_NAME] ]
- if not ref $self->[NYTP_SIi_SUB_NAME];
- push @{$self->[NYTP_SIi_SUB_NAME]}, $new->[NYTP_SIi_SUB_NAME];
- }
-
- $self->[NYTP_SIi_FIRST_LINE] = _min($self->[NYTP_SIi_FIRST_LINE],
$new->[NYTP_SIi_FIRST_LINE]);
- $self->[NYTP_SIi_LAST_LINE] = _max($self->[NYTP_SIi_LAST_LINE],
$new->[NYTP_SIi_LAST_LINE]);
- $self->[NYTP_SIi_CALL_COUNT] += $new->[NYTP_SIi_CALL_COUNT];
- $self->[NYTP_SIi_INCL_RTIME] += $new->[NYTP_SIi_INCL_RTIME];
- $self->[NYTP_SIi_EXCL_RTIME] += $new->[NYTP_SIi_EXCL_RTIME];
- $self->[NYTP_SIi_REC_DEPTH] = max($self->[NYTP_SIi_REC_DEPTH],
$new->[NYTP_SIi_REC_DEPTH]);
+ push @{ $self->meta->{merged_sub_names} }, $donor->subname;
+
+ $self->[NYTP_SIi_FIRST_LINE] = _min($self->[NYTP_SIi_FIRST_LINE],
$donor->[NYTP_SIi_FIRST_LINE]);
+ $self->[NYTP_SIi_LAST_LINE] = _max($self->[NYTP_SIi_LAST_LINE],
$donor->[NYTP_SIi_LAST_LINE]);
+ $self->[NYTP_SIi_CALL_COUNT] += $donor->[NYTP_SIi_CALL_COUNT];
+ $self->[NYTP_SIi_INCL_RTIME] += $donor->[NYTP_SIi_INCL_RTIME];
+ $self->[NYTP_SIi_EXCL_RTIME] += $donor->[NYTP_SIi_EXCL_RTIME];
+ $self->[NYTP_SIi_REC_DEPTH] = max($self->[NYTP_SIi_REC_DEPTH],
$donor->[NYTP_SIi_REC_DEPTH]);
# adding reci_rtime is correct only if one sub doesn't call the other
- $self->[NYTP_SIi_RECI_RTIME] += $new->[NYTP_SIi_RECI_RTIME]; # XXX
+ $self->[NYTP_SIi_RECI_RTIME] += $donor->[NYTP_SIi_RECI_RTIME]; # XXX
# { fid => { line => [ count, incl_time, ... ] } }
- my $dst_called_by = $self->[NYTP_SIi_CALLED_BY] ||= {};
- my $src_called_by = $new ->[NYTP_SIi_CALLED_BY] || {};
-
- my $subname = $self->subname(' and ');
+ my $dst_called_by = $self ->[NYTP_SIi_CALLED_BY] ||= {};
+ my $src_called_by = $donor->[NYTP_SIi_CALLED_BY] || {};
# iterate over src and merge into dst
while (my ($fid, $src_line_hash) = each %$src_called_by) {
+
my $dst_line_hash = $dst_called_by->{$fid};
- if (!$dst_line_hash) {
- $dst_called_by->{$fid} = $src_line_hash;
- warn "renamed sub caller $self->[NYTP_SIi_SUB_NAME] into
$subname\n" if $trace;
- next;
- }
- warn "merged sub caller $self->[NYTP_SIi_SUB_NAME] into
$subname\n" if $trace;
+ #if (!$dst_line_hash) { $dst_called_by->{$fid} = $src_line_hash;
next; }
# merge lines in %$src_line_hash into %$dst_line_hash
- while (my ($line, $src_line_info) = each %$src_line_hash) {
+ for my $line (keys %$src_line_hash) {
my $dst_line_info = $dst_line_hash->{$line} ||= [];
- _merge_in_caller_info($dst_line_info, $src_line_info);
+ _merge_in_caller_info($dst_line_info, delete
$src_line_hash->{$line}, "merge in $donor_subname");
}
}
+
return;
}
sub _merge_in_caller_info {
- my ($dst_line_info, $src_line_info) = @_;
-
+ my ($dst_line_info, $src_line_info, $tag) = @_;
+ $tag = ($tag) ? " $tag" : "";
+
+ if (!...@$src_line_info) {
+ carp sprintf "_merge_in_caller_info%s skipped (empty donor)", $tag
+ if $trace;
+ return;
+ }
if (!...@$dst_line_info) {
- @$dst_line_info = @$src_line_info;
- }
- else {
-
- # merge @$src_line_info into @$dst_line_info
- $dst_line_info->[$_] += $src_line_info->[$_] for (
- NYTP_SCi_INCL_RTIME, NYTP_SCi_EXCL_RTIME,
- );
- # ug, we can't really combine recursive incl_time, but this is
better than undef
- $dst_line_info->[NYTP_SCi_RECI_RTIME] =
max($dst_line_info->[NYTP_SCi_RECI_RTIME],
-
$src_line_info->[NYTP_SCi_RECI_RTIME]);
-
- my $src_cs = $src_line_info->[NYTP_SCi_CALLING_SUB]||={};
- my $dst_cs = $dst_line_info->[NYTP_SCi_CALLING_SUB]||={};
- $dst_cs->{$_} = $src_cs->{$_} for keys %$src_cs;
- }
+ @$dst_line_info = (0) x NYTP_SCi_elements;
+ $dst_line_info->[NYTP_SCi_CALLING_SUB] = undef;
+ }
+
+ if ($trace) {
+ carp sprintf "_merge_in_caller_info%s merging:", $tag;
+ warn sprintf " . %s\n", fmt_sc($src_line_info);
+ warn sprintf " + %s\n", fmt_sc($dst_line_info);
+ }
+
+ # merge @$src_line_info into @$dst_line_info
+ $dst_line_info->[$_] += $src_line_info->[$_] for (
+ NYTP_SCi_CALL_COUNT, NYTP_SCi_INCL_RTIME, NYTP_SCi_EXCL_RTIME,
+ );
+ $dst_line_info->[NYTP_SCi_REC_DEPTH] =
max($dst_line_info->[NYTP_SCi_REC_DEPTH],
+
$src_line_info->[NYTP_SCi_REC_DEPTH]);
+ # ug, we can't really combine recursive incl_time, but this is better
than undef
+ $dst_line_info->[NYTP_SCi_RECI_RTIME] =
max($dst_line_info->[NYTP_SCi_RECI_RTIME],
+
$src_line_info->[NYTP_SCi_RECI_RTIME]);
+
+ my $src_cs = $src_line_info->[NYTP_SCi_CALLING_SUB]|| {};
+ my $dst_cs = $dst_line_info->[NYTP_SCi_CALLING_SUB]||={};
+ $dst_cs->{$_} = $src_cs->{$_} for keys %$src_cs;
+
+ warn sprintf " = %s\n", fmt_sc($dst_line_info)
+ if $trace;
+
+ @$src_line_info = (); # zap!
+
return;
}
+sub fmt_sc {
+ my ($sc) = @_;
+ my $dst_cs = $sc->[NYTP_SCi_CALLING_SUB]||{};
+ my $by = join " & ", sort keys %$dst_cs;
+ sprintf "calls %d%s",
+ $sc->[NYTP_SCi_CALL_COUNT], ($by) ? ", by $by" : "";
+}
+
sub caller_fids {
my ($self, $merge_evals) = @_;
@@ -376,6 +406,13 @@
$fid, $line, $separator,
join(" ", map { defined($_) ? $_ : 'undef' } @sc);
}
+
+ # where a sub has had others merged into it, list them
+ my $merge_subs = $self->meta->{merged_sub_names} || [];
+ for my $ms (sort @$merge_subs) {
+ printf $fh "%s%s%s%s\n",
+ $prefix, 'merge_donor', $separator, $ms;
+ }
}
# vim:ts=8:sw=4:et
=======================================
--- /trunk/t/test13.rdt Tue Jun 1 04:28:28 2010
+++ /trunk/t/test13.rdt Sat Jun 5 15:40:22 2010
@@ -29,6 +29,7 @@
fid_fileinfo 1 sub main::bar 7-9
fid_fileinfo 1 sub main::baz 11-17
fid_fileinfo 1 sub main::foo 3-5
+fid_fileinfo 1 sub main::x undef-undef
fid_fileinfo 1 call 4 main::CORE:print [ 3 0 0 0 0 0 0
main::foo ]
fid_fileinfo 1 call 8 main::CORE:print [ 1 0 0 0 0 0 0
main::bar ]
fid_fileinfo 1 call 12 main::CORE:print [ 1 0 0 0 0 0 0
main::baz ]
=======================================
--- /trunk/t/test22-strevala.rdt Tue Jun 1 13:42:18 2010
+++ /trunk/t/test22-strevala.rdt Sat Jun 5 15:40:22 2010
@@ -21,57 +21,41 @@
fid_block_time 2 2 [ 0 1 ]
fid_block_time 3 1 [ 0 1 ]
fid_block_time 3 2 [ 0 1 ]
-fid_block_time 4 1 [ 0 1 ]
-fid_block_time 4 2 [ 0 1 ]
fid_block_time 5 2 [ 0 2 ]
fid_block_time 6 1 [ 0 1 ]
fid_block_time 6 2 [ 0 1 ]
-fid_block_time 7 1 [ 0 1 ]
-fid_block_time 7 2 [ 0 1 ]
fid_fileinfo 1 [ test22-strevala.p 1 2 0 0 ]
fid_fileinfo 1 sub main::BEGIN 0-0
fid_fileinfo 1 sub main::CORE:print 0-0
fid_fileinfo 1 sub main::RUNTIME 1-1
fid_fileinfo 1 call 6 main::__ANON__[(eval 1)[test22-strevala.p:6]:1] [ 1
0 0 0 0 0 0 main::RUNTIME ]
-fid_fileinfo 1 call 9 main::__ANON__[(eval 2)[test22-strevala.p:9]:1] [ 1
0 0 0 0 0 0 main::RUNTIME ]
-fid_fileinfo 1 call 9 main::__ANON__[(eval 3)[test22-strevala.p:9]:1] [ 1
0 0 0 0 0 0 main::RUNTIME ]
+fid_fileinfo 1 call 9 main::__ANON__[(eval 2)[test22-strevala.p:9]:1] [ 2
0 0 0 0 0 0 main::RUNTIME ]
fid_fileinfo 1 eval 6 [ count 1 nested 0 merged 0 ]
-fid_fileinfo 1 eval 9 [ count 2 nested 0 merged 0 ]
-fid_fileinfo 1 eval 12 [ count 1 nested 2 merged 0 ]
+fid_fileinfo 1 eval 9 [ count 1 nested 0 merged 1 ]
+fid_fileinfo 1 eval 12 [ count 1 nested 1 merged 0 ]
fid_fileinfo 2 [ (eval 1)[test22-strevala.p:6] 1 6 2 2 0 0 ]
fid_fileinfo 2 sub main::__ANON__[(eval 1)[test22-strevala.p:6]:1]
1-1
fid_fileinfo 2 call 1 main::CORE:print [ 1 0 0 0 0 0 0
main::__ANON__[(eval 1)[test22-strevala.p:6]:1] ]
fid_fileinfo 3 [ (eval 2)[test22-strevala.p:9] 1 9 3 2 0 0 ]
fid_fileinfo 3 sub main::__ANON__[(eval 2)[test22-strevala.p:9]:1]
1-1
-fid_fileinfo 3 call 1 main::CORE:print [ 1 0 0 0 0 0 0
main::__ANON__[(eval 2)[test22-strevala.p:9]:1] ]
-fid_fileinfo 4 [ (eval 3)[test22-strevala.p:9] 1 9 4 2 0 0 ]
-fid_fileinfo 4 sub main::__ANON__[(eval 3)[test22-strevala.p:9]:1]
1-1
-fid_fileinfo 4 call 1 main::CORE:print [ 1 0 0 0 0 0 0
main::__ANON__[(eval 3)[test22-strevala.p:9]:1] ]
+fid_fileinfo 3 call 1 main::CORE:print [ 2 0 0 0 0 0 0
main::__ANON__[(eval 2)[test22-strevala.p:9]:1]|main::__ANON__[(eval
3)[test22-strevala.p:9]:1] ]
fid_fileinfo 5 [ (eval 4)[test22-strevala.p:12] 1 12 5 2 0 0 ]
-fid_fileinfo 5 call 2 main::__ANON__[(eval 5)[(eval
4)[test22-strevala.p:12]:2]:1] [ 1 0 0 0 0 0 0 main::RUNTIME ]
-fid_fileinfo 5 call 2 main::__ANON__[(eval 6)[(eval
4)[test22-strevala.p:12]:2]:1] [ 1 0 0 0 0 0 0 main::RUNTIME ]
-fid_fileinfo 5 eval 2 [ count 2 nested 0 merged 0 ]
+fid_fileinfo 5 call 2 main::__ANON__[(eval 5)[(eval
4)[test22-strevala.p:12]:2]:1] [ 2 0 0 0 0 0 0 main::RUNTIME ]
+fid_fileinfo 5 eval 2 [ count 1 nested 0 merged 1 ]
fid_fileinfo 6 [ (eval 5)[(eval 4)[test22-strevala.p:12]:2] 5 2 6 2 0
0 ]
fid_fileinfo 6 sub main::__ANON__[(eval 5)[(eval
4)[test22-strevala.p:12]:2]:1] 1-1
-fid_fileinfo 6 call 1 main::CORE:print [ 1 0 0 0 0 0 0
main::__ANON__[(eval 5)[(eval 4)[test22-strevala.p:12]:2]:1] ]
-fid_fileinfo 7 [ (eval 6)[(eval 4)[test22-strevala.p:12]:2] 5 2 7 2 0
0 ]
-fid_fileinfo 7 sub main::__ANON__[(eval 6)[(eval
4)[test22-strevala.p:12]:2]:1] 1-1
-fid_fileinfo 7 call 1 main::CORE:print [ 1 0 0 0 0 0 0
main::__ANON__[(eval 6)[(eval 4)[test22-strevala.p:12]:2]:1] ]
+fid_fileinfo 6 call 1 main::CORE:print [ 2 0 0 0 0 0 0
main::__ANON__[(eval 6)[(eval 4)[test22-strevala.p:12]:2]:1]|
main::__ANON__[(eval 5)[(eval 4)[test22-strevala.p:12]:2]:1] ]
fid_line_time 1 3 [ 0 1 ]
fid_line_time 1 6 [ 0 1 ]
fid_line_time 1 9 [ 0 2 ]
fid_line_time 1 12 [ 0 1 ]
fid_line_time 2 1 [ 0 1 ]
fid_line_time 2 2 [ 0 1 ]
-fid_line_time 3 1 [ 0 1 ]
-fid_line_time 3 2 [ 0 1 ]
-fid_line_time 4 1 [ 0 1 ]
-fid_line_time 4 2 [ 0 1 ]
+fid_line_time 3 1 [ 0 2 ]
+fid_line_time 3 2 [ 0 2 ]
fid_line_time 5 2 [ 0 2 ]
-fid_line_time 6 1 [ 0 1 ]
-fid_line_time 6 2 [ 0 1 ]
-fid_line_time 7 1 [ 0 1 ]
-fid_line_time 7 2 [ 0 1 ]
+fid_line_time 6 1 [ 0 2 ]
+fid_line_time 6 2 [ 0 2 ]
fid_sub_time 1 3 [ 0 1 ]
fid_sub_time 1 6 [ 0 1 ]
fid_sub_time 1 9 [ 0 2 ]
@@ -80,31 +64,23 @@
fid_sub_time 2 2 [ 0 1 ]
fid_sub_time 3 1 [ 0 1 ]
fid_sub_time 3 2 [ 0 1 ]
-fid_sub_time 4 1 [ 0 1 ]
-fid_sub_time 4 2 [ 0 1 ]
fid_sub_time 5 2 [ 0 2 ]
fid_sub_time 6 1 [ 0 1 ]
fid_sub_time 6 2 [ 0 1 ]
-fid_sub_time 7 1 [ 0 1 ]
-fid_sub_time 7 2 [ 0 1 ]
profile_modes fid_block_time block
profile_modes fid_line_time line
profile_modes fid_sub_time sub
sub_subinfo main::BEGIN [ 1:0-0 calls 0 times 0 0 0 0 ]
sub_subinfo main::CORE:print [ 1:0-0 calls 5 times 0 0 0 0 ]
sub_subinfo main::CORE:print called_by 2:1 [ 1 0 0 0 0 0 0
main::__ANON__[(eval 1)[test22-strevala.p:6]:1] ]
-sub_subinfo main::CORE:print called_by 3:1 [ 1 0 0 0 0 0 0
main::__ANON__[(eval 2)[test22-strevala.p:9]:1] ]
-sub_subinfo main::CORE:print called_by 4:1 [ 1 0 0 0 0 0 0
main::__ANON__[(eval 3)[test22-strevala.p:9]:1] ]
-sub_subinfo main::CORE:print called_by 6:1 [ 1 0 0 0 0 0 0
main::__ANON__[(eval 5)[(eval 4)[test22-strevala.p:12]:2]:1] ]
-sub_subinfo main::CORE:print called_by 7:1 [ 1 0 0 0 0 0 0
main::__ANON__[(eval 6)[(eval 4)[test22-strevala.p:12]:2]:1] ]
+sub_subinfo main::CORE:print called_by 3:1 [ 2 0 0 0 0 0 0
main::__ANON__[(eval 2)[test22-strevala.p:9]:1]|main::__ANON__[(eval
3)[test22-strevala.p:9]:1] ]
+sub_subinfo main::CORE:print called_by 6:1 [ 2 0 0 0 0 0 0
main::__ANON__[(eval 6)[(eval 4)[test22-strevala.p:12]:2]:1]|
main::__ANON__[(eval 5)[(eval 4)[test22-strevala.p:12]:2]:1] ]
sub_subinfo main::RUNTIME [ 1:1-1 calls 0 times 0 0 0 0 ]
sub_subinfo main::__ANON__[(eval 1)[test22-strevala.p:6]:1] [ 2:1-1 calls
1 times 0 0 0 0 ]
sub_subinfo main::__ANON__[(eval 1)[test22-strevala.p:6]:1] called_by 1:6
[ 1 0 0 0 0 0 0 main::RUNTIME ]
-sub_subinfo main::__ANON__[(eval 2)[test22-strevala.p:9]:1] [ 3:1-1 calls
1 times 0 0 0 0 ]
-sub_subinfo main::__ANON__[(eval 2)[test22-strevala.p:9]:1] called_by 1:9
[ 1 0 0 0 0 0 0 main::RUNTIME ]
-sub_subinfo main::__ANON__[(eval 3)[test22-strevala.p:9]:1] [ 4:1-1 calls
1 times 0 0 0 0 ]
-sub_subinfo main::__ANON__[(eval 3)[test22-strevala.p:9]:1] called_by 1:9
[ 1 0 0 0 0 0 0 main::RUNTIME ]
-sub_subinfo main::__ANON__[(eval 5)[(eval 4)[test22-strevala.p:12]:2]:1] [
6:1-1 calls 1 times 0 0 0 0 ]
-sub_subinfo main::__ANON__[(eval 5)[(eval 4)[test22-strevala.p:12]:2]:1]
called_by 5:2 [ 1 0 0 0 0 0 0 main::RUNTIME ]
-sub_subinfo main::__ANON__[(eval 6)[(eval 4)[test22-strevala.p:12]:2]:1] [
7:1-1 calls 1 times 0 0 0 0 ]
-sub_subinfo main::__ANON__[(eval 6)[(eval 4)[test22-strevala.p:12]:2]:1]
called_by 5:2 [ 1 0 0 0 0 0 0 main::RUNTIME ]
+sub_subinfo main::__ANON__[(eval 2)[test22-strevala.p:9]:1] [ 3:1-1 calls
2 times 0 0 0 0 ]
+sub_subinfo main::__ANON__[(eval 2)[test22-strevala.p:9]:1] called_by 1:9
[ 2 0 0 0 0 0 0 main::RUNTIME ]
+sub_subinfo main::__ANON__[(eval 2)[test22-strevala.p:9]:1] merge_donor
main::__ANON__[(eval 3)[test22-strevala.p:9]:1]
+sub_subinfo main::__ANON__[(eval 5)[(eval 4)[test22-strevala.p:12]:2]:1] [
6:1-1 calls 2 times 0 0 0 0 ]
+sub_subinfo main::__ANON__[(eval 5)[(eval 4)[test22-strevala.p:12]:2]:1]
called_by 5:2 [ 2 0 0 0 0 0 0 main::RUNTIME ]
+sub_subinfo main::__ANON__[(eval 5)[(eval 4)[test22-strevala.p:12]:2]:1]
merge_donor main::__ANON__[(eval 6)[(eval 4)[test22-strevala.p:12]:2]:1]
=======================================
--- /trunk/t/test24-strevalc.rdt Tue Jun 1 13:42:18 2010
+++ /trunk/t/test24-strevalc.rdt Sat Jun 5 15:40:22 2010
@@ -22,11 +22,10 @@
fid_block_time 6 1 [ 0 1 ]
fid_block_time 7 1 [ 0 1 ]
fid_block_time 8 1 [ 0 2 ]
-fid_block_time 9 1 [ 0 2 ]
fid_fileinfo 1 [ test24-strevalc.p 1 2 0 0 ]
fid_fileinfo 1 sub main::BEGIN 0-0
fid_fileinfo 1 sub main::RUNTIME 1-1
-fid_fileinfo 1 eval 8 [ count 5 nested 2 merged 1 ]
+fid_fileinfo 1 eval 8 [ count 4 nested 2 merged 2 ]
fid_fileinfo 2 [ (eval 1)[test24-strevalc.p:8] 1 8 2 2 0 0 ]
fid_fileinfo 4 [ (eval 3)[test24-strevalc.p:8] 1 8 4 2 0 0 ]
fid_fileinfo 4 eval 1 [ count 1 nested 0 merged 0 ]
@@ -36,10 +35,7 @@
fid_fileinfo 7 [ (eval 6)[(eval 5)[test24-strevalc.p:8]:1] 6 1 7 2 0 0
]
fid_fileinfo 8 [ (eval 7)[test24-strevalc.p:8] 1 8 8 2 0 0 ]
fid_fileinfo 8 sub main::__ANON__[(eval 7)[test24-strevalc.p:8]:1]
1-1
-fid_fileinfo 8 call 1 main::__ANON__[(eval 7)[test24-strevalc.p:8]:1] [ 1
0 0 0 0 0 0 main::RUNTIME ]
-fid_fileinfo 9 [ (eval 8)[test24-strevalc.p:8] 1 8 9 2 0 0 ]
-fid_fileinfo 9 sub main::__ANON__[(eval 8)[test24-strevalc.p:8]:1]
1-1
-fid_fileinfo 9 call 1 main::__ANON__[(eval 8)[test24-strevalc.p:8]:1] [ 1
0 0 0 0 0 0 main::RUNTIME ]
+fid_fileinfo 8 call 1 main::__ANON__[(eval 7)[test24-strevalc.p:8]:1] [ 2
0 0 0 0 0 0 main::RUNTIME ]
fid_line_time 1 2 [ 0 1 ]
fid_line_time 1 7 [ 0 1 ]
fid_line_time 1 8 [ 0 6 ]
@@ -48,8 +44,7 @@
fid_line_time 5 1 [ 0 1 ]
fid_line_time 6 1 [ 0 1 ]
fid_line_time 7 1 [ 0 1 ]
-fid_line_time 8 1 [ 0 2 ]
-fid_line_time 9 1 [ 0 2 ]
+fid_line_time 8 1 [ 0 4 ]
fid_sub_time 1 2 [ 0 1 ]
fid_sub_time 1 7 [ 0 1 ]
fid_sub_time 1 8 [ 0 6 ]
@@ -59,13 +54,11 @@
fid_sub_time 6 1 [ 0 1 ]
fid_sub_time 7 1 [ 0 1 ]
fid_sub_time 8 1 [ 0 2 ]
-fid_sub_time 9 1 [ 0 2 ]
profile_modes fid_block_time block
profile_modes fid_line_time line
profile_modes fid_sub_time sub
sub_subinfo main::BEGIN [ 1:0-0 calls 0 times 0 0 0 0 ]
sub_subinfo main::RUNTIME [ 1:1-1 calls 0 times 0 0 0 0 ]
-sub_subinfo main::__ANON__[(eval 7)[test24-strevalc.p:8]:1] [ 8:1-1 calls
1 times 0 0 0 0 ]
-sub_subinfo main::__ANON__[(eval 7)[test24-strevalc.p:8]:1] called_by 8:1
[ 1 0 0 0 0 0 0 main::RUNTIME ]
-sub_subinfo main::__ANON__[(eval 8)[test24-strevalc.p:8]:1] [ 9:1-1 calls
1 times 0 0 0 0 ]
-sub_subinfo main::__ANON__[(eval 8)[test24-strevalc.p:8]:1] called_by 9:1
[ 1 0 0 0 0 0 0 main::RUNTIME ]
+sub_subinfo main::__ANON__[(eval 7)[test24-strevalc.p:8]:1] [ 8:1-1 calls
2 times 0 0 0 0 ]
+sub_subinfo main::__ANON__[(eval 7)[test24-strevalc.p:8]:1] called_by 8:1
[ 2 0 0 0 0 0 0 main::RUNTIME ]
+sub_subinfo main::__ANON__[(eval 7)[test24-strevalc.p:8]:1] merge_donor
main::__ANON__[(eval 8)[test24-strevalc.p:8]:1]
=======================================
--- /trunk/t/test50-disable.rdt Tue Jun 1 04:28:28 2010
+++ /trunk/t/test50-disable.rdt Sat Jun 5 15:40:22 2010
@@ -18,6 +18,7 @@
fid_block_time 1 4 [ 0 1 ]
fid_block_time 1 5 [ 0 1 ]
fid_fileinfo 1 [ test50-disable.p 1 2 0 0 ]
+fid_fileinfo 1 sub DB::disable_profile 0-0
fid_fileinfo 1 sub main::BEGIN 0-0
fid_fileinfo 1 sub main::RUNTIME 1-1
fid_fileinfo 1 call 2 DB::disable_profile [ 1 0 0 0 0 0 0
main::RUNTIME ]
=======================================
--- /trunk/t/test51-enable.rdt Tue Jun 1 04:28:28 2010
+++ /trunk/t/test51-enable.rdt Sat Jun 5 15:40:22 2010
@@ -19,6 +19,7 @@
fid_block_time 1 7 [ 0 1 ]
fid_block_time 1 16 [ 0 1 ]
fid_fileinfo 1 [ test51-enable.p 1 2 0 0 ]
+fid_fileinfo 1 sub DB::disable_profile 0-0
fid_fileinfo 1 sub main::BEGIN 0-0
fid_fileinfo 1 sub main::CORE:unlink 0-0
fid_fileinfo 1 sub main::RUNTIME 1-1
=======================================
--- /trunk/t/test61-submerge.rdt Tue Jun 1 13:42:18 2010
+++ /trunk/t/test61-submerge.rdt Sat Jun 5 15:40:22 2010
@@ -18,47 +18,27 @@
fid_block_time 1 8 [ 0 2 ]
fid_block_time 2 1 [ 0 1 ]
fid_block_time 2 2 [ 0 1 ]
-fid_block_time 3 1 [ 0 1 ]
-fid_block_time 3 2 [ 0 1 ]
-fid_block_time 4 1 [ 0 1 ]
-fid_block_time 4 2 [ 0 1 ]
fid_fileinfo 1 [ test61-submerge.p 1 2 0 0 ]
fid_fileinfo 1 sub main::BEGIN 0-0
fid_fileinfo 1 sub main::CORE:print 0-0
fid_fileinfo 1 sub main::RUNTIME 1-1
fid_fileinfo 1 sub main::foo 4-4
fid_fileinfo 1 call 4 main::CORE:print [ 3 0 0 0 0 0 0
main::foo ]
-fid_fileinfo 1 call 8 main::__ANON__[(eval 1)[test61-submerge.p:8]:1] [ 1
0 0 0 0 0 0 main::RUNTIME ]
-fid_fileinfo 1 call 8 main::__ANON__[(eval 2)[test61-submerge.p:8]:1] [ 1
0 0 0 0 0 0 main::RUNTIME ]
-fid_fileinfo 1 call 8 main::__ANON__[(eval 3)[test61-submerge.p:8]:1] [ 1
0 0 0 0 0 0 main::RUNTIME ]
-fid_fileinfo 1 eval 8 [ count 3 nested 0 merged 0 ]
+fid_fileinfo 1 call 8 main::__ANON__[(eval 1)[test61-submerge.p:8]:1] [ 3
0 0 0 0 0 0 main::RUNTIME ]
+fid_fileinfo 1 eval 8 [ count 1 nested 0 merged 2 ]
fid_fileinfo 2 [ (eval 1)[test61-submerge.p:8] 1 8 2 2 0 0 ]
fid_fileinfo 2 sub main::__ANON__[(eval 1)[test61-submerge.p:8]:1]
1-1
-fid_fileinfo 2 call 1 main::foo [ 1 0 0 0 0 0 0 main::__ANON__[(eval
1)[test61-submerge.p:8]:1] ]
-fid_fileinfo 3 [ (eval 2)[test61-submerge.p:8] 1 8 3 2 0 0 ]
-fid_fileinfo 3 sub main::__ANON__[(eval 2)[test61-submerge.p:8]:1]
1-1
-fid_fileinfo 3 call 1 main::foo [ 1 0 0 0 0 0 0 main::__ANON__[(eval
2)[test61-submerge.p:8]:1] ]
-fid_fileinfo 4 [ (eval 3)[test61-submerge.p:8] 1 8 4 2 0 0 ]
-fid_fileinfo 4 sub main::__ANON__[(eval 3)[test61-submerge.p:8]:1]
1-1
-fid_fileinfo 4 call 1 main::foo [ 1 0 0 0 0 0 0 main::__ANON__[(eval
3)[test61-submerge.p:8]:1] ]
+fid_fileinfo 2 call 1 main::foo [ 3 0 0 0 0 0 0 main::__ANON__[(eval
2)[test61-submerge.p:8]:1]|main::__ANON__[(eval 1)[test61-submerge.p:8]:1]|
main::__ANON__[(eval 3)[test61-submerge.p:8]:1] ]
fid_line_time 1 4 [ 0 3 ]
fid_line_time 1 6 [ 0 1 ]
fid_line_time 1 8 [ 0 2 ]
-fid_line_time 2 1 [ 0 1 ]
-fid_line_time 2 2 [ 0 1 ]
-fid_line_time 3 1 [ 0 1 ]
-fid_line_time 3 2 [ 0 1 ]
-fid_line_time 4 1 [ 0 1 ]
-fid_line_time 4 2 [ 0 1 ]
+fid_line_time 2 1 [ 0 3 ]
+fid_line_time 2 2 [ 0 3 ]
fid_sub_time 1 4 [ 0 3 ]
fid_sub_time 1 6 [ 0 1 ]
fid_sub_time 1 8 [ 0 2 ]
fid_sub_time 2 1 [ 0 1 ]
fid_sub_time 2 2 [ 0 1 ]
-fid_sub_time 3 1 [ 0 1 ]
-fid_sub_time 3 2 [ 0 1 ]
-fid_sub_time 4 1 [ 0 1 ]
-fid_sub_time 4 2 [ 0 1 ]
profile_modes fid_block_time block
profile_modes fid_line_time line
profile_modes fid_sub_time sub
@@ -66,13 +46,9 @@
sub_subinfo main::CORE:print [ 1:0-0 calls 3 times 0 0 0 0 ]
sub_subinfo main::CORE:print called_by 1:4 [ 3 0 0 0 0 0 0
main::foo ]
sub_subinfo main::RUNTIME [ 1:1-1 calls 0 times 0 0 0 0 ]
-sub_subinfo main::__ANON__[(eval 1)[test61-submerge.p:8]:1] [ 2:1-1 calls
1 times 0 0 0 0 ]
-sub_subinfo main::__ANON__[(eval 1)[test61-submerge.p:8]:1] called_by 1:8
[ 1 0 0 0 0 0 0 main::RUNTIME ]
-sub_subinfo main::__ANON__[(eval 2)[test61-submerge.p:8]:1] [ 3:1-1 calls
1 times 0 0 0 0 ]
-sub_subinfo main::__ANON__[(eval 2)[test61-submerge.p:8]:1] called_by 1:8
[ 1 0 0 0 0 0 0 main::RUNTIME ]
-sub_subinfo main::__ANON__[(eval 3)[test61-submerge.p:8]:1] [ 4:1-1 calls
1 times 0 0 0 0 ]
-sub_subinfo main::__ANON__[(eval 3)[test61-submerge.p:8]:1] called_by 1:8
[ 1 0 0 0 0 0 0 main::RUNTIME ]
+sub_subinfo main::__ANON__[(eval 1)[test61-submerge.p:8]:1] [ 2:1-1 calls
3 times 0 0 0 0 ]
+sub_subinfo main::__ANON__[(eval 1)[test61-submerge.p:8]:1] called_by 1:8
[ 3 0 0 0 0 0 0 main::RUNTIME ]
+sub_subinfo main::__ANON__[(eval 1)[test61-submerge.p:8]:1] merge_donor
main::__ANON__[(eval 2)[test61-submerge.p:8]:1]
+sub_subinfo main::__ANON__[(eval 1)[test61-submerge.p:8]:1] merge_donor
main::__ANON__[(eval 3)[test61-submerge.p:8]:1]
sub_subinfo main::foo [ 1:4-4 calls 3 times 0 0 0 0 ]
-sub_subinfo main::foo called_by 2:1 [ 1 0 0 0 0 0 0 main::__ANON__[(eval
1)[test61-submerge.p:8]:1] ]
-sub_subinfo main::foo called_by 3:1 [ 1 0 0 0 0 0 0 main::__ANON__[(eval
2)[test61-submerge.p:8]:1] ]
-sub_subinfo main::foo called_by 4:1 [ 1 0 0 0 0 0 0 main::__ANON__[(eval
3)[test61-submerge.p:8]:1] ]
+sub_subinfo main::foo called_by 2:1 [ 3 0 0 0 0 0 0 main::__ANON__[(eval
2)[test61-submerge.p:8]:1]|main::__ANON__[(eval 1)[test61-submerge.p:8]:1]|
main::__ANON__[(eval 3)[test61-submerge.p:8]:1] ]
=======================================
--- /trunk/t/test62-subcaller1.rdt Tue Jun 1 04:28:28 2010
+++ /trunk/t/test62-subcaller1.rdt Sat Jun 5 15:40:22 2010
@@ -39,6 +39,7 @@
fid_block_time 2 11 [ 0 1 ]
fid_block_time 2 15 [ 0 1 ]
fid_fileinfo 1 [ test62-subcaller1.p 1 2 0 0 ]
+fid_fileinfo 1 sub Devel::NYTProf::Test::example_xsub
undef-undef
fid_fileinfo 1 sub MyTie::FETCH 7-7
fid_fileinfo 1 sub MyTie::STORE 8-8
fid_fileinfo 1 sub MyTie::TIESCALAR 6-6
--
You've received this message because you are subscribed to
the Devel::NYTProf Development User group.
Group hosted at: http://groups.google.com/group/develnytprof-dev
Project hosted at: http://perl-devel-nytprof.googlecode.com
CPAN distribution: http://search.cpan.org/dist/Devel-NYTProf
To post, email: [email protected]
To unsubscribe, email: [email protected]