VM: Keep jump table address in a register.
authorLudovic Courtès <ludo@gnu.org>
Mon, 4 Jul 2011 21:56:16 +0000 (23:56 +0200)
committerLudovic Courtès <ludo@gnu.org>
Wed, 6 Jul 2011 10:50:32 +0000 (12:50 +0200)
* libguile/vm-engine.c (VM_NAME)[HAVE_LABELS_AS_VALUES]: Rename
  `jump_table' to `jump_table_pointer'.  Add `jump_table' as a local
  variable, initialize it.

* libguile/vm-engine.h (JT_REG): New macro.

libguile/vm-engine.c
libguile/vm-engine.h

index 22bd39c..c90458d 100644 (file)
@@ -61,23 +61,31 @@ VM_NAME (SCM vm, SCM program, SCM *argv, int nargs)
   SCM finish_args;                      /* used both for returns: both in error
                                            and normal situations */
 #ifdef HAVE_LABELS_AS_VALUES
-  static void **jump_table = NULL;
+  static const void **jump_table_pointer = NULL;
 #endif
-  
+
 #ifdef HAVE_LABELS_AS_VALUES
-  if (SCM_UNLIKELY (!jump_table))
+  register const void **jump_table JT_REG;
+
+  if (SCM_UNLIKELY (!jump_table_pointer))
     {
       int i;
-      jump_table = malloc (SCM_VM_NUM_INSTRUCTIONS * sizeof(void*));
+      jump_table_pointer = malloc (SCM_VM_NUM_INSTRUCTIONS * sizeof (void*));
       for (i = 0; i < SCM_VM_NUM_INSTRUCTIONS; i++)
-        jump_table[i] = &&vm_error_bad_instruction;
+        jump_table_pointer[i] = &&vm_error_bad_instruction;
 #define VM_INSTRUCTION_TO_LABEL 1
+#define jump_table jump_table_pointer
 #include <libguile/vm-expand.h>
 #include <libguile/vm-i-system.i>
 #include <libguile/vm-i-scheme.i>
 #include <libguile/vm-i-loader.i>
+#undef jump_table
 #undef VM_INSTRUCTION_TO_LABEL
     }
+
+  /* Attempt to keep JUMP_TABLE_POINTER in a register.  This saves one
+     load instruction at each instruction dispatch.  */
+  jump_table = jump_table_pointer;
 #endif
 
   /* Initialization */
index 48ab09a..000397d 100644 (file)
 /* too few registers! because of register allocation errors with various gcs,
    just punt on explicit assignments on i386, hoping that the "register"
    declaration will be sufficient. */
+#elif defined __x86_64__
+/* GCC 4.6 chooses %rbp for IP_REG and %rbx for SP_REG, which works
+   well.  Tell it to keep the jump table in a r12, which is
+   callee-saved.  */
+#define JT_REG asm ("r12")
 #endif
 #if defined(PPC) || defined(_POWER) || defined(_IBMR2)
 #define IP_REG asm("26")
@@ -89,6 +94,9 @@
 #ifndef FP_REG
 #define FP_REG
 #endif
+#ifndef JT_REG
+#define JT_REG
+#endif
 
 \f
 /*