From 5909f93acae76217f42b7a1231c20885e06afae9 Mon Sep 17 00:00:00 2001
From: Per Hedbor <ph@opera.com>
Date: Thu, 15 Aug 2013 13:57:06 +0200
Subject: [PATCH] Instead of returning 1, return the branch-to address

This makes jumps marginally more efficient (saves one instruction and some memory reading)
---
 src/apply_low.h           |  2 +-
 src/interpret.c           | 22 ++++++++++++----------
 src/interpret.h           |  4 ++--
 src/interpret_functions.h | 18 +++++++++---------
 4 files changed, 24 insertions(+), 22 deletions(-)

diff --git a/src/apply_low.h b/src/apply_low.h
index b6146be577..7362ae7de0 100644
--- a/src/apply_low.h
+++ b/src/apply_low.h
@@ -322,7 +322,7 @@
 #endif /* ENTRY_PROLOGUE_SIZE */
 	  ;
 
-	return 1;
+	return new_frame->pc;
       }
 
       default:
diff --git a/src/interpret.c b/src/interpret.c
index 8e46512c77..c0caf18f92 100644
--- a/src/interpret.c
+++ b/src/interpret.c
@@ -962,13 +962,15 @@ static INLINE void low_debug_instr_prologue (PIKE_INSTR_T instr)
        (actually, they will always be incorrect before running FILL_STACK,
        but at least currently that is the first opcode run).
     */
-    if( instr+F_OFFSET != F_FILL_STACK )
-    {
-        if(/* Pike_fp->fun>=0 && */ Pike_fp->current_object->prog &&
-           Pike_fp->locals+Pike_fp->num_locals > Pike_sp)
-            Pike_fatal("Stack error (stupid! %p %p+%x).\n",Pike_sp,
-                       Pike_fp->locals, Pike_fp->num_locals*sizeof(struct svalue));
-    }
+
+    /* as it turns out, this is no longer true.. */
+    /* if( instr+F_OFFSET != F_FILL_STACK ) */
+    /* { */
+    /*     if(/\* Pike_fp->fun>=0 && *\/ Pike_fp->current_object->prog && */
+    /*        Pike_fp->locals+Pike_fp->num_locals > Pike_sp) */
+    /*         Pike_fatal("Stack error (stupid! %p %p+%x).\n",Pike_sp, */
+    /*                    Pike_fp->locals, Pike_fp->num_locals*sizeof(struct svalue)); */
+    /* } */
 
     if(Pike_interpreter.recoveries &&
        (Pike_sp-Pike_interpreter.evaluator_stack <
@@ -2055,7 +2057,7 @@ void really_free_pike_scope(struct pike_frame *scope)
   really_free_pike_frame(scope);
 }
 
-int lower_mega_apply( INT32 args, struct object *o, ptrdiff_t fun )
+void *lower_mega_apply( INT32 args, struct object *o, ptrdiff_t fun )
 {
   struct program *p;
   check_stack(256);
@@ -2189,7 +2191,7 @@ int lower_mega_apply( INT32 args, struct object *o, ptrdiff_t fun )
               + ENTRY_PROLOGUE_SIZE
 #endif /* ENTRY_PROLOGUE_SIZE */
               ;
-            return 1;
+            return new_frame->pc;
           }
           else
           {
@@ -2234,7 +2236,7 @@ int lower_mega_apply( INT32 args, struct object *o, ptrdiff_t fun )
  *   eval_instruction() is done the frame needs to be removed by a call
  *   to low_return() or low_return_pop().
  */
-int low_mega_apply(enum apply_type type, INT32 args, void *arg1, void *arg2)
+void* low_mega_apply(enum apply_type type, INT32 args, void *arg1, void *arg2)
 {
   struct object *o = NULL;
   struct pike_frame *scope=0;
diff --git a/src/interpret.h b/src/interpret.h
index 8d228350e3..a14394ca5d 100644
--- a/src/interpret.h
+++ b/src/interpret.h
@@ -792,8 +792,8 @@ PMOD_EXPORT void find_external_context(struct external_variable_context *loc,
 				       int arg2);
 struct pike_frame *alloc_pike_frame(void);
 void really_free_pike_scope(struct pike_frame *scope);
-int lower_mega_apply( INT32 args, struct object *o, ptrdiff_t fun );
-int low_mega_apply(enum apply_type type, INT32 args, void *arg1, void *arg2);
+void *lower_mega_apply( INT32 args, struct object *o, ptrdiff_t fun );
+void *low_mega_apply(enum apply_type type, INT32 args, void *arg1, void *arg2);
 void low_return(void);
 void low_return_pop(void);
 void unlink_previous_frame(void);
diff --git a/src/interpret_functions.h b/src/interpret_functions.h
index ed87253f11..727b9078cc 100644
--- a/src/interpret_functions.h
+++ b/src/interpret_functions.h
@@ -2234,7 +2234,7 @@ OPCODE1_JUMP(F_CALL_OTHER,"call other", I_UPDATE_ALL, {
   {
     LOCAL_VAR(struct svalue tmp);
     LOCAL_VAR(struct svalue tmp2);
-
+    LOCAL_VAR(void *p);
     SET_SVAL(tmp, PIKE_T_STRING, 1, string,
 	     Pike_fp->context->prog->strings[arg1]);
 
@@ -2243,10 +2243,10 @@ OPCODE1_JUMP(F_CALL_OTHER,"call other", I_UPDATE_ALL, {
     move_svalue (s, &tmp2);
     print_return_value();
 
-    if(low_mega_apply(APPLY_STACK, args, 0, 0))
+    if(p = low_mega_apply(APPLY_STACK, args, 0, 0))
     {
       Pike_fp->flags |= PIKE_FRAME_RETURN_INTERNAL;
-      DO_JUMP_TO(Pike_fp->pc);
+      DO_JUMP_TO(p);
     }
     else {
       DO_JUMP_TO_NEXT;
@@ -2293,6 +2293,7 @@ OPCODE1_JUMP(F_CALL_OTHER_AND_POP,"call other & pop", I_UPDATE_ALL, {
   {
     LOCAL_VAR(struct svalue tmp);
     LOCAL_VAR(struct svalue tmp2);
+    LOCAL_VAR(void *p);
 
     SET_SVAL(tmp, PIKE_T_STRING, 1, string,
 	     Pike_fp->context->prog->strings[arg1]);
@@ -2302,10 +2303,10 @@ OPCODE1_JUMP(F_CALL_OTHER_AND_POP,"call other & pop", I_UPDATE_ALL, {
     move_svalue (s, &tmp2);
     print_return_value();
 
-    if(low_mega_apply(APPLY_STACK, args, 0, 0))
+    if(p = low_mega_apply(APPLY_STACK, args, 0, 0))
     {
       Pike_fp->flags |= PIKE_FRAME_RETURN_INTERNAL | PIKE_FRAME_RETURN_POP;
-      DO_JUMP_TO(Pike_fp->pc);
+      DO_JUMP_TO(p);
     }
     else {
       pop_stack();
@@ -2352,7 +2353,7 @@ OPCODE1_RETURN(F_CALL_OTHER_AND_RETURN,"call other & return", I_UPDATE_ALL, {
   {
     LOCAL_VAR(struct svalue tmp);
     LOCAL_VAR(struct svalue tmp2);
-
+    LOCAL_VAR(void *p);
     SET_SVAL(tmp, PIKE_T_STRING, 1, string,
 	     Pike_fp->context->prog->strings[arg1]);
 
@@ -2361,12 +2362,11 @@ OPCODE1_RETURN(F_CALL_OTHER_AND_RETURN,"call other & return", I_UPDATE_ALL, {
     move_svalue (s, &tmp2);
     print_return_value();
 
-    if(low_mega_apply(APPLY_STACK, args, 0, 0))
+    if(p = low_mega_apply(APPLY_STACK, args, 0, 0))
     {
-      PIKE_OPCODE_T *addr = Pike_fp->pc;
       DO_IF_DEBUG(Pike_fp->next->pc=0);
       unlink_previous_frame();
-      DO_JUMP_TO(addr);
+      DO_JUMP_TO(p);
     }
     DO_DUMB_RETURN;
   }
-- 
GitLab