mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-08 12:40:49 -08:00
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.
This commit is contained in:
parent
213483124b
commit
fe65db05f4
5 changed files with 20 additions and 19 deletions
15
src/eval.c
15
src/eval.c
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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 ();
|
||||
}
|
||||
|
||||
|
|
|
|||
11
src/thread.c
11
src/thread.c
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue