# HG changeset patch # User John W. Eaton # Date 1468613335 14400 # Fri Jul 15 16:08:55 2016 -0400 # Node ID 2188aff56b51aaa1ece08fefaea823ceb0f26cac # Parent 879f297f31945a259f30f1a0032a13f42320880e 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. diff --git a/libinterp/corefcn/profiler.cc b/libinterp/corefcn/profiler.cc --- a/libinterp/corefcn/profiler.cc +++ b/libinterp/corefcn/profiler.cc @@ -176,34 +176,18 @@ profile_data_accumulator::tree_node::get 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 @@ profile_data_accumulator::enter_function // 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 @@ profile_data_accumulator::enter_function 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 @@ profile_data_accumulator::enter_function 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 @@ profile_data_accumulator::reset (void) 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 @@ profile_data_accumulator::query_time (vo 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; diff --git a/scripts/profiler/profile.m b/scripts/profiler/profile.m --- a/scripts/profiler/profile.m +++ b/scripts/profiler/profile.m @@ -69,7 +69,6 @@ function retval = profile (option) switch (option) case "on" - __profiler_reset__ (); __profiler_enable__ (true); case "off"