aboutsummaryrefslogtreecommitdiffstats
path: root/src/lisp.h
diff options
context:
space:
mode:
authorPaul Eggert2018-06-28 00:37:08 -0700
committerPaul Eggert2018-06-28 00:42:46 -0700
commit76eda952b09db6d79342b7ddfcae45c7c836ab62 (patch)
treec1283adb00332f30c98e46da61e427057948aacc /src/lisp.h
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.
Diffstat (limited to 'src/lisp.h')
-rw-r--r--src/lisp.h44
1 files changed, 32 insertions, 12 deletions
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