aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMattias EngdegÄrd2022-02-26 12:49:02 +0100
committerMattias EngdegÄrd2022-03-12 17:32:31 +0100
commitfe65db05f42bcbf755f037575b3c29b74f279bdf (patch)
treec184bf57ac6a9bc7489c9c7700dcc3bd4441083d /src
parent213483124b4381663efd0dd001037363223ce188 (diff)
downloademacs-fe65db05f42bcbf755f037575b3c29b74f279bdf.tar.gz
emacs-fe65db05f42bcbf755f037575b3c29b74f279bdf.zip
Maintain end of specpdl instead of size
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.
Diffstat (limited to 'src')
-rw-r--r--src/eval.c15
-rw-r--r--src/fileio.c3
-rw-r--r--src/lisp.h2
-rw-r--r--src/thread.c11
-rw-r--r--src/thread.h8
5 files changed, 20 insertions, 19 deletions
diff --git a/src/eval.c b/src/eval.c
index 0fc492fbe0e..a9d56ca23b3 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -223,8 +223,8 @@ init_eval_once_for_pdumper (void)
223{ 223{
224 enum { size = 50 }; 224 enum { size = 50 };
225 union specbinding *pdlvec = malloc ((size + 1) * sizeof *specpdl); 225 union specbinding *pdlvec = malloc ((size + 1) * sizeof *specpdl);
226 specpdl_size = size;
227 specpdl = specpdl_ptr = pdlvec + 1; 226 specpdl = specpdl_ptr = pdlvec + 1;
227 specpdl_end = specpdl + size;
228} 228}
229 229
230void 230void
@@ -1773,7 +1773,7 @@ signal_or_quit (Lisp_Object error_symbol, Lisp_Object data, bool keyboard_quit)
1773 && ! NILP (error_symbol) 1773 && ! NILP (error_symbol)
1774 /* Don't try to call a lisp function if we've already overflowed 1774 /* Don't try to call a lisp function if we've already overflowed
1775 the specpdl stack. */ 1775 the specpdl stack. */
1776 && specpdl_ptr < specpdl + specpdl_size) 1776 && specpdl_ptr < specpdl_end)
1777 { 1777 {
1778 /* Edebug takes care of restoring these variables when it exits. */ 1778 /* Edebug takes care of restoring these variables when it exits. */
1779 max_ensure_room (&max_lisp_eval_depth, lisp_eval_depth, 20); 1779 max_ensure_room (&max_lisp_eval_depth, lisp_eval_depth, 20);
@@ -2323,22 +2323,23 @@ alist mapping symbols to their value. */)
2323void 2323void
2324grow_specpdl_allocation (void) 2324grow_specpdl_allocation (void)
2325{ 2325{
2326 eassert (specpdl_ptr == specpdl + specpdl_size); 2326 eassert (specpdl_ptr == specpdl_end);
2327 2327
2328 specpdl_ref count = SPECPDL_INDEX (); 2328 specpdl_ref count = SPECPDL_INDEX ();
2329 ptrdiff_t max_size = min (max_specpdl_size, PTRDIFF_MAX - 1000); 2329 ptrdiff_t max_size = min (max_specpdl_size, PTRDIFF_MAX - 1000);
2330 union specbinding *pdlvec = specpdl - 1; 2330 union specbinding *pdlvec = specpdl - 1;
2331 ptrdiff_t pdlvecsize = specpdl_size + 1; 2331 ptrdiff_t size = specpdl_end - specpdl;
2332 if (max_size <= specpdl_size) 2332 ptrdiff_t pdlvecsize = size + 1;
2333 if (max_size <= size)
2333 { 2334 {
2334 if (max_specpdl_size < 400) 2335 if (max_specpdl_size < 400)
2335 max_size = max_specpdl_size = 400; 2336 max_size = max_specpdl_size = 400;
2336 if (max_size <= specpdl_size) 2337 if (max_size <= size)
2337 xsignal0 (Qexcessive_variable_binding); 2338 xsignal0 (Qexcessive_variable_binding);
2338 } 2339 }
2339 pdlvec = xpalloc (pdlvec, &pdlvecsize, 1, max_size + 1, sizeof *specpdl); 2340 pdlvec = xpalloc (pdlvec, &pdlvecsize, 1, max_size + 1, sizeof *specpdl);
2340 specpdl = pdlvec + 1; 2341 specpdl = pdlvec + 1;
2341 specpdl_size = pdlvecsize - 1; 2342 specpdl_end = specpdl + pdlvecsize - 1;
2342 specpdl_ptr = specpdl_ref_to_ptr (count); 2343 specpdl_ptr = specpdl_ref_to_ptr (count);
2343} 2344}
2344 2345
diff --git a/src/fileio.c b/src/fileio.c
index 243a87a4821..a0282204de8 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -5973,7 +5973,8 @@ A non-nil CURRENT-ONLY argument means save only current buffer. */)
5973 bool old_message_p = 0; 5973 bool old_message_p = 0;
5974 struct auto_save_unwind auto_save_unwind; 5974 struct auto_save_unwind auto_save_unwind;
5975 5975
5976 intmax_t sum = INT_ADD_WRAPV (specpdl_size, 40, &sum) ? INTMAX_MAX : sum; 5976 intmax_t sum = INT_ADD_WRAPV (specpdl_end - specpdl, 40, &sum)
5977 ? INTMAX_MAX : sum;
5977 if (max_specpdl_size < sum) 5978 if (max_specpdl_size < sum)
5978 max_specpdl_size = sum; 5979 max_specpdl_size = sum;
5979 5980
diff --git a/src/lisp.h b/src/lisp.h
index b99441fa6c1..3c73570babf 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3469,7 +3469,7 @@ INLINE void
3469grow_specpdl (void) 3469grow_specpdl (void)
3470{ 3470{
3471 specpdl_ptr++; 3471 specpdl_ptr++;
3472 if (specpdl_ptr == specpdl + specpdl_size) 3472 if (specpdl_ptr == specpdl_end)
3473 grow_specpdl_allocation (); 3473 grow_specpdl_allocation ();
3474} 3474}
3475 3475
diff --git a/src/thread.c b/src/thread.c
index 4c98d590b7a..b5b7d7c0d71 100644
--- a/src/thread.c
+++ b/src/thread.c
@@ -790,7 +790,7 @@ run_thread (void *state)
790 xfree (self->m_specpdl - 1); 790 xfree (self->m_specpdl - 1);
791 self->m_specpdl = NULL; 791 self->m_specpdl = NULL;
792 self->m_specpdl_ptr = NULL; 792 self->m_specpdl_ptr = NULL;
793 self->m_specpdl_size = 0; 793 self->m_specpdl_end = NULL;
794 794
795 { 795 {
796 struct handler *c, *c_next; 796 struct handler *c, *c_next;
@@ -862,11 +862,10 @@ If NAME is given, it must be a string; it names the new thread. */)
862 /* Perhaps copy m_last_thing_searched from parent? */ 862 /* Perhaps copy m_last_thing_searched from parent? */
863 new_thread->m_current_buffer = current_thread->m_current_buffer; 863 new_thread->m_current_buffer = current_thread->m_current_buffer;
864 864
865 new_thread->m_specpdl_size = 50; 865 ptrdiff_t size = 50;
866 new_thread->m_specpdl = xmalloc ((1 + new_thread->m_specpdl_size) 866 union specbinding *pdlvec = xmalloc ((1 + size) * sizeof (union specbinding));
867 * sizeof (union specbinding)); 867 new_thread->m_specpdl = pdlvec + 1; /* Skip the dummy entry. */
868 /* Skip the dummy entry. */ 868 new_thread->m_specpdl_end = new_thread->m_specpdl + size;
869 ++new_thread->m_specpdl;
870 new_thread->m_specpdl_ptr = new_thread->m_specpdl; 869 new_thread->m_specpdl_ptr = new_thread->m_specpdl;
871 870
872 sys_cond_init (&new_thread->thread_condvar); 871 sys_cond_init (&new_thread->thread_condvar);
diff --git a/src/thread.h b/src/thread.h
index 1e7eb86f6ee..f2755045b2e 100644
--- a/src/thread.h
+++ b/src/thread.h
@@ -92,14 +92,14 @@ struct thread_state
92 struct handler *m_handlerlist_sentinel; 92 struct handler *m_handlerlist_sentinel;
93#define handlerlist_sentinel (current_thread->m_handlerlist_sentinel) 93#define handlerlist_sentinel (current_thread->m_handlerlist_sentinel)
94 94
95 /* Current number of specbindings allocated in specpdl. */
96 ptrdiff_t m_specpdl_size;
97#define specpdl_size (current_thread->m_specpdl_size)
98
99 /* Pointer to beginning of specpdl. */ 95 /* Pointer to beginning of specpdl. */
100 union specbinding *m_specpdl; 96 union specbinding *m_specpdl;
101#define specpdl (current_thread->m_specpdl) 97#define specpdl (current_thread->m_specpdl)
102 98
99 /* End of specpld (just beyond the last element). */
100 union specbinding *m_specpdl_end;
101#define specpdl_end (current_thread->m_specpdl_end)
102
103 /* Pointer to first unused element in specpdl. */ 103 /* Pointer to first unused element in specpdl. */
104 union specbinding *m_specpdl_ptr; 104 union specbinding *m_specpdl_ptr;
105#define specpdl_ptr (current_thread->m_specpdl_ptr) 105#define specpdl_ptr (current_thread->m_specpdl_ptr)