aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert2018-06-28 00:37:08 -0700
committerPaul Eggert2018-06-28 00:42:46 -0700
commit76eda952b09db6d79342b7ddfcae45c7c836ab62 (patch)
treec1283adb00332f30c98e46da61e427057948aacc
parent79f6911bf1f6262c723f5a3602c2f80cbe63cf54 (diff)
downloademacs-76eda952b09db6d79342b7ddfcae45c7c836ab62.tar.gz
emacs-76eda952b09db6d79342b7ddfcae45c7c836ab62.zip
Tune SAFE_FREE
On my platform (Fedora 28 x86-64, AMD Phenom II X4 910e) this sped up a SAFE_FREE-using microbenchmark (string-distance "abc" "abc") by about 18%, and shrank the Emacs text size by about 0.1%. * src/callint.c (Fcall_interactively): * src/callproc.c (call_process): * src/doc.c (get_doc_string, Fsnarf_documentation): * src/editfns.c (Freplace_buffer_contents): * src/emacs-module.c (funcall_module): * src/eval.c (Flet): * src/process.c (Fmake_process): * src/term.c (tty_menu_show): * src/xdisp.c (safe__call): * src/xmenu.c (x_menu_show): Use SAFE_FREE_UNBIND_TO. * src/data.c (wrong_choice): No need to call SAFE_FREE here. * src/lisp.h (USE_SAFE_ALLOCA): * src/regex.c (REGEX_USE_SAFE_ALLOCA): Do not declare sa_must_free local; no longer needed. All uses removed. (SAFE_FREE): Rewrite in terms of safe_free. (safe_free): New function, optimized to use xfree. (SAFE_FREE_UNBIND_TO): New macro. (safe_free_unbind_to): New function.
-rw-r--r--src/callint.c3
-rw-r--r--src/callproc.c5
-rw-r--r--src/data.c5
-rw-r--r--src/doc.c9
-rw-r--r--src/editfns.c8
-rw-r--r--src/emacs-module.c3
-rw-r--r--src/eval.c3
-rw-r--r--src/lisp.h44
-rw-r--r--src/process.c3
-rw-r--r--src/regex.c2
-rw-r--r--src/term.c4
-rw-r--r--src/xdisp.c3
-rw-r--r--src/xmenu.c3
13 files changed, 51 insertions, 44 deletions
diff --git a/src/callint.c b/src/callint.c
index fd44494cfee..c6e003ed408 100644
--- a/src/callint.c
+++ b/src/callint.c
@@ -779,8 +779,7 @@ invoke it. If KEYS is omitted or nil, the return value of
779 specbind (Qcommand_debug_status, Qnil); 779 specbind (Qcommand_debug_status, Qnil);
780 780
781 Lisp_Object val = Ffuncall (nargs, args); 781 Lisp_Object val = Ffuncall (nargs, args);
782 SAFE_FREE (); 782 return SAFE_FREE_UNBIND_TO (speccount, val);
783 return unbind_to (speccount, val);
784} 783}
785 784
786DEFUN ("prefix-numeric-value", Fprefix_numeric_value, Sprefix_numeric_value, 785DEFUN ("prefix-numeric-value", Fprefix_numeric_value, Sprefix_numeric_value,
diff --git a/src/callproc.c b/src/callproc.c
index 973f324139c..17eb8132d96 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -599,7 +599,6 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd,
599 Lisp_Object volatile coding_systems_volatile = coding_systems; 599 Lisp_Object volatile coding_systems_volatile = coding_systems;
600 Lisp_Object volatile current_dir_volatile = current_dir; 600 Lisp_Object volatile current_dir_volatile = current_dir;
601 bool volatile display_p_volatile = display_p; 601 bool volatile display_p_volatile = display_p;
602 bool volatile sa_must_free_volatile = sa_must_free;
603 int volatile fd_error_volatile = fd_error; 602 int volatile fd_error_volatile = fd_error;
604 int volatile filefd_volatile = filefd; 603 int volatile filefd_volatile = filefd;
605 ptrdiff_t volatile count_volatile = count; 604 ptrdiff_t volatile count_volatile = count;
@@ -616,7 +615,6 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd,
616 coding_systems = coding_systems_volatile; 615 coding_systems = coding_systems_volatile;
617 current_dir = current_dir_volatile; 616 current_dir = current_dir_volatile;
618 display_p = display_p_volatile; 617 display_p = display_p_volatile;
619 sa_must_free = sa_must_free_volatile;
620 fd_error = fd_error_volatile; 618 fd_error = fd_error_volatile;
621 filefd = filefd_volatile; 619 filefd = filefd_volatile;
622 count = count_volatile; 620 count = count_volatile;
@@ -885,8 +883,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd,
885 when exiting. */ 883 when exiting. */
886 synch_process_pid = 0; 884 synch_process_pid = 0;
887 885
888 SAFE_FREE (); 886 SAFE_FREE_UNBIND_TO (count, Qnil);
889 unbind_to (count, Qnil);
890 887
891 if (!wait_ok) 888 if (!wait_ok)
892 return build_unibyte_string ("internal error"); 889 return build_unibyte_string ("internal error");
diff --git a/src/data.c b/src/data.c
index 49c3dd834ba..605a5f43af7 100644
--- a/src/data.c
+++ b/src/data.c
@@ -1049,7 +1049,10 @@ wrong_choice (Lisp_Object choice, Lisp_Object wrong)
1049 } 1049 }
1050 1050
1051 obj = Fconcat (i, args); 1051 obj = Fconcat (i, args);
1052 SAFE_FREE (); 1052
1053 /* No need to call SAFE_FREE, since signaling does that for us. */
1054 (void) sa_count;
1055
1053 xsignal2 (Qerror, obj, wrong); 1056 xsignal2 (Qerror, obj, wrong);
1054} 1057}
1055 1058
diff --git a/src/doc.c b/src/doc.c
index 4264ed50640..075154e94bc 100644
--- a/src/doc.c
+++ b/src/doc.c
@@ -86,7 +86,7 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition)
86 int offset; 86 int offset;
87 EMACS_INT position; 87 EMACS_INT position;
88 Lisp_Object file, tem, pos; 88 Lisp_Object file, tem, pos;
89 ptrdiff_t count; 89 ptrdiff_t count = SPECPDL_INDEX ();
90 USE_SAFE_ALLOCA; 90 USE_SAFE_ALLOCA;
91 91
92 if (INTEGERP (filepos)) 92 if (INTEGERP (filepos))
@@ -148,7 +148,6 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition)
148 return concat3 (cannot_open, file, quote_nl); 148 return concat3 (cannot_open, file, quote_nl);
149 } 149 }
150 } 150 }
151 count = SPECPDL_INDEX ();
152 record_unwind_protect_int (close_file_unwind, fd); 151 record_unwind_protect_int (close_file_unwind, fd);
153 152
154 /* Seek only to beginning of disk block. */ 153 /* Seek only to beginning of disk block. */
@@ -204,8 +203,7 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition)
204 } 203 }
205 p += nread; 204 p += nread;
206 } 205 }
207 unbind_to (count, Qnil); 206 SAFE_FREE_UNBIND_TO (count, Qnil);
208 SAFE_FREE ();
209 207
210 /* Sanity checking. */ 208 /* Sanity checking. */
211 if (CONSP (filepos)) 209 if (CONSP (filepos))
@@ -659,8 +657,7 @@ the same file name is found in the `doc-directory'. */)
659 memmove (buf, end, filled); 657 memmove (buf, end, filled);
660 } 658 }
661 659
662 SAFE_FREE (); 660 return SAFE_FREE_UNBIND_TO (count, Qnil);
663 return unbind_to (count, Qnil);
664} 661}
665 662
666/* Return true if text quoting style should default to quote `like this'. */ 663/* Return true if text quoting style should default to quote `like this'. */
diff --git a/src/editfns.c b/src/editfns.c
index 7d032a7ca4c..88dfba1f910 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -3198,6 +3198,8 @@ differences between the two buffers. */)
3198 return Qnil; 3198 return Qnil;
3199 } 3199 }
3200 3200
3201 ptrdiff_t count = SPECPDL_INDEX ();
3202
3201 /* FIXME: It is not documented how to initialize the contents of the 3203 /* FIXME: It is not documented how to initialize the contents of the
3202 context structure. This code cargo-cults from the existing 3204 context structure. This code cargo-cults from the existing
3203 caller in src/analyze.c of GNU Diffutils, which appears to 3205 caller in src/analyze.c of GNU Diffutils, which appears to
@@ -3231,7 +3233,6 @@ differences between the two buffers. */)
3231 eassert (! early_abort); 3233 eassert (! early_abort);
3232 3234
3233 Fundo_boundary (); 3235 Fundo_boundary ();
3234 ptrdiff_t count = SPECPDL_INDEX ();
3235 record_unwind_protect_excursion (); 3236 record_unwind_protect_excursion ();
3236 3237
3237 ptrdiff_t i = size_a; 3238 ptrdiff_t i = size_a;
@@ -3279,10 +3280,8 @@ differences between the two buffers. */)
3279 --i; 3280 --i;
3280 --j; 3281 --j;
3281 } 3282 }
3282 unbind_to (count, Qnil);
3283 SAFE_FREE ();
3284 3283
3285 return Qnil; 3284 return SAFE_FREE_UNBIND_TO (count, Qnil);
3286} 3285}
3287 3286
3288static void 3287static void
@@ -4885,7 +4884,6 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
4885 if (buf == initial_buffer) 4884 if (buf == initial_buffer)
4886 { 4885 {
4887 buf = xmalloc (bufsize); 4886 buf = xmalloc (bufsize);
4888 sa_must_free = true;
4889 buf_save_value_index = SPECPDL_INDEX (); 4887 buf_save_value_index = SPECPDL_INDEX ();
4890 record_unwind_protect_ptr (xfree, buf); 4888 record_unwind_protect_ptr (xfree, buf);
4891 memcpy (buf, initial_buffer, used); 4889 memcpy (buf, initial_buffer, used);
diff --git a/src/emacs-module.c b/src/emacs-module.c
index 3a246637990..5b9f6629e76 100644
--- a/src/emacs-module.c
+++ b/src/emacs-module.c
@@ -786,7 +786,6 @@ funcall_module (Lisp_Object function, ptrdiff_t nargs, Lisp_Object *arglist)
786 } 786 }
787 787
788 emacs_value ret = func->subr (env, nargs, args, func->data); 788 emacs_value ret = func->subr (env, nargs, args, func->data);
789 SAFE_FREE ();
790 789
791 eassert (&priv == env->private_members); 790 eassert (&priv == env->private_members);
792 791
@@ -795,7 +794,7 @@ funcall_module (Lisp_Object function, ptrdiff_t nargs, Lisp_Object *arglist)
795 maybe_quit (); 794 maybe_quit ();
796 795
797 module_signal_or_throw (&priv); 796 module_signal_or_throw (&priv);
798 return unbind_to (count, value_to_lisp (ret)); 797 return SAFE_FREE_UNBIND_TO (count, value_to_lisp (ret));
799} 798}
800 799
801Lisp_Object 800Lisp_Object
diff --git a/src/eval.c b/src/eval.c
index 952a0ec4b46..9e0fabdcfba 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -981,8 +981,7 @@ usage: (let VARLIST BODY...) */)
981 specbind (Qinternal_interpreter_environment, lexenv); 981 specbind (Qinternal_interpreter_environment, lexenv);
982 982
983 elt = Fprogn (XCDR (args)); 983 elt = Fprogn (XCDR (args));
984 SAFE_FREE (); 984 return SAFE_FREE_UNBIND_TO (count, elt);
985 return unbind_to (count, elt);
986} 985}
987 986
988DEFUN ("while", Fwhile, Swhile, 1, UNEVALLED, 0, 987DEFUN ("while", Fwhile, Swhile, 1, UNEVALLED, 0,
diff --git a/src/lisp.h b/src/lisp.h
index 8c884dce150..b544d814d99 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -4500,7 +4500,7 @@ extern void *record_xmalloc (size_t) ATTRIBUTE_ALLOC_SIZE ((1));
4500 4500
4501#define USE_SAFE_ALLOCA \ 4501#define USE_SAFE_ALLOCA \
4502 ptrdiff_t sa_avail = MAX_ALLOCA; \ 4502 ptrdiff_t sa_avail = MAX_ALLOCA; \
4503 ptrdiff_t sa_count = SPECPDL_INDEX (); bool sa_must_free = false 4503 ptrdiff_t sa_count = SPECPDL_INDEX ()
4504 4504
4505#define AVAIL_ALLOCA(size) (sa_avail -= (size), alloca (size)) 4505#define AVAIL_ALLOCA(size) (sa_avail -= (size), alloca (size))
4506 4506
@@ -4508,7 +4508,7 @@ extern void *record_xmalloc (size_t) ATTRIBUTE_ALLOC_SIZE ((1));
4508 4508
4509#define SAFE_ALLOCA(size) ((size) <= sa_avail \ 4509#define SAFE_ALLOCA(size) ((size) <= sa_avail \
4510 ? AVAIL_ALLOCA (size) \ 4510 ? AVAIL_ALLOCA (size) \
4511 : (sa_must_free = true, record_xmalloc (size))) 4511 : record_xmalloc (size))
4512 4512
4513/* SAFE_NALLOCA sets BUF to a newly allocated array of MULTIPLIER * 4513/* SAFE_NALLOCA sets BUF to a newly allocated array of MULTIPLIER *
4514 NITEMS items, each of the same type as *BUF. MULTIPLIER must 4514 NITEMS items, each of the same type as *BUF. MULTIPLIER must
@@ -4521,7 +4521,6 @@ extern void *record_xmalloc (size_t) ATTRIBUTE_ALLOC_SIZE ((1));
4521 else \ 4521 else \
4522 { \ 4522 { \
4523 (buf) = xnmalloc (nitems, sizeof *(buf) * (multiplier)); \ 4523 (buf) = xnmalloc (nitems, sizeof *(buf) * (multiplier)); \
4524 sa_must_free = true; \
4525 record_unwind_protect_ptr (xfree, buf); \ 4524 record_unwind_protect_ptr (xfree, buf); \
4526 } \ 4525 } \
4527 } while (false) 4526 } while (false)
@@ -4534,15 +4533,37 @@ extern void *record_xmalloc (size_t) ATTRIBUTE_ALLOC_SIZE ((1));
4534 memcpy (ptr, SDATA (string), SBYTES (string) + 1); \ 4533 memcpy (ptr, SDATA (string), SBYTES (string) + 1); \
4535 } while (false) 4534 } while (false)
4536 4535
4537/* SAFE_FREE frees xmalloced memory and enables GC as needed. */ 4536/* Free xmalloced memory and enable GC as needed. */
4538 4537
4539#define SAFE_FREE() \ 4538#define SAFE_FREE() safe_free (sa_count)
4540 do { \ 4539
4541 if (sa_must_free) { \ 4540INLINE void
4542 sa_must_free = false; \ 4541safe_free (ptrdiff_t sa_count)
4543 unbind_to (sa_count, Qnil); \ 4542{
4544 } \ 4543 while (specpdl_ptr != specpdl + sa_count)
4545 } while (false) 4544 {
4545 specpdl_ptr--;
4546 eassert (specpdl_ptr->kind == SPECPDL_UNWIND_PTR
4547 && specpdl_ptr->unwind_ptr.func == xfree);
4548 xfree (specpdl_ptr->unwind_ptr.arg);
4549 }
4550}
4551
4552/* Pop the specpdl stack back to COUNT, and return VAL.
4553 Prefer this to { SAFE_FREE (); unbind_to (COUNT, VAL); }
4554 when COUNT predates USE_SAFE_ALLOCA, as it is a bit more efficient
4555 and also lets callers intermix SAFE_ALLOCA calls with other calls
4556 that grow the specpdl stack. */
4557
4558#define SAFE_FREE_UNBIND_TO(count, val) \
4559 safe_free_unbind_to (count, sa_count, val)
4560
4561INLINE Lisp_Object
4562safe_free_unbind_to (ptrdiff_t count, ptrdiff_t sa_count, Lisp_Object val)
4563{
4564 eassert (count <= sa_count);
4565 return unbind_to (count, val);
4566}
4546 4567
4547/* Set BUF to point to an allocated array of NELT Lisp_Objects, 4568/* Set BUF to point to an allocated array of NELT Lisp_Objects,
4548 immediately followed by EXTRA spare bytes. */ 4569 immediately followed by EXTRA spare bytes. */
@@ -4560,7 +4581,6 @@ extern void *record_xmalloc (size_t) ATTRIBUTE_ALLOC_SIZE ((1));
4560 { \ 4581 { \
4561 (buf) = xmalloc (alloca_nbytes); \ 4582 (buf) = xmalloc (alloca_nbytes); \
4562 record_unwind_protect_array (buf, nelt); \ 4583 record_unwind_protect_array (buf, nelt); \
4563 sa_must_free = true; \
4564 } \ 4584 } \
4565 } while (false) 4585 } while (false)
4566 4586
diff --git a/src/process.c b/src/process.c
index 6dba218c907..279b74bc66e 100644
--- a/src/process.c
+++ b/src/process.c
@@ -1923,8 +1923,7 @@ usage: (make-process &rest ARGS) */)
1923 else 1923 else
1924 create_pty (proc); 1924 create_pty (proc);
1925 1925
1926 SAFE_FREE (); 1926 return SAFE_FREE_UNBIND_TO (count, proc);
1927 return unbind_to (count, proc);
1928} 1927}
1929 1928
1930/* If PROC doesn't have its pid set, then an error was signaled and 1929/* If PROC doesn't have its pid set, then an error was signaled and
diff --git a/src/regex.c b/src/regex.c
index b8c6f3f19b2..6ee13c4c99d 100644
--- a/src/regex.c
+++ b/src/regex.c
@@ -455,7 +455,7 @@ ptrdiff_t emacs_re_safe_alloca = MAX_ALLOCA;
455/* Like USE_SAFE_ALLOCA, but use emacs_re_safe_alloca. */ 455/* Like USE_SAFE_ALLOCA, but use emacs_re_safe_alloca. */
456# define REGEX_USE_SAFE_ALLOCA \ 456# define REGEX_USE_SAFE_ALLOCA \
457 ptrdiff_t sa_avail = emacs_re_safe_alloca; \ 457 ptrdiff_t sa_avail = emacs_re_safe_alloca; \
458 ptrdiff_t sa_count = SPECPDL_INDEX (); bool sa_must_free = false 458 ptrdiff_t sa_count = SPECPDL_INDEX ()
459 459
460# define REGEX_SAFE_FREE() SAFE_FREE () 460# define REGEX_SAFE_FREE() SAFE_FREE ()
461# define REGEX_ALLOCATE SAFE_ALLOCA 461# define REGEX_ALLOCATE SAFE_ALLOCA
diff --git a/src/term.c b/src/term.c
index 85bfa84d937..f5fca7f987e 100644
--- a/src/term.c
+++ b/src/term.c
@@ -3776,9 +3776,7 @@ tty_menu_show (struct frame *f, int x, int y, int menuflags,
3776 3776
3777 tty_menu_end: 3777 tty_menu_end:
3778 3778
3779 SAFE_FREE (); 3779 return SAFE_FREE_UNBIND_TO (specpdl_count, entry);
3780 unbind_to (specpdl_count, Qnil);
3781 return entry;
3782} 3780}
3783 3781
3784#endif /* !MSDOS */ 3782#endif /* !MSDOS */
diff --git a/src/xdisp.c b/src/xdisp.c
index dcb002055b4..3406c2fb466 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -2637,8 +2637,7 @@ safe__call (bool inhibit_quit, ptrdiff_t nargs, Lisp_Object func, va_list ap)
2637 so there is no possibility of wanting to redisplay. */ 2637 so there is no possibility of wanting to redisplay. */
2638 val = internal_condition_case_n (Ffuncall, nargs, args, Qt, 2638 val = internal_condition_case_n (Ffuncall, nargs, args, Qt,
2639 safe_eval_handler); 2639 safe_eval_handler);
2640 SAFE_FREE (); 2640 val = SAFE_FREE_UNBIND_TO (count, val);
2641 val = unbind_to (count, val);
2642 } 2641 }
2643 2642
2644 return val; 2643 return val;
diff --git a/src/xmenu.c b/src/xmenu.c
index 6477d5b0aca..dc6f33112c5 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -2375,8 +2375,7 @@ x_menu_show (struct frame *f, int x, int y, int menuflags,
2375 2375
2376 return_entry: 2376 return_entry:
2377 unblock_input (); 2377 unblock_input ();
2378 SAFE_FREE (); 2378 return SAFE_FREE_UNBIND_TO (specpdl_count, entry);
2379 return unbind_to (specpdl_count, entry);
2380} 2379}
2381 2380
2382#endif /* not USE_X_TOOLKIT */ 2381#endif /* not USE_X_TOOLKIT */