aboutsummaryrefslogtreecommitdiffstats
path: root/src/editfns.c
diff options
context:
space:
mode:
authorPaul Eggert2018-06-14 15:59:09 -0700
committerPaul Eggert2018-06-14 17:13:39 -0700
commitaca938d1f4ec176a2d00a77693b231298b9c5c4e (patch)
tree7498947860bca4044afef608d1dc03e4717fde3d /src/editfns.c
parent6c04c848e677e458e39811b10335cd6aeece6e2a (diff)
downloademacs-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/editfns.c')
-rw-r--r--src/editfns.c27
1 files changed, 11 insertions, 16 deletions
diff --git a/src/editfns.c b/src/editfns.c
index e672c0eb74d..3147f9d1466 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -995,30 +995,24 @@ This function does not move point. */)
995 Qnil, Qt, Qnil); 995 Qnil, Qt, Qnil);
996} 996}
997 997
998/* Save current buffer state for `save-excursion' special form. 998/* Save current buffer state for save-excursion special form. */
999 We (ab)use Lisp_Misc_Save_Value to allow explicit free and so
1000 offload some work from GC. */
1001 999
1002Lisp_Object 1000void
1003save_excursion_save (void) 1001save_excursion_save (union specbinding *pdl)
1004{ 1002{
1005 return make_save_obj_obj_obj_obj 1003 eassert (pdl->unwind_excursion.kind == SPECPDL_UNWIND_EXCURSION);
1006 (Fpoint_marker (), 1004 pdl->unwind_excursion.marker = Fpoint_marker ();
1007 Qnil, 1005 /* Selected window if current buffer is shown in it, nil otherwise. */
1008 /* Selected window if current buffer is shown in it, nil otherwise. */ 1006 pdl->unwind_excursion.window
1009 (EQ (XWINDOW (selected_window)->contents, Fcurrent_buffer ()) 1007 = (EQ (XWINDOW (selected_window)->contents, Fcurrent_buffer ())
1010 ? selected_window : Qnil), 1008 ? selected_window : Qnil);
1011 Qnil);
1012} 1009}
1013 1010
1014/* Restore saved buffer before leaving `save-excursion' special form. */ 1011/* Restore saved buffer before leaving `save-excursion' special form. */
1015 1012
1016void 1013void
1017save_excursion_restore (Lisp_Object info) 1014save_excursion_restore (Lisp_Object marker, Lisp_Object window)
1018{ 1015{
1019 Lisp_Object marker = XSAVE_OBJECT (info, 0);
1020 Lisp_Object window = XSAVE_OBJECT (info, 2);
1021 free_misc (info);
1022 Lisp_Object buffer = Fmarker_buffer (marker); 1016 Lisp_Object buffer = Fmarker_buffer (marker);
1023 /* If we're unwinding to top level, saved buffer may be deleted. This 1017 /* If we're unwinding to top level, saved buffer may be deleted. This
1024 means that all of its markers are unchained and so BUFFER is nil. */ 1018 means that all of its markers are unchained and so BUFFER is nil. */
@@ -1027,6 +1021,7 @@ save_excursion_restore (Lisp_Object info)
1027 1021
1028 Fset_buffer (buffer); 1022 Fset_buffer (buffer);
1029 1023
1024 /* Point marker. */
1030 Fgoto_char (marker); 1025 Fgoto_char (marker);
1031 unchain_marker (XMARKER (marker)); 1026 unchain_marker (XMARKER (marker));
1032 1027