diff options
Diffstat (limited to 'src/lisp.h')
| -rw-r--r-- | src/lisp.h | 44 |
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) { \ | 4540 | INLINE void |
| 4542 | sa_must_free = false; \ | 4541 | safe_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 | |||
| 4561 | INLINE Lisp_Object | ||
| 4562 | safe_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 | ||