diff options
| author | Paul Eggert | 2018-06-14 15:59:09 -0700 |
|---|---|---|
| committer | Paul Eggert | 2018-06-14 17:13:39 -0700 |
| commit | aca938d1f4ec176a2d00a77693b231298b9c5c4e (patch) | |
| tree | 7498947860bca4044afef608d1dc03e4717fde3d /src/eval.c | |
| parent | 6c04c848e677e458e39811b10335cd6aeece6e2a (diff) | |
| download | emacs-aca938d1f4ec176a2d00a77693b231298b9c5c4e.tar.gz emacs-aca938d1f4ec176a2d00a77693b231298b9c5c4e.zip | |
Avoid allocating Lisp_Save_Value for excursions
* src/editfns.c (save_excursion_save): New arg PDL,
specifying where to save the state. All uses changed.
(save_excursion_restore): Args are now the marker and info
rather than a pointer to a Lisp_Save_Value containing them.
All uses changed.
* src/eval.c (default_toplevel_binding, Fbacktrace__locals):
Treat excursions like other miscellaneous pdl types.
(record_unwind_protect_excursion): Save data directly
into the pdl rather than creating an object on the heap.
This avoids the need to allocate and free an object.
(do_one_unbind, backtrace_eval_unrewind):
Unwind excursions directly.
(mark_specpdl): Mark excursions directly.
* src/lisp.h (SPECPDL_UNWIND_EXCURSION): New constant.
(union specbinding): New member unwind_excursion.
Diffstat (limited to 'src/eval.c')
| -rw-r--r-- | src/eval.c | 38 |
1 files changed, 27 insertions, 11 deletions
diff --git a/src/eval.c b/src/eval.c index 5c7cb3196a6..dded16bed55 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -675,6 +675,7 @@ default_toplevel_binding (Lisp_Object symbol) | |||
| 675 | case SPECPDL_UNWIND: | 675 | case SPECPDL_UNWIND: |
| 676 | case SPECPDL_UNWIND_PTR: | 676 | case SPECPDL_UNWIND_PTR: |
| 677 | case SPECPDL_UNWIND_INT: | 677 | case SPECPDL_UNWIND_INT: |
| 678 | case SPECPDL_UNWIND_EXCURSION: | ||
| 678 | case SPECPDL_UNWIND_VOID: | 679 | case SPECPDL_UNWIND_VOID: |
| 679 | case SPECPDL_BACKTRACE: | 680 | case SPECPDL_BACKTRACE: |
| 680 | case SPECPDL_LET_LOCAL: | 681 | case SPECPDL_LET_LOCAL: |
| @@ -3427,7 +3428,9 @@ record_unwind_protect_int (void (*function) (int), int arg) | |||
| 3427 | void | 3428 | void |
| 3428 | record_unwind_protect_excursion (void) | 3429 | record_unwind_protect_excursion (void) |
| 3429 | { | 3430 | { |
| 3430 | record_unwind_protect (save_excursion_restore, save_excursion_save ()); | 3431 | specpdl_ptr->unwind_excursion.kind = SPECPDL_UNWIND_EXCURSION; |
| 3432 | save_excursion_save (specpdl_ptr); | ||
| 3433 | grow_specpdl (); | ||
| 3431 | } | 3434 | } |
| 3432 | 3435 | ||
| 3433 | void | 3436 | void |
| @@ -3475,6 +3478,10 @@ do_one_unbind (union specbinding *this_binding, bool unwinding, | |||
| 3475 | case SPECPDL_UNWIND_VOID: | 3478 | case SPECPDL_UNWIND_VOID: |
| 3476 | this_binding->unwind_void.func (); | 3479 | this_binding->unwind_void.func (); |
| 3477 | break; | 3480 | break; |
| 3481 | case SPECPDL_UNWIND_EXCURSION: | ||
| 3482 | save_excursion_restore (this_binding->unwind_excursion.marker, | ||
| 3483 | this_binding->unwind_excursion.window); | ||
| 3484 | break; | ||
| 3478 | case SPECPDL_BACKTRACE: | 3485 | case SPECPDL_BACKTRACE: |
| 3479 | break; | 3486 | break; |
| 3480 | case SPECPDL_LET: | 3487 | case SPECPDL_LET: |
| @@ -3749,18 +3756,21 @@ backtrace_eval_unrewind (int distance) | |||
| 3749 | unwind_protect, but the problem is that we don't know how to | 3756 | unwind_protect, but the problem is that we don't know how to |
| 3750 | rewind them afterwards. */ | 3757 | rewind them afterwards. */ |
| 3751 | case SPECPDL_UNWIND: | 3758 | case SPECPDL_UNWIND: |
| 3752 | { | 3759 | if (tmp->unwind.func == set_buffer_if_live) |
| 3753 | Lisp_Object oldarg = tmp->unwind.arg; | 3760 | { |
| 3754 | if (tmp->unwind.func == set_buffer_if_live) | 3761 | Lisp_Object oldarg = tmp->unwind.arg; |
| 3755 | tmp->unwind.arg = Fcurrent_buffer (); | 3762 | tmp->unwind.arg = Fcurrent_buffer (); |
| 3756 | else if (tmp->unwind.func == save_excursion_restore) | 3763 | set_buffer_if_live (oldarg); |
| 3757 | tmp->unwind.arg = save_excursion_save (); | 3764 | } |
| 3758 | else | 3765 | break; |
| 3759 | break; | 3766 | case SPECPDL_UNWIND_EXCURSION: |
| 3760 | tmp->unwind.func (oldarg); | 3767 | { |
| 3761 | break; | 3768 | Lisp_Object marker = tmp->unwind_excursion.marker; |
| 3769 | Lisp_Object window = tmp->unwind_excursion.window; | ||
| 3770 | save_excursion_save (tmp); | ||
| 3771 | save_excursion_restore (marker, window); | ||
| 3762 | } | 3772 | } |
| 3763 | 3773 | break; | |
| 3764 | case SPECPDL_UNWIND_PTR: | 3774 | case SPECPDL_UNWIND_PTR: |
| 3765 | case SPECPDL_UNWIND_INT: | 3775 | case SPECPDL_UNWIND_INT: |
| 3766 | case SPECPDL_UNWIND_VOID: | 3776 | case SPECPDL_UNWIND_VOID: |
| @@ -3895,6 +3905,7 @@ NFRAMES and BASE specify the activation frame to use, as in `backtrace-frame'. | |||
| 3895 | case SPECPDL_UNWIND: | 3905 | case SPECPDL_UNWIND: |
| 3896 | case SPECPDL_UNWIND_PTR: | 3906 | case SPECPDL_UNWIND_PTR: |
| 3897 | case SPECPDL_UNWIND_INT: | 3907 | case SPECPDL_UNWIND_INT: |
| 3908 | case SPECPDL_UNWIND_EXCURSION: | ||
| 3898 | case SPECPDL_UNWIND_VOID: | 3909 | case SPECPDL_UNWIND_VOID: |
| 3899 | case SPECPDL_BACKTRACE: | 3910 | case SPECPDL_BACKTRACE: |
| 3900 | break; | 3911 | break; |
| @@ -3924,6 +3935,11 @@ mark_specpdl (union specbinding *first, union specbinding *ptr) | |||
| 3924 | mark_object (specpdl_arg (pdl)); | 3935 | mark_object (specpdl_arg (pdl)); |
| 3925 | break; | 3936 | break; |
| 3926 | 3937 | ||
| 3938 | case SPECPDL_UNWIND_EXCURSION: | ||
| 3939 | mark_object (pdl->unwind_excursion.marker); | ||
| 3940 | mark_object (pdl->unwind_excursion.window); | ||
| 3941 | break; | ||
| 3942 | |||
| 3927 | case SPECPDL_BACKTRACE: | 3943 | case SPECPDL_BACKTRACE: |
| 3928 | { | 3944 | { |
| 3929 | ptrdiff_t nargs = backtrace_nargs (pdl); | 3945 | ptrdiff_t nargs = backtrace_nargs (pdl); |