changeset 22131:fdbe2eab2aef

fix profiler initialization (bug #46315) * profile.m: When turning profiler on, just enable it, don't reset it. * profiler.cc (profile_data_accumulator::profile_data_accumulator): Create new call tree on initialization. Initialize active_fcn to 0. (profile_data_accumulator::~profile_data_accumulator): Always delete call_tree. (profile_data_accumulator::set_acive): Simply set enabled flag. (profile_data_accumulator::enter_function): Don't call add_current_time if active_fcn isn't valid. If active_fcn isn't set, set it to call_tree. (profile_data_accumulator::exit_function): Don't to anything if there is no active_fcn. (profile_data_accumulator::add_current_time): Likewise. (profile_data_accumulator::reset): Reinitialize call_tree and active_fcn.
author John W. Eaton <jwe@octave.org>
date Fri, 15 Jul 2016 16:08:55 -0400
parents d4f385635257
children 27b63b55bacb
files libinterp/corefcn/profiler.cc scripts/profiler/profile.m
diffstat 2 files changed, 36 insertions(+), 44 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/profiler.cc	Mon Jul 18 07:36:23 2016 -0700
+++ b/libinterp/corefcn/profiler.cc	Fri Jul 15 16:08:55 2016 -0400
@@ -176,34 +176,18 @@
 
 profile_data_accumulator::profile_data_accumulator ()
   : known_functions (), fcn_index (),
-    enabled (false), call_tree (0), last_time (-1.0)
-{}
+    enabled (false), call_tree (new tree_node (0, 0)),
+    active_fcn (0), last_time (-1.0)
+{ }
 
 profile_data_accumulator::~profile_data_accumulator ()
 {
-  if (call_tree)
-    delete call_tree;
+  delete call_tree;
 }
 
 void
 profile_data_accumulator::set_active (bool value)
 {
-  if (value)
-    {
-      // Create a call-tree top-node if there isn't yet one.
-      if (! call_tree)
-        call_tree = new tree_node (0, 0);
-
-      // Let the top-node be the active one.  This ensures we have a clean
-      // fresh start collecting times.
-      active_fcn = call_tree;
-    }
-  else
-    {
-      // Make sure we start with fresh timing if we're re-enabled later.
-      last_time = -1.0;
-    }
-
   enabled = value;
 }
 
@@ -216,7 +200,7 @@
 
   // If there is already an active function, add to its time before
   // pushing the new one.
-  if (active_fcn != call_tree)
+  if (active_fcn && active_fcn != call_tree)
     add_current_time ();
 
   // Map the function's name to its index.
@@ -231,7 +215,11 @@
   else
     fcn_idx = pos->second;
 
+  if (! active_fcn)
+    active_fcn = call_tree;
+
   active_fcn = active_fcn->enter (fcn_idx);
+
   last_time = query_time ();
 
 }
@@ -239,26 +227,29 @@
 void
 profile_data_accumulator::exit_function (const std::string& fcn)
 {
-  assert (call_tree);
-  // FIXME: This assert statements doesn't make sense if profile() is called
-  //        from within a function hierarchy to begin with.  See bug #39587.
-  //assert (active_fcn != call_tree);
+  if (active_fcn)
+    {
+      assert (call_tree);
+      // FIXME: This assert statements doesn't make sense if profile() is called
+      //        from within a function hierarchy to begin with.  See bug #39587.
+      //assert (active_fcn != call_tree);
 
-  // Usually, if we are disabled this function is not even called.  But the
-  // call disabling the profiler is an exception.  So also check here
-  // and only record the time if enabled.
-  if (is_active ())
-    add_current_time ();
+      // Usually, if we are disabled this function is not even called.  But the
+      // call disabling the profiler is an exception.  So also check here
+      // and only record the time if enabled.
+      if (is_active ())
+        add_current_time ();
 
-  fcn_index_map::iterator pos = fcn_index.find (fcn);
-  // FIXME: This assert statements doesn't make sense if profile() is called
-  //        from within a function hierarchy to begin with.  See bug #39587.
-  //assert (pos != fcn_index.end ());
-  active_fcn = active_fcn->exit (pos->second);
+      fcn_index_map::iterator pos = fcn_index.find (fcn);
+      // FIXME: This assert statements doesn't make sense if profile() is called
+      //        from within a function hierarchy to begin with.  See bug #39587.
+      //assert (pos != fcn_index.end ());
+      active_fcn = active_fcn->exit (pos->second);
 
-  // If this was an "inner call", we resume executing the parent function
-  // up the stack.  So note the start-time for this!
-  last_time = query_time ();
+      // If this was an "inner call", we resume executing the parent function
+      // up the stack.  So note the start-time for this!
+      last_time = query_time ();
+    }
 }
 
 void
@@ -273,7 +264,8 @@
   if (call_tree)
     {
       delete call_tree;
-      call_tree = 0;
+      call_tree = new tree_node (0, 0);
+      active_fcn = 0;
     }
 
   last_time = -1.0;
@@ -382,11 +374,12 @@
 void
 profile_data_accumulator::add_current_time (void)
 {
-  const double t = query_time ();
-  assert (last_time >= 0.0 && last_time <= t);
+  if (active_fcn)
+    {
+      const double t = query_time ();
 
-  assert (call_tree && active_fcn != call_tree);
-  active_fcn->add_time (t - last_time);
+      active_fcn->add_time (t - last_time);
+    }
 }
 
 profile_data_accumulator profiler;
--- a/scripts/profiler/profile.m	Mon Jul 18 07:36:23 2016 -0700
+++ b/scripts/profiler/profile.m	Fri Jul 15 16:08:55 2016 -0400
@@ -69,7 +69,6 @@
 
   switch (option)
     case "on"
-      __profiler_reset__ ();
       __profiler_enable__ (true);
 
     case "off"