[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] master aca938d 07/10: Avoid allocating Lisp_Save_Value for
From: |
Paul Eggert |
Subject: |
[Emacs-diffs] master aca938d 07/10: Avoid allocating Lisp_Save_Value for excursions |
Date: |
Thu, 14 Jun 2018 20:15:25 -0400 (EDT) |
branch: master
commit aca938d1f4ec176a2d00a77693b231298b9c5c4e
Author: Paul Eggert <address@hidden>
Commit: Paul Eggert <address@hidden>
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.
---
src/editfns.c | 27 +++++++++++----------------
src/eval.c | 38 +++++++++++++++++++++++++++-----------
src/lisp.h | 9 +++++++--
3 files changed, 45 insertions(+), 29 deletions(-)
diff --git a/src/editfns.c b/src/editfns.c
index e672c0e..3147f9d 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -995,30 +995,24 @@ This function does not move point. */)
Qnil, Qt, Qnil);
}
-/* Save current buffer state for `save-excursion' special form.
- We (ab)use Lisp_Misc_Save_Value to allow explicit free and so
- offload some work from GC. */
+/* Save current buffer state for save-excursion special form. */
-Lisp_Object
-save_excursion_save (void)
+void
+save_excursion_save (union specbinding *pdl)
{
- return make_save_obj_obj_obj_obj
- (Fpoint_marker (),
- Qnil,
- /* Selected window if current buffer is shown in it, nil otherwise. */
- (EQ (XWINDOW (selected_window)->contents, Fcurrent_buffer ())
- ? selected_window : Qnil),
- Qnil);
+ eassert (pdl->unwind_excursion.kind == SPECPDL_UNWIND_EXCURSION);
+ pdl->unwind_excursion.marker = Fpoint_marker ();
+ /* Selected window if current buffer is shown in it, nil otherwise. */
+ pdl->unwind_excursion.window
+ = (EQ (XWINDOW (selected_window)->contents, Fcurrent_buffer ())
+ ? selected_window : Qnil);
}
/* Restore saved buffer before leaving `save-excursion' special form. */
void
-save_excursion_restore (Lisp_Object info)
+save_excursion_restore (Lisp_Object marker, Lisp_Object window)
{
- Lisp_Object marker = XSAVE_OBJECT (info, 0);
- Lisp_Object window = XSAVE_OBJECT (info, 2);
- free_misc (info);
Lisp_Object buffer = Fmarker_buffer (marker);
/* If we're unwinding to top level, saved buffer may be deleted. This
means that all of its markers are unchained and so BUFFER is nil. */
@@ -1027,6 +1021,7 @@ save_excursion_restore (Lisp_Object info)
Fset_buffer (buffer);
+ /* Point marker. */
Fgoto_char (marker);
unchain_marker (XMARKER (marker));
diff --git a/src/eval.c b/src/eval.c
index 5c7cb31..dded16b 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -675,6 +675,7 @@ default_toplevel_binding (Lisp_Object symbol)
case SPECPDL_UNWIND:
case SPECPDL_UNWIND_PTR:
case SPECPDL_UNWIND_INT:
+ case SPECPDL_UNWIND_EXCURSION:
case SPECPDL_UNWIND_VOID:
case SPECPDL_BACKTRACE:
case SPECPDL_LET_LOCAL:
@@ -3427,7 +3428,9 @@ record_unwind_protect_int (void (*function) (int), int
arg)
void
record_unwind_protect_excursion (void)
{
- record_unwind_protect (save_excursion_restore, save_excursion_save ());
+ specpdl_ptr->unwind_excursion.kind = SPECPDL_UNWIND_EXCURSION;
+ save_excursion_save (specpdl_ptr);
+ grow_specpdl ();
}
void
@@ -3475,6 +3478,10 @@ do_one_unbind (union specbinding *this_binding, bool
unwinding,
case SPECPDL_UNWIND_VOID:
this_binding->unwind_void.func ();
break;
+ case SPECPDL_UNWIND_EXCURSION:
+ save_excursion_restore (this_binding->unwind_excursion.marker,
+ this_binding->unwind_excursion.window);
+ break;
case SPECPDL_BACKTRACE:
break;
case SPECPDL_LET:
@@ -3749,18 +3756,21 @@ backtrace_eval_unrewind (int distance)
unwind_protect, but the problem is that we don't know how to
rewind them afterwards. */
case SPECPDL_UNWIND:
- {
- Lisp_Object oldarg = tmp->unwind.arg;
- if (tmp->unwind.func == set_buffer_if_live)
+ if (tmp->unwind.func == set_buffer_if_live)
+ {
+ Lisp_Object oldarg = tmp->unwind.arg;
tmp->unwind.arg = Fcurrent_buffer ();
- else if (tmp->unwind.func == save_excursion_restore)
- tmp->unwind.arg = save_excursion_save ();
- else
- break;
- tmp->unwind.func (oldarg);
- break;
+ set_buffer_if_live (oldarg);
+ }
+ break;
+ case SPECPDL_UNWIND_EXCURSION:
+ {
+ Lisp_Object marker = tmp->unwind_excursion.marker;
+ Lisp_Object window = tmp->unwind_excursion.window;
+ save_excursion_save (tmp);
+ save_excursion_restore (marker, window);
}
-
+ break;
case SPECPDL_UNWIND_PTR:
case SPECPDL_UNWIND_INT:
case SPECPDL_UNWIND_VOID:
@@ -3895,6 +3905,7 @@ NFRAMES and BASE specify the activation frame to use, as
in `backtrace-frame'.
case SPECPDL_UNWIND:
case SPECPDL_UNWIND_PTR:
case SPECPDL_UNWIND_INT:
+ case SPECPDL_UNWIND_EXCURSION:
case SPECPDL_UNWIND_VOID:
case SPECPDL_BACKTRACE:
break;
@@ -3924,6 +3935,11 @@ mark_specpdl (union specbinding *first, union
specbinding *ptr)
mark_object (specpdl_arg (pdl));
break;
+ case SPECPDL_UNWIND_EXCURSION:
+ mark_object (pdl->unwind_excursion.marker);
+ mark_object (pdl->unwind_excursion.window);
+ break;
+
case SPECPDL_BACKTRACE:
{
ptrdiff_t nargs = backtrace_nargs (pdl);
diff --git a/src/lisp.h b/src/lisp.h
index b7e5d9e..af3f587 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3188,6 +3188,7 @@ enum specbind_tag {
SPECPDL_UNWIND, /* An unwind_protect function on Lisp_Object.
*/
SPECPDL_UNWIND_PTR, /* Likewise, on void *. */
SPECPDL_UNWIND_INT, /* Likewise, on int. */
+ SPECPDL_UNWIND_EXCURSION, /* Likewise, on an execursion. */
SPECPDL_UNWIND_VOID, /* Likewise, with no arg. */
SPECPDL_BACKTRACE, /* An element of the backtrace. */
SPECPDL_LET, /* A plain and simple dynamic let-binding. */
@@ -3216,6 +3217,10 @@ union specbinding
} unwind_int;
struct {
ENUM_BF (specbind_tag) kind : CHAR_BIT;
+ Lisp_Object marker, window;
+ } unwind_excursion;
+ struct {
+ ENUM_BF (specbind_tag) kind : CHAR_BIT;
void (*func) (void);
} unwind_void;
struct {
@@ -4106,9 +4111,9 @@ extern void mark_threads (void);
/* Defined in editfns.c. */
extern void insert1 (Lisp_Object);
-extern Lisp_Object save_excursion_save (void);
+extern void save_excursion_save (union specbinding *);
+extern void save_excursion_restore (Lisp_Object, Lisp_Object);
extern Lisp_Object save_restriction_save (void);
-extern void save_excursion_restore (Lisp_Object);
extern void save_restriction_restore (Lisp_Object);
extern _Noreturn void time_overflow (void);
extern Lisp_Object make_buffer_string (ptrdiff_t, ptrdiff_t, bool);
- [Emacs-diffs] master updated (51adab5 -> 4139c98), Paul Eggert, 2018/06/14
- [Emacs-diffs] master 12fd59b 03/10: Avoid Lisp_Misc allocation if C stack suffices, Paul Eggert, 2018/06/14
- [Emacs-diffs] master ef66660 02/10: Simplify init_module_assertions, Paul Eggert, 2018/06/14
- [Emacs-diffs] master 3f0a8a2 04/10: Use record_unwind_protect_ptr to avoid allocation, Paul Eggert, 2018/06/14
- [Emacs-diffs] master 30d393f 01/10: New mint_ptr representation for C pointers, Paul Eggert, 2018/06/14
- [Emacs-diffs] master d98670e 08/10: Avoid allocating Lisp_Save_Value for arrays, Paul Eggert, 2018/06/14
- [Emacs-diffs] master f8ad6b3 09/10: New type Lisp_Misc_Ptr, Paul Eggert, 2018/06/14
- [Emacs-diffs] master aca938d 07/10: Avoid allocating Lisp_Save_Value for excursions,
Paul Eggert <=
- [Emacs-diffs] master 888bf98 05/10: Avoid allocating a Lisp_Save_Value in ftfont.c, Paul Eggert, 2018/06/14
- [Emacs-diffs] master 6c04c84 06/10: Just use cons in macfont_descriptor_entity, Paul Eggert, 2018/06/14
- [Emacs-diffs] master 4139c98 10/10: Remove Lisp_Misc_Save_Value, Paul Eggert, 2018/06/14