diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2018-06-07 19:12:28 -0700 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2018-06-14 17:13:39 -0700 |
commit | d98670eb04925fdc4a4928a9b0d0858881da418f (patch) | |
tree | 52d74dac7f568f7bcfe252ec9efd7658177895e0 /src/eval.c | |
parent | aca938d1f4ec176a2d00a77693b231298b9c5c4e (diff) | |
download | emacs-d98670eb04925fdc4a4928a9b0d0858881da418f.tar.gz |
Avoid allocating Lisp_Save_Value for arrays
* src/alloc.c (mark_maybe_objects): New function.
* src/eval.c (default_toplevel_binding)
(backtrace_eval_unrewind, Fbacktrace__locals):
Treat array unwindings like other miscellaneous pdl types.
(record_unwind_protect_array): New function.
(do_one_unbind): Free the array while unwinding.
(mark_specpdl): Mark arrays directly.
* src/lisp.h (SPECPDL_UNWIND_ARRAY): New constant.
(union specbinding): New member unwind_array.
(SAFE_ALLOCA_LISP_EXTRA): Use record_unwind_protect_array
instead of make_save_memory + record_unwind_protect.
Diffstat (limited to 'src/eval.c')
-rw-r--r-- | src/eval.c | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/src/eval.c b/src/eval.c index dded16bed55..952a0ec4b46 100644 --- a/src/eval.c +++ b/src/eval.c @@ -673,6 +673,7 @@ default_toplevel_binding (Lisp_Object symbol) break; case SPECPDL_UNWIND: + case SPECPDL_UNWIND_ARRAY: case SPECPDL_UNWIND_PTR: case SPECPDL_UNWIND_INT: case SPECPDL_UNWIND_EXCURSION: @@ -3408,6 +3409,15 @@ record_unwind_protect (void (*function) (Lisp_Object), Lisp_Object arg) } void +record_unwind_protect_array (Lisp_Object *array, ptrdiff_t nelts) +{ + specpdl_ptr->unwind_array.kind = SPECPDL_UNWIND_ARRAY; + specpdl_ptr->unwind_array.array = array; + specpdl_ptr->unwind_array.nelts = nelts; + grow_specpdl (); +} + +void record_unwind_protect_ptr (void (*function) (void *), void *arg) { specpdl_ptr->unwind_ptr.kind = SPECPDL_UNWIND_PTR; @@ -3469,6 +3479,9 @@ do_one_unbind (union specbinding *this_binding, bool unwinding, case SPECPDL_UNWIND: this_binding->unwind.func (this_binding->unwind.arg); break; + case SPECPDL_UNWIND_ARRAY: + xfree (this_binding->unwind_array.array); + break; case SPECPDL_UNWIND_PTR: this_binding->unwind_ptr.func (this_binding->unwind_ptr.arg); break; @@ -3771,6 +3784,7 @@ backtrace_eval_unrewind (int distance) save_excursion_restore (marker, window); } break; + case SPECPDL_UNWIND_ARRAY: case SPECPDL_UNWIND_PTR: case SPECPDL_UNWIND_INT: case SPECPDL_UNWIND_VOID: @@ -3903,6 +3917,7 @@ NFRAMES and BASE specify the activation frame to use, as in `backtrace-frame'. break; case SPECPDL_UNWIND: + case SPECPDL_UNWIND_ARRAY: case SPECPDL_UNWIND_PTR: case SPECPDL_UNWIND_INT: case SPECPDL_UNWIND_EXCURSION: @@ -3935,6 +3950,10 @@ mark_specpdl (union specbinding *first, union specbinding *ptr) mark_object (specpdl_arg (pdl)); break; + case SPECPDL_UNWIND_ARRAY: + mark_maybe_objects (pdl->unwind_array.array, pdl->unwind_array.nelts); + break; + case SPECPDL_UNWIND_EXCURSION: mark_object (pdl->unwind_excursion.marker); mark_object (pdl->unwind_excursion.window); |