# HG changeset patch # User Julien Bect # Date 1403541992 -7200 # lun. juin 23 18:46:32 2014 +0200 # Branch stable # Node ID 016e37cd0afd8a755caa41ebffea603a84e081cc # Parent 492c5614953571a0b07f4c1621cc7bc5c85c0251 New attempt to improve speed with templates... diff -r 492c56149535 -r 016e37cd0afd libinterp/corefcn/profiler.cc --- a/libinterp/corefcn/profiler.cc ven. juin 06 11:43:17 2014 -0400 +++ b/libinterp/corefcn/profiler.cc lun. juin 23 18:46:32 2014 +0200 @@ -32,29 +32,6 @@ #include "pager.h" #include "profiler.h" -profile_data_accumulator::enter::enter (profile_data_accumulator& a, - const std::string& f) - : acc (a) -{ - // FIXME: Add test for f != "" to prevent a blank line showing up - // in profiler statistics. See bug #39524. The root cause - // is that the function name is not set for the recurring readline - // hook function. - if (acc.is_active () && f != "") - { - fcn = f; - acc.enter_function (fcn); - } - else - fcn = ""; -} - -profile_data_accumulator::enter::~enter () -{ - if (fcn != "") - acc.exit_function (fcn); -} - profile_data_accumulator::stats::stats () : time (0.0), calls (0), recursive (false), parents (), children () diff -r 492c56149535 -r 016e37cd0afd libinterp/corefcn/profiler.h --- a/libinterp/corefcn/profiler.h ven. juin 06 11:43:17 2014 -0400 +++ b/libinterp/corefcn/profiler.h lun. juin 23 18:46:32 2014 +0200 @@ -39,17 +39,37 @@ // This is a utility class that can be used to call the enter/exit // functions in a manner protected from stack unwinding. - class enter + template class enter { private: profile_data_accumulator& acc; std::string fcn; + bool is_active; public: - enter (profile_data_accumulator&, const std::string&); - virtual ~enter (void); + enter (profile_data_accumulator& a, const T& t) : acc (a) + { + is_active = acc.is_active (); + + if (is_active) + { + fcn = t.profiler_name (); + + // NOTE: The test f != "" must be kept to prevent a blank line showing + // up in profiler statistics. See bug #39524. The root cause is that + // the function name is not set for the recurring readline hook function. + if (fcn != "") + acc.enter_function (fcn); + } + } + + ~enter () + { + if (is_active) + acc.exit_function (fcn); + } private: @@ -181,10 +201,12 @@ extern OCTINTERP_API profile_data_accumulator profiler; // Helper macro to profile a block of code. -#define BEGIN_PROFILER_BLOCK(name) \ + +#define BEGIN_PROFILER_BLOCK(classname) \ { \ - profile_data_accumulator::enter pe (profiler, (name)); + profile_data_accumulator::enter pe (profiler, *this) + #define END_PROFILER_BLOCK \ - } + } // end of block => call pe's destructor #endif diff -r 492c56149535 -r 016e37cd0afd libinterp/octave-value/ov-builtin.cc --- a/libinterp/octave-value/ov-builtin.cc ven. juin 06 11:43:17 2014 -0400 +++ b/libinterp/octave-value/ov-builtin.cc lun. juin 23 18:46:32 2014 +0200 @@ -127,7 +127,7 @@ try { - BEGIN_PROFILER_BLOCK (profiler_name ()) + BEGIN_PROFILER_BLOCK (octave_builtin); retval = (*f) (args, nargout); // Do not allow null values to be returned from functions. @@ -142,7 +142,7 @@ if (retval.length () == 1 && retval.xelem (0).is_undefined ()) retval.clear (); - END_PROFILER_BLOCK + END_PROFILER_BLOCK; } catch (octave_execution_exception) { diff -r 492c56149535 -r 016e37cd0afd libinterp/octave-value/ov-mex-fcn.cc --- a/libinterp/octave-value/ov-mex-fcn.cc ven. juin 06 11:43:17 2014 -0400 +++ b/libinterp/octave-value/ov-mex-fcn.cc lun. juin 23 18:46:32 2014 +0200 @@ -148,9 +148,11 @@ try { - BEGIN_PROFILER_BLOCK (profiler_name ()) + BEGIN_PROFILER_BLOCK (octave_mex_function); + retval = call_mex (have_fmex, mex_fcn_ptr, args, nargout, this); - END_PROFILER_BLOCK + + END_PROFILER_BLOCK; } catch (octave_execution_exception) { diff -r 492c56149535 -r 016e37cd0afd libinterp/octave-value/ov-usr-fcn.cc --- a/libinterp/octave-value/ov-usr-fcn.cc ven. juin 06 11:43:17 2014 -0400 +++ b/libinterp/octave-value/ov-usr-fcn.cc lun. juin 23 18:46:32 2014 +0200 @@ -149,9 +149,11 @@ frame.protect_var (tree_evaluator::statement_context); tree_evaluator::statement_context = tree_evaluator::script; - BEGIN_PROFILER_BLOCK (profiler_name ()) + BEGIN_PROFILER_BLOCK (octave_user_script); + cmd_list->accept (*current_evaluator); - END_PROFILER_BLOCK + + END_PROFILER_BLOCK; if (tree_return_command::returning) tree_return_command::returning = 0; @@ -574,7 +576,7 @@ frame.protect_var (tree_evaluator::statement_context); tree_evaluator::statement_context = tree_evaluator::function; - BEGIN_PROFILER_BLOCK (profiler_name ()) + BEGIN_PROFILER_BLOCK (octave_user_function); if (is_special_expr ()) { @@ -588,7 +590,7 @@ else cmd_list->accept (*current_evaluator); - END_PROFILER_BLOCK + END_PROFILER_BLOCK; if (echo_commands) print_code_function_trailer (); diff -r 492c56149535 -r 016e37cd0afd libinterp/parse-tree/pt-binop.cc --- a/libinterp/parse-tree/pt-binop.cc ven. juin 06 11:43:17 2014 -0400 +++ b/libinterp/parse-tree/pt-binop.cc lun. juin 23 18:46:32 2014 +0200 @@ -121,7 +121,7 @@ if (! error_state && b.is_defined ()) { - BEGIN_PROFILER_BLOCK ("binary " + oper ()) + BEGIN_PROFILER_BLOCK (tree_binary_expression); // Note: The profiler does not catch the braindead // short-circuit evaluation code above, but that should be @@ -134,7 +134,7 @@ if (error_state) retval = octave_value (); - END_PROFILER_BLOCK + END_PROFILER_BLOCK; } } } diff -r 492c56149535 -r 016e37cd0afd libinterp/parse-tree/pt-binop.h --- a/libinterp/parse-tree/pt-binop.h ven. juin 06 11:43:17 2014 -0400 +++ b/libinterp/parse-tree/pt-binop.h lun. juin 23 18:46:32 2014 +0200 @@ -107,6 +107,9 @@ void accept (tree_walker& tw); + std::string profiler_name (void) const { + return "binary " + oper (); } + protected: // The operands for the expression. diff -r 492c56149535 -r 016e37cd0afd libinterp/parse-tree/pt-unop.cc --- a/libinterp/parse-tree/pt-unop.cc ven. juin 06 11:43:17 2014 -0400 +++ b/libinterp/parse-tree/pt-unop.cc lun. juin 23 18:46:32 2014 +0200 @@ -73,14 +73,14 @@ if (! error_state) { - BEGIN_PROFILER_BLOCK ("prefix " + oper ()) - + BEGIN_PROFILER_BLOCK (tree_prefix_expression); + ref.do_unary_op (etype); if (! error_state) retval = ref.value (); - END_PROFILER_BLOCK + END_PROFILER_BLOCK; } } else @@ -89,7 +89,7 @@ if (! error_state && val.is_defined ()) { - BEGIN_PROFILER_BLOCK ("prefix " + oper ()) + BEGIN_PROFILER_BLOCK (tree_prefix_expression); // Attempt to do the operation in-place if it is unshared // (a temporary expression). @@ -101,7 +101,7 @@ if (error_state) retval = octave_value (); - END_PROFILER_BLOCK + END_PROFILER_BLOCK; } } } @@ -162,9 +162,11 @@ { retval = ref.value (); - BEGIN_PROFILER_BLOCK ("postfix " + oper ()) + BEGIN_PROFILER_BLOCK (tree_postfix_expression); + ref.do_unary_op (etype); - END_PROFILER_BLOCK + + END_PROFILER_BLOCK; } } else @@ -173,14 +175,14 @@ if (! error_state && val.is_defined ()) { - BEGIN_PROFILER_BLOCK ("postfix " + oper ()) + BEGIN_PROFILER_BLOCK (tree_postfix_expression); retval = ::do_unary_op (etype, val); if (error_state) retval = octave_value (); - END_PROFILER_BLOCK + END_PROFILER_BLOCK; } } } diff -r 492c56149535 -r 016e37cd0afd libinterp/parse-tree/pt-unop.h --- a/libinterp/parse-tree/pt-unop.h ven. juin 06 11:43:17 2014 -0400 +++ b/libinterp/parse-tree/pt-unop.h lun. juin 23 18:46:32 2014 +0200 @@ -108,6 +108,11 @@ void accept (tree_walker& tw); + std::string profiler_name (void) const + { + return "prefix " + oper (); + } + private: // No copying! @@ -145,6 +150,11 @@ void accept (tree_walker& tw); + std::string profiler_name (void) const + { + return "postfix " + oper (); + } + private: // No copying!