]> git.eshelyaron.com Git - emacs.git/commitdiff
Maintain end of specpdl instead of size
authorMattias Engdegård <mattiase@acm.org>
Sat, 26 Feb 2022 11:49:02 +0000 (12:49 +0100)
committerMattias Engdegård <mattiase@acm.org>
Sat, 12 Mar 2022 16:32:31 +0000 (17:32 +0100)
Keep track of the end of specpdl explicitly since that is what we are
comparing against on critical code paths.

* src/eval.c (init_eval_once_for_pdumper, signal_or_quit)
(grow_specpdl_allocation):
* src/fileio.c (Fdo_auto_save):
* src/lisp.h (grow_specpdl):
* src/thread.c (run_thread, Fmake_thread):
* src/thread.h (struct thread_state):
Replace specpdl_size with specpdl_end, according to the equation
specpdl_end = specpdl + specpdl_size.

src/eval.c
src/fileio.c
src/lisp.h
src/thread.c
src/thread.h

index 0fc492fbe0e32eb0943e15c17a065842a0dbbfca..a9d56ca23b3fbf291fe258f709bff08f6fa0b06d 100644 (file)
@@ -223,8 +223,8 @@ init_eval_once_for_pdumper (void)
 {
   enum { size = 50 };
   union specbinding *pdlvec = malloc ((size + 1) * sizeof *specpdl);
-  specpdl_size = size;
   specpdl = specpdl_ptr = pdlvec + 1;
+  specpdl_end = specpdl + size;
 }
 
 void
@@ -1773,7 +1773,7 @@ signal_or_quit (Lisp_Object error_symbol, Lisp_Object data, bool keyboard_quit)
       && ! NILP (error_symbol)
       /* Don't try to call a lisp function if we've already overflowed
          the specpdl stack.  */
-      && specpdl_ptr < specpdl + specpdl_size)
+      && specpdl_ptr < specpdl_end)
     {
       /* Edebug takes care of restoring these variables when it exits.  */
       max_ensure_room (&max_lisp_eval_depth, lisp_eval_depth, 20);
@@ -2323,22 +2323,23 @@ alist mapping symbols to their value.  */)
 void
 grow_specpdl_allocation (void)
 {
-  eassert (specpdl_ptr == specpdl + specpdl_size);
+  eassert (specpdl_ptr == specpdl_end);
 
   specpdl_ref count = SPECPDL_INDEX ();
   ptrdiff_t max_size = min (max_specpdl_size, PTRDIFF_MAX - 1000);
   union specbinding *pdlvec = specpdl - 1;
-  ptrdiff_t pdlvecsize = specpdl_size + 1;
-  if (max_size <= specpdl_size)
+  ptrdiff_t size = specpdl_end - specpdl;
+  ptrdiff_t pdlvecsize = size + 1;
+  if (max_size <= size)
     {
       if (max_specpdl_size < 400)
        max_size = max_specpdl_size = 400;
-      if (max_size <= specpdl_size)
+      if (max_size <= size)
        xsignal0 (Qexcessive_variable_binding);
     }
   pdlvec = xpalloc (pdlvec, &pdlvecsize, 1, max_size + 1, sizeof *specpdl);
   specpdl = pdlvec + 1;
-  specpdl_size = pdlvecsize - 1;
+  specpdl_end = specpdl + pdlvecsize - 1;
   specpdl_ptr = specpdl_ref_to_ptr (count);
 }
 
index 243a87a48211d38b0feaf4860eedf675af3d13c7..a0282204de870db50b7f15cb0269fb462faeb3ca 100644 (file)
@@ -5973,7 +5973,8 @@ A non-nil CURRENT-ONLY argument means save only current buffer.  */)
   bool old_message_p = 0;
   struct auto_save_unwind auto_save_unwind;
 
-  intmax_t sum = INT_ADD_WRAPV (specpdl_size, 40, &sum) ? INTMAX_MAX : sum;
+  intmax_t sum = INT_ADD_WRAPV (specpdl_end - specpdl, 40, &sum)
+                 ? INTMAX_MAX : sum;
   if (max_specpdl_size < sum)
     max_specpdl_size = sum;
 
index b99441fa6c19ee2ff912a9f06664c1248114b572..3c73570babfacb3d0fc31384b885eea255c74cc5 100644 (file)
@@ -3469,7 +3469,7 @@ INLINE void
 grow_specpdl (void)
 {
   specpdl_ptr++;
-  if (specpdl_ptr == specpdl + specpdl_size)
+  if (specpdl_ptr == specpdl_end)
     grow_specpdl_allocation ();
 }
 
index 4c98d590b7a59894463a804050b665dfd812ad05..b5b7d7c0d7138342968e29279b5d1b7a4d92675f 100644 (file)
@@ -790,7 +790,7 @@ run_thread (void *state)
   xfree (self->m_specpdl - 1);
   self->m_specpdl = NULL;
   self->m_specpdl_ptr = NULL;
-  self->m_specpdl_size = 0;
+  self->m_specpdl_end = NULL;
 
   {
     struct handler *c, *c_next;
@@ -862,11 +862,10 @@ If NAME is given, it must be a string; it names the new thread.  */)
   /* Perhaps copy m_last_thing_searched from parent?  */
   new_thread->m_current_buffer = current_thread->m_current_buffer;
 
-  new_thread->m_specpdl_size = 50;
-  new_thread->m_specpdl = xmalloc ((1 + new_thread->m_specpdl_size)
-                                  * sizeof (union specbinding));
-  /* Skip the dummy entry.  */
-  ++new_thread->m_specpdl;
+  ptrdiff_t size = 50;
+  union specbinding *pdlvec = xmalloc ((1 + size) * sizeof (union specbinding));
+  new_thread->m_specpdl = pdlvec + 1;  /* Skip the dummy entry.  */
+  new_thread->m_specpdl_end = new_thread->m_specpdl + size;
   new_thread->m_specpdl_ptr = new_thread->m_specpdl;
 
   sys_cond_init (&new_thread->thread_condvar);
index 1e7eb86f6eef97f368c03c0b6a118b52d69962ce..f2755045b2e46eeae3b82a7f0a48886fa3f60dbb 100644 (file)
@@ -92,14 +92,14 @@ struct thread_state
   struct handler *m_handlerlist_sentinel;
 #define handlerlist_sentinel (current_thread->m_handlerlist_sentinel)
 
-  /* Current number of specbindings allocated in specpdl.  */
-  ptrdiff_t m_specpdl_size;
-#define specpdl_size (current_thread->m_specpdl_size)
-
   /* Pointer to beginning of specpdl.  */
   union specbinding *m_specpdl;
 #define specpdl (current_thread->m_specpdl)
 
+  /* End of specpld (just beyond the last element).  */
+  union specbinding *m_specpdl_end;
+#define specpdl_end (current_thread->m_specpdl_end)
+
   /* Pointer to first unused element in specpdl.  */
   union specbinding *m_specpdl_ptr;
 #define specpdl_ptr (current_thread->m_specpdl_ptr)