# 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!