diff options
| author | Mattias EngdegÄrd | 2022-02-26 12:49:02 +0100 |
|---|---|---|
| committer | Mattias EngdegÄrd | 2022-03-12 17:32:31 +0100 |
| commit | fe65db05f42bcbf755f037575b3c29b74f279bdf (patch) | |
| tree | c184bf57ac6a9bc7489c9c7700dcc3bd4441083d /src | |
| parent | 213483124b4381663efd0dd001037363223ce188 (diff) | |
| download | emacs-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.c | 15 | ||||
| -rw-r--r-- | src/fileio.c | 3 | ||||
| -rw-r--r-- | src/lisp.h | 2 | ||||
| -rw-r--r-- | src/thread.c | 11 | ||||
| -rw-r--r-- | src/thread.h | 8 |
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 | ||
| 230 | void | 230 | void |
| @@ -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. */) | |||
| 2323 | void | 2323 | void |
| 2324 | grow_specpdl_allocation (void) | 2324 | grow_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 | |||
| 3469 | grow_specpdl (void) | 3469 | grow_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) |