emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] nick.lloyd-bytecode-jit a35c6fd 2/2: ; Fix a possible bug


From: Nickolas Lloyd
Subject: [Emacs-diffs] nick.lloyd-bytecode-jit a35c6fd 2/2: ; Fix a possible bug with JIT-compiled functions in the call stack
Date: Fri, 23 Dec 2016 22:52:39 +0000 (UTC)

branch: nick.lloyd-bytecode-jit
commit a35c6fdc42bb31f5e8bf743c94366341ad700595
Author: Nickolas Lloyd <address@hidden>
Commit: Nickolas Lloyd <address@hidden>

    ; Fix a possible bug with JIT-compiled functions in the call stack
    
    * src/bytecode-jit.c (jit_byte_code__, jit_exec): Insert entry into
    `byte_stack_list' from `jit_exec' instead of `jit_byte_code__'.  It seems 
like
    this would be needed for proper stack unwinding in `unwind_to_catch'.
    * src/bytecode.c (relocate_byte_stack) [HAVE_LIBJIT]: Skip entries in
    `byte_stack_list' with no associated bytecode stack.
---
 src/bytecode-jit.c |   40 +++++++++++++++++++---------------------
 src/bytecode.c     |    4 ++++
 2 files changed, 23 insertions(+), 21 deletions(-)

diff --git a/src/bytecode-jit.c b/src/bytecode-jit.c
index 6faa972..28269fe 100644
--- a/src/bytecode-jit.c
+++ b/src/bytecode-jit.c
@@ -32,11 +32,7 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 
 /* Fetch the next byte from the bytecode stream.  */
 
-#if BYTE_CODE_SAFE
-#define FETCH (eassert (stack.byte_string_start == SDATA (stack.byte_string)), 
*stack.pc++)
-#else
-#define FETCH *stack.pc++
-#endif
+#define FETCH *pc++
 
 /* Fetch two bytes from the bytecode stream and make a 16-bit number
    out of them.  */
@@ -660,7 +656,15 @@ jit_exec (Lisp_Object byte_code, Lisp_Object 
args_template, ptrdiff_t nargs, Lis
   {
     Lisp_Object (*func)(Lisp_Object *) =
       (Lisp_Object (*)(Lisp_Object *))AREF (byte_code, COMPILED_JIT_ID);
-    return func (top);
+    /* We don't actually need to use this structure to keep track of a
+       stack, since our stack isn't GCed.  We just need to use it as a
+       placeholder in `byte_stack_list' to facilitate proper unwinding. */
+    struct byte_stack stack = {};
+    stack.next = byte_stack_list;
+    byte_stack_list = &stack;
+    Lisp_Object ret = func (top);
+    byte_stack_list = byte_stack_list->next;
+    return ret;
   }
 }
 
@@ -675,13 +679,14 @@ jit_byte_code__ (Lisp_Object byte_code)
   Lisp_Object *stacke;
 #endif
   ptrdiff_t bytestr_length;
-  struct byte_stack stack;
   Lisp_Object bytestr;
   Lisp_Object vector;
   Lisp_Object maxdepth;
   Lisp_Object *top;
   enum handlertype type;
 
+  unsigned char *byte_string_start, *pc;
+
   /* jit-specific variables */
   jit_function_t this_func;
   jit_type_t params[1];
@@ -725,15 +730,9 @@ jit_byte_code__ (Lisp_Object byte_code)
   bytestr_length = SBYTES (bytestr);
   vectorp = XVECTOR (vector)->contents;
 
-  stack.byte_string = bytestr;
-  stack.pc = stack.byte_string_start = SDATA (bytestr);
+  pc = byte_string_start = SDATA (bytestr);
   if (MAX_ALLOCA / word_size <= XFASTINT (maxdepth))
     memory_full (SIZE_MAX);
-#if BYTE_MAINTAIN_TOP
-  stack.top = NULL;
-#endif
-  stack.next = byte_stack_list;
-  byte_stack_list = &stack;
 
   /* prepare for jit */
   jit_context_build_start (jit_context);
@@ -752,7 +751,7 @@ jit_byte_code__ (Lisp_Object byte_code)
       labels[i] = jit_label_undefined;
   }
 
-  while (stack.pc < stack.byte_string_start + bytestr_length)
+  while (pc < byte_string_start + bytestr_length)
     {
 #ifndef BYTE_CODE_THREADED
       op = FETCH;
@@ -773,7 +772,7 @@ jit_byte_code__ (Lisp_Object byte_code)
         plain break.  */
 #define NEXT                                                           \
       do {                                                             \
-       if (stack.pc >= stack.byte_string_start + bytestr_length)       \
+       if (pc >= byte_string_start + bytestr_length)                   \
          goto exit;                                                    \
        else                                                            \
          {                                                             \
@@ -837,7 +836,7 @@ jit_byte_code__ (Lisp_Object byte_code)
 
 #endif
 
-#define JIT_PC (stack.pc - stack.byte_string_start)
+#define JIT_PC (pc - byte_string_start)
 #define JIT_NEED_STACK jit_value_ref (this_func, stackv)
 #define JIT_NEXT                               \
       do {                                     \
@@ -1175,7 +1174,7 @@ jit_byte_code__ (Lisp_Object byte_code)
            else
              {
                op = FETCH - 128;
-               op += (stack.pc - stack.byte_string_start);
+               op += (pc - byte_string_start);
              }
            CHECK_RANGE (op);
            JIT_NEED_STACK;
@@ -1202,7 +1201,7 @@ jit_byte_code__ (Lisp_Object byte_code)
        CASE (BRgoto):
          {
            op = FETCH - 128;
-           const int dest = (stack.pc - stack.byte_string_start) + op;
+           const int dest = (pc - byte_string_start) + op;
            JIT_CALL (byte_code_quit, NULL, 0);
            jit_insn_branch (
              this_func,
@@ -1997,7 +1996,7 @@ jit_byte_code__ (Lisp_Object byte_code)
          call3 (Qerror,
                 build_string ("Invalid byte opcode: op=%s, ptr=%d"),
                 make_number (op),
-                make_number ((stack.pc - 1) - stack.byte_string_start));
+                make_number (pc - 1 - byte_string_start));
 
          /* Handy byte-codes for lexical binding.  */
        CASE (Bstack_ref1):
@@ -2079,7 +2078,6 @@ jit_byte_code__ (Lisp_Object byte_code)
     }
 
  exit:
-  byte_stack_list = byte_stack_list->next;
 
   {
     int err = !jit_function_compile (this_func);
diff --git a/src/bytecode.c b/src/bytecode.c
index 6567039..26860da 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -66,6 +66,10 @@ relocate_byte_stack (struct byte_stack *stack)
 {
   for (; stack; stack = stack->next)
     {
+#ifdef HAVE_LIBJIT
+      if (!stack->byte_string_start)
+       continue;
+#endif
       if (stack->byte_string_start != SDATA (stack->byte_string))
        {
          ptrdiff_t offset = stack->pc - stack->byte_string_start;



reply via email to

[Prev in Thread] Current Thread [Next in Thread]