Revision: 853
Author: tim.bunce
Date: Thu Aug  6 17:22:16 2009
Log: Finally got GraphViz file generation working in a reasonable way.
(Lots of scope for polish, but at least it's usable and useful now.)
Added entry for fake main::RUNTIME sub.

http://code.google.com/p/perl-devel-nytprof/source/detail?r=853

Modified:
  /trunk/Changes
  /trunk/NYTProf.xs
  /trunk/bin/nytprofhtml

=======================================
--- /trunk/Changes      Wed Aug  5 15:35:34 2009
+++ /trunk/Changes      Thu Aug  6 17:22:16 2009
@@ -10,7 +10,6 @@
  XXX subroutine profiler docs need update
  XXX doc findcaller option
  XXX note here and doc goto behaviour
-XXX set prereq version of Test::More

    Note: The file format has changed. Old files can't be read.

@@ -45,6 +44,12 @@
    Added interactive treemap view of package and subroutine times.
      Left-click to zoom in (drill-down) one level, right-click to zoom out.

+  Added generation of GraphViz dot language files to visualize
+    the call graph. A top-level link on the index page provides an
+    inter-package graph, and per-source-file links provide a graph
+    of sub calls in to, out of, and between the subs in the file.
+    See http://en.wikipedia.org/wiki/Graphviz
+
    Added columns to the main source code reports to show
      a count of sub calls and time spent in those calls.

=======================================
--- /trunk/NYTProf.xs   Thu Aug  6 16:33:35 2009
+++ /trunk/NYTProf.xs   Thu Aug  6 17:22:16 2009
@@ -3148,6 +3148,15 @@
              logwarn("Associating package of %s with %.*s (fid %d)\n",
                   sub_name, (int)filename_len, filename, fid );
      }
+
+    if (1) { /* Create a fake entry for main::RUNTIME subroutine */
+        char *runtime = "main::RUNTIME";
+        SV *sv;
+        /* get name of file that contained first profiled sub in 'main::'  
*/
+        SV *pkg_filename_sv = sub_pkg_filename_sv(aTHX_ runtime);
+        sv = *hv_fetch(hv, runtime, strlen(runtime), 1);
+        sv_setpvf(sv, "%s:%d-%d", SvPV_nolen(pkg_filename_sv), 1, 1);
+    }

      /* Iterate over PL_DBsub writing out fid and source line range of subs.
       * If filename is missing (i.e., because it's an xsub so has no source  
file)
=======================================
--- /trunk/bin/nytprofhtml      Wed Aug  5 15:35:34 2009
+++ /trunk/bin/nytprofhtml      Thu Aug  6 17:22:16 2009
@@ -96,7 +96,7 @@
  print "Generating report...\n";
  my $reporter = new Devel::NYTProf::Reader($opt{file});

-# place to store this crap
+# place to store this
  $reporter->output_dir($opt{out});

  # set formatting for html
@@ -284,9 +284,26 @@
          my ($profile, $filestr) = @_;

          my $sub_table = subroutine_table($profile, $filestr, undef, undef);
+
+        my $dot_file = html_safe_filename($filestr) . ".dot";
+        our %dot_file_generated;
+        if ($dot_file_generated{$dot_file}++) { # just once for  
line/block/sub
+            my $subs_in_file = $profile->subs_defined_in_file($filestr, 0);
+            # include subs defined in this file
+            # and/or called from subs defined in this file
+            my $sub_filter = sub {
+                my ($si, $calledby) = @_;
+                return 1 if not defined $calledby;
+                my $include = ($subs_in_file->{$si->subname}
+                            || $subs_in_file->{$calledby});
+                return $include;
+            };
+            output_subs_callgraph_dot_file($reporter, $dot_file,  
$sub_filter, 0);
+        }

          return qq{
          $sub_table
+        Call graph for these subroutines as a <a  
href="http://en.wikipedia.org/wiki/Graphviz";>Graphviz</a> <a  
href="$dot_file">dot language file</a>.
        <table border="1" cellpadding="0">
        <thead>
        <tr><th>Line</th>
@@ -874,17 +891,16 @@

      # gather link info
      my %sub2called_by;
-    my %pkg_subs;
      for my $subname (keys %$subinfos) {
          my $si = $subinfos->{$subname};
-
-        next if $sub_filter and $sub_filter->($si, undef);
+        next unless $si->calls; # skip subs never called
+
+        next if $sub_filter and not $sub_filter->($si, undef);

          my $called_by_subnames = $si->called_by_subnames;
          if (!%$called_by_subnames) {
              warn sprintf "%s has no caller subnames but a call count  
of %d\n",
-                    $subname, $si->calls
-                if $si->calls;
+                    $subname, $si->calls;
              next;
          }

@@ -899,9 +915,14 @@
          }

          $sub2called_by{$subname} = $called_by_subnames;
-        $pkg_subs{$si->package}{$subname} = $called_by_subnames;
      }

+    # list of all subs to be included in graph (has duplicates)
+    my %pkg_subs;
+    for (keys %sub2called_by, map { keys %$_ } values %sub2called_by) {
+        m/^(.*)::(.*)?$/ or warn "Strange sub name '$_'";
+        $pkg_subs{$1}{$_} = $sub2called_by{$_} || {};
+    }

  #stmt : node_stmt | edge_stmt | attr_stmt | ID '=' ID | subgraph
  #attr_stmt : (graph | node | edge) attr_list

--~--~---------~--~----~------------~-------~--~----~
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]
-~----------~----~----~----~------~----~------~--~---

Reply via email to