From 14df02056f872dcdbd8b61f69900c84c79a800a4 Mon Sep 17 00:00:00 2001
From: Arne Goedeke <el@laramies.com>
Date: Fri, 2 Aug 2013 20:21:41 +0200
Subject: [PATCH] [performance] do not assume that `== can modify call_outs

the call_out data structures in backends are protected again reentrance,
so we can safely assume that `== does never modify the call_out hash
table. this change makes backend_find_call_out significantly faster and
speeds up the corresponding call_out handling benchmark by 25%. It is
still _much_ slower than in 7.8, probably because call_outs are objects
in 7.9, which introduces quite some overhead.
---
 src/backend.cmod | 24 +++++-------------------
 1 file changed, 5 insertions(+), 19 deletions(-)

diff --git a/src/backend.cmod b/src/backend.cmod
index 2c5bc69f35..24e9d23981 100644
--- a/src/backend.cmod
+++ b/src/backend.cmod
@@ -1010,7 +1010,6 @@ PIKECLASS Backend
      {
        size_t hval, fun_hval;
        struct Backend_CallOut_struct *c;
-       struct svalue *save_sp;
        
        if(!me->num_pending_calls) return -1;
        
@@ -1031,11 +1030,11 @@ PIKECLASS Backend
 	 }
        }
        /* Note: is_eq() may call Pike code (which we want),
-	*       but Pike code may change the hash tables...
+	*       however, it cannot modify the hash_table since
+	*       we are protected by PROTECT_CALL_OUTS.
 	*/
        fun_hval=hash_svalue(fun);
        hval = fun_hval % me->hash_size;
-       save_sp = Pike_sp;
        for(c=me->call_hash[hval].fun;c;c=c->next_fun)
        {
 	 if(c->fun_hval == fun_hval)
@@ -1044,25 +1043,12 @@ PIKECLASS Backend
 	   if(CALL(c->pos) != c)
 	     Pike_fatal("Call_out->pos not correct!\n");
 #endif
-	   push_int(c->pos);
-	   push_svalue(ITEM(c->args));
+	   if (is_eq(fun, ITEM(c->args))) {
+	       return c->pos;
+	   }
 	 }
        }
 
-       /* Check if any of the potential hits we found is a match. */
-       while (Pike_sp > save_sp) {
-	 if (is_eq(fun, Pike_sp-1)) {
-	   INT_TYPE pos;
-#ifdef PIKE_DEBUG
-	   if (TYPEOF(Pike_sp[-2]) != T_INT)
-	     Pike_fatal("Call_out->pos out of sync!\n");
-#endif
-	   pos = Pike_sp[-2].u.integer;
-	   pop_n_elems(Pike_sp - save_sp);
-	   return pos;
-	 }
-	 pop_n_elems(2);
-       }
        return -1;
      }
 
-- 
GitLab