aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2018-06-07 19:12:28 -0700
committerPaul Eggert2018-06-14 17:13:39 -0700
commitd98670eb04925fdc4a4928a9b0d0858881da418f (patch)
tree52d74dac7f568f7bcfe252ec9efd7658177895e0 /src
parentaca938d1f4ec176a2d00a77693b231298b9c5c4e (diff)
downloademacs-d98670eb04925fdc4a4928a9b0d0858881da418f.tar.gz
emacs-d98670eb04925fdc4a4928a9b0d0858881da418f.zip
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')
-rw-r--r--src/alloc.c7
-rw-r--r--src/eval.c19
-rw-r--r--src/lisp.h14
3 files changed, 37 insertions, 3 deletions
diff --git a/src/alloc.c b/src/alloc.c
index e5fc6ebeb1a..1d3ec4fbb8a 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -4845,6 +4845,13 @@ mark_maybe_object (Lisp_Object obj)
4845 } 4845 }
4846} 4846}
4847 4847
4848void
4849mark_maybe_objects (Lisp_Object *array, ptrdiff_t nelts)
4850{
4851 for (Lisp_Object *lim = array + nelts; array < lim; array++)
4852 mark_maybe_object (*array);
4853}
4854
4848/* Return true if P might point to Lisp data that can be garbage 4855/* Return true if P might point to Lisp data that can be garbage
4849 collected, and false otherwise (i.e., false if it is easy to see 4856 collected, and false otherwise (i.e., false if it is easy to see
4850 that P cannot point to Lisp data that can be garbage collected). 4857 that P cannot point to Lisp data that can be garbage collected).
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)
673 break; 673 break;
674 674
675 case SPECPDL_UNWIND: 675 case SPECPDL_UNWIND:
676 case SPECPDL_UNWIND_ARRAY:
676 case SPECPDL_UNWIND_PTR: 677 case SPECPDL_UNWIND_PTR:
677 case SPECPDL_UNWIND_INT: 678 case SPECPDL_UNWIND_INT:
678 case SPECPDL_UNWIND_EXCURSION: 679 case SPECPDL_UNWIND_EXCURSION:
@@ -3408,6 +3409,15 @@ record_unwind_protect (void (*function) (Lisp_Object), Lisp_Object arg)
3408} 3409}
3409 3410
3410void 3411void
3412record_unwind_protect_array (Lisp_Object *array, ptrdiff_t nelts)
3413{
3414 specpdl_ptr->unwind_array.kind = SPECPDL_UNWIND_ARRAY;
3415 specpdl_ptr->unwind_array.array = array;
3416 specpdl_ptr->unwind_array.nelts = nelts;
3417 grow_specpdl ();
3418}
3419
3420void
3411record_unwind_protect_ptr (void (*function) (void *), void *arg) 3421record_unwind_protect_ptr (void (*function) (void *), void *arg)
3412{ 3422{
3413 specpdl_ptr->unwind_ptr.kind = SPECPDL_UNWIND_PTR; 3423 specpdl_ptr->unwind_ptr.kind = SPECPDL_UNWIND_PTR;
@@ -3469,6 +3479,9 @@ do_one_unbind (union specbinding *this_binding, bool unwinding,
3469 case SPECPDL_UNWIND: 3479 case SPECPDL_UNWIND:
3470 this_binding->unwind.func (this_binding->unwind.arg); 3480 this_binding->unwind.func (this_binding->unwind.arg);
3471 break; 3481 break;
3482 case SPECPDL_UNWIND_ARRAY:
3483 xfree (this_binding->unwind_array.array);
3484 break;
3472 case SPECPDL_UNWIND_PTR: 3485 case SPECPDL_UNWIND_PTR:
3473 this_binding->unwind_ptr.func (this_binding->unwind_ptr.arg); 3486 this_binding->unwind_ptr.func (this_binding->unwind_ptr.arg);
3474 break; 3487 break;
@@ -3771,6 +3784,7 @@ backtrace_eval_unrewind (int distance)
3771 save_excursion_restore (marker, window); 3784 save_excursion_restore (marker, window);
3772 } 3785 }
3773 break; 3786 break;
3787 case SPECPDL_UNWIND_ARRAY:
3774 case SPECPDL_UNWIND_PTR: 3788 case SPECPDL_UNWIND_PTR:
3775 case SPECPDL_UNWIND_INT: 3789 case SPECPDL_UNWIND_INT:
3776 case SPECPDL_UNWIND_VOID: 3790 case SPECPDL_UNWIND_VOID:
@@ -3903,6 +3917,7 @@ NFRAMES and BASE specify the activation frame to use, as in `backtrace-frame'.
3903 break; 3917 break;
3904 3918
3905 case SPECPDL_UNWIND: 3919 case SPECPDL_UNWIND:
3920 case SPECPDL_UNWIND_ARRAY:
3906 case SPECPDL_UNWIND_PTR: 3921 case SPECPDL_UNWIND_PTR:
3907 case SPECPDL_UNWIND_INT: 3922 case SPECPDL_UNWIND_INT:
3908 case SPECPDL_UNWIND_EXCURSION: 3923 case SPECPDL_UNWIND_EXCURSION:
@@ -3935,6 +3950,10 @@ mark_specpdl (union specbinding *first, union specbinding *ptr)
3935 mark_object (specpdl_arg (pdl)); 3950 mark_object (specpdl_arg (pdl));
3936 break; 3951 break;
3937 3952
3953 case SPECPDL_UNWIND_ARRAY:
3954 mark_maybe_objects (pdl->unwind_array.array, pdl->unwind_array.nelts);
3955 break;
3956
3938 case SPECPDL_UNWIND_EXCURSION: 3957 case SPECPDL_UNWIND_EXCURSION:
3939 mark_object (pdl->unwind_excursion.marker); 3958 mark_object (pdl->unwind_excursion.marker);
3940 mark_object (pdl->unwind_excursion.window); 3959 mark_object (pdl->unwind_excursion.window);
diff --git a/src/lisp.h b/src/lisp.h
index af3f587222d..f02b50bad75 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3186,6 +3186,8 @@ extern void defvar_kboard (struct Lisp_Kboard_Objfwd *, const char *, int);
3186 3186
3187enum specbind_tag { 3187enum specbind_tag {
3188 SPECPDL_UNWIND, /* An unwind_protect function on Lisp_Object. */ 3188 SPECPDL_UNWIND, /* An unwind_protect function on Lisp_Object. */
3189 SPECPDL_UNWIND_ARRAY, /* Likewise, on an array that needs freeing.
3190 Its elements are potential Lisp_Objects. */
3189 SPECPDL_UNWIND_PTR, /* Likewise, on void *. */ 3191 SPECPDL_UNWIND_PTR, /* Likewise, on void *. */
3190 SPECPDL_UNWIND_INT, /* Likewise, on int. */ 3192 SPECPDL_UNWIND_INT, /* Likewise, on int. */
3191 SPECPDL_UNWIND_EXCURSION, /* Likewise, on an execursion. */ 3193 SPECPDL_UNWIND_EXCURSION, /* Likewise, on an execursion. */
@@ -3207,6 +3209,12 @@ union specbinding
3207 } unwind; 3209 } unwind;
3208 struct { 3210 struct {
3209 ENUM_BF (specbind_tag) kind : CHAR_BIT; 3211 ENUM_BF (specbind_tag) kind : CHAR_BIT;
3212 void (*func) (Lisp_Object);
3213 Lisp_Object *array;
3214 ptrdiff_t nelts;
3215 } unwind_array;
3216 struct {
3217 ENUM_BF (specbind_tag) kind : CHAR_BIT;
3210 void (*func) (void *); 3218 void (*func) (void *);
3211 void *arg; 3219 void *arg;
3212 } unwind_ptr; 3220 } unwind_ptr;
@@ -3702,6 +3710,7 @@ extern void refill_memory_reserve (void);
3702#endif 3710#endif
3703extern void alloc_unexec_pre (void); 3711extern void alloc_unexec_pre (void);
3704extern void alloc_unexec_post (void); 3712extern void alloc_unexec_post (void);
3713extern void mark_maybe_objects (Lisp_Object *, ptrdiff_t);
3705extern void mark_stack (char *, char *); 3714extern void mark_stack (char *, char *);
3706extern void flush_stack_call_func (void (*func) (void *arg), void *arg); 3715extern void flush_stack_call_func (void (*func) (void *arg), void *arg);
3707extern const char *pending_malloc_warning; 3716extern const char *pending_malloc_warning;
@@ -4016,6 +4025,7 @@ extern struct handler *push_handler (Lisp_Object, enum handlertype);
4016extern struct handler *push_handler_nosignal (Lisp_Object, enum handlertype); 4025extern struct handler *push_handler_nosignal (Lisp_Object, enum handlertype);
4017extern void specbind (Lisp_Object, Lisp_Object); 4026extern void specbind (Lisp_Object, Lisp_Object);
4018extern void record_unwind_protect (void (*) (Lisp_Object), Lisp_Object); 4027extern void record_unwind_protect (void (*) (Lisp_Object), Lisp_Object);
4028extern void record_unwind_protect_array (Lisp_Object *, ptrdiff_t);
4019extern void record_unwind_protect_ptr (void (*) (void *), void *); 4029extern void record_unwind_protect_ptr (void (*) (void *), void *);
4020extern void record_unwind_protect_int (void (*) (int), int); 4030extern void record_unwind_protect_int (void (*) (int), int);
4021extern void record_unwind_protect_void (void (*) (void)); 4031extern void record_unwind_protect_void (void (*) (void));
@@ -4710,11 +4720,9 @@ extern void *record_xmalloc (size_t) ATTRIBUTE_ALLOC_SIZE ((1));
4710 (buf) = AVAIL_ALLOCA (alloca_nbytes); \ 4720 (buf) = AVAIL_ALLOCA (alloca_nbytes); \
4711 else \ 4721 else \
4712 { \ 4722 { \
4713 Lisp_Object arg_; \
4714 (buf) = xmalloc (alloca_nbytes); \ 4723 (buf) = xmalloc (alloca_nbytes); \
4715 arg_ = make_save_memory (buf, nelt); \ 4724 record_unwind_protect_array (buf, nelt); \
4716 sa_must_free = true; \ 4725 sa_must_free = true; \
4717 record_unwind_protect (free_save_value, arg_); \
4718 } \ 4726 } \
4719 } while (false) 4727 } while (false)
4720 4728