changeset 27369:5bf76ab4cce3

don't use stack to save and restore nargout value in evaluator (bug #56752) * pt-eval.h, pt-eval.cc (tree_evaluator::m_nargout): Reduce the overhead of saving and restoring the value of nargout in the evaluator by using an integer instead of a stack. The unwind_protect objects we use on the call stack already provide the stack of values needed to save and restore the value of nargout.
author John W. Eaton <jwe@octave.org>
date Wed, 28 Aug 2019 16:15:08 -0400
parents 71d9bd3332e4
children a2d3fa82b730
files libinterp/parse-tree/pt-eval.cc libinterp/parse-tree/pt-eval.h
diffstat 2 files changed, 15 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/parse-tree/pt-eval.cc	Tue Sep 03 14:24:15 2019 -0700
+++ b/libinterp/parse-tree/pt-eval.cc	Wed Aug 28 16:15:08 2019 -0400
@@ -2955,16 +2955,14 @@
         if (val.is_function ())
           fcn = val.function_value (true);
 
-        int nargout = m_nargout_stack.top ();
-
         if (fcn && ! (expr.is_postfix_indexed ()
                       && fcn->accepts_postfix_index (expr.postfix_index ())))
           {
-            retval = fcn->call (*this, nargout);
+            retval = fcn->call (*this, m_nargout);
           }
         else
           {
-            if (expr.print_result () && nargout == 0
+            if (expr.print_result () && m_nargout == 0
                 && statement_printing_enabled ())
               {
                 octave_value_list args = ovl (val);
@@ -3108,8 +3106,6 @@
   {
     octave_value_list retval;
 
-    int nargout = m_nargout_stack.top ();
-
     std::string type = idx_expr.type_tags ();
     std::list<tree_argument_list *> args = idx_expr.arg_lists ();
     std::list<string_vector> arg_nm = idx_expr.arg_names ();
@@ -3182,7 +3178,7 @@
               {
                 try
                   {
-                    retval = fcn->call (*this, nargout, first_args);
+                    retval = fcn->call (*this, m_nargout, first_args);
                   }
                 catch (index_exception& e)
                   {
@@ -3260,7 +3256,7 @@
 
                     octave_value_list tmp_list
                       = base_expr_val.subsref (type.substr (beg, i-beg),
-                                               idx_list, nargout);
+                                               idx_list, m_nargout);
 
                     partial_expr_val
                       = tmp_list.length () ? tmp_list(0) : octave_value ();
@@ -3341,7 +3337,7 @@
             try
               {
                 retval = base_expr_val.subsref (type.substr (beg, n-beg),
-                                                idx_list, nargout);
+                                                idx_list, m_nargout);
                 beg = n;
                 idx_list.clear ();
               }
@@ -3379,7 +3375,7 @@
                     // FIXME: Do we ever need the names of the arguments
                     // passed to FCN here?
 
-                    retval = fcn->call (*this, nargout, final_args);
+                    retval = fcn->call (*this, m_nargout, final_args);
                   }
                 catch (index_exception& e)
                   {
@@ -3415,7 +3411,7 @@
                 final_args = idx_list.front ();
               }
 
-            retval = fcn->call (*this, nargout, final_args);
+            retval = fcn->call (*this, m_nargout, final_args);
           }
       }
 
@@ -3688,9 +3684,7 @@
   void
   tree_evaluator::visit_constant (tree_constant& expr)
   {
-    int nargout = m_nargout_stack.top ();
-
-    if (nargout > 1)
+    if (m_nargout > 1)
       error ("invalid number of output arguments for constant expression");
 
     push_result (expr.value ());
@@ -4420,9 +4414,8 @@
 
         assert (f);
 
-        int nargout = m_nargout_stack.top ();
-
-        push_result (f->call (*this, nargout));
+        push_result (f->call (*this, m_nargout));
+
         return;
       }
 
@@ -4472,9 +4465,9 @@
   {
     unwind_protect frame;
 
-    m_nargout_stack.push (nargout);
-
-    frame.add_method (m_nargout_stack, &value_stack<int>::pop);
+    frame.protect_var (m_nargout);
+
+    m_nargout = nargout;
 
     expr->accept (*this);
   }
--- a/libinterp/parse-tree/pt-eval.h	Tue Sep 03 14:24:15 2019 -0700
+++ b/libinterp/parse-tree/pt-eval.h	Wed Aug 28 16:15:08 2019 -0400
@@ -132,7 +132,7 @@
       : m_interpreter (interp), m_statement_context (SC_OTHER),
         m_result_type (RT_UNDEFINED), m_expr_result_value (),
         m_expr_result_value_list (), m_lvalue_list_stack (),
-        m_nargout_stack (), m_autoload_map (), m_bp_table (*this),
+        m_nargout (0), m_autoload_map (), m_bp_table (*this),
         m_call_stack (*this), m_profiler (), m_debug_frame (0),
         m_debug_mode (false), m_quiet_breakpoint_flag (false),
         m_debugger_stack (), m_max_recursion_depth (256),
@@ -829,7 +829,7 @@
 
     value_stack<const std::list<octave_lvalue>*> m_lvalue_list_stack;
 
-    value_stack<int> m_nargout_stack;
+    int m_nargout;
 
     // List of autoloads (function -> file mapping).
     std::map<std::string, std::string> m_autoload_map;