diff options
| author | Paul Eggert | 2019-07-20 19:40:03 -0700 |
|---|---|---|
| committer | Paul Eggert | 2019-07-20 20:13:46 -0700 |
| commit | 5018b663c6c0d31f27fb44630a69d9e0bd73273d (patch) | |
| tree | e256994675a86333f69cbfc045f82e0460fd2a97 /src/alloc.c | |
| parent | 26de2d42d0460c5b193456950a568cb04a29dc00 (diff) | |
| download | emacs-5018b663c6c0d31f27fb44630a69d9e0bd73273d.tar.gz emacs-5018b663c6c0d31f27fb44630a69d9e0bd73273d.zip | |
Inhibit GC after inhibit_garbage_collection
Without this patch, there are unlikely ways that garbage
collection could occur (sometimes causing undefined behavior)
even when inhibit_garbage_collection is in effect.
* src/alloc.c (garbage_collection_inhibited): New var.
(pure_alloc): Increment it if pure space is exhausted, so that
garbage_collect_1 no longer needs to inspect
pure_bytes_used_before_overflow.
(allow_garbage_collection): New function.
(inhibit_garbage_collection): Increment the new variable rather
than specbinding a user variable.
(garbage_collect_1): Do not garbage collect if the new variable
is set, rather than if pure_bytes_used_before_overflow is set.
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/src/alloc.c b/src/alloc.c index 9d18fd918bd..09b3a4ea7e4 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -292,6 +292,10 @@ static ptrdiff_t pure_bytes_used_lisp; | |||
| 292 | 292 | ||
| 293 | static ptrdiff_t pure_bytes_used_non_lisp; | 293 | static ptrdiff_t pure_bytes_used_non_lisp; |
| 294 | 294 | ||
| 295 | /* If positive, garbage collection is inhibited. Otherwise, zero. */ | ||
| 296 | |||
| 297 | static intptr_t garbage_collection_inhibited; | ||
| 298 | |||
| 295 | /* If nonzero, this is a warning delivered by malloc and not yet | 299 | /* If nonzero, this is a warning delivered by malloc and not yet |
| 296 | displayed. */ | 300 | displayed. */ |
| 297 | 301 | ||
| @@ -5120,6 +5124,10 @@ pure_alloc (size_t size, int type) | |||
| 5120 | pure_bytes_used_before_overflow += pure_bytes_used - size; | 5124 | pure_bytes_used_before_overflow += pure_bytes_used - size; |
| 5121 | pure_bytes_used = 0; | 5125 | pure_bytes_used = 0; |
| 5122 | pure_bytes_used_lisp = pure_bytes_used_non_lisp = 0; | 5126 | pure_bytes_used_lisp = pure_bytes_used_non_lisp = 0; |
| 5127 | |||
| 5128 | /* Can't GC if pure storage overflowed because we can't determine | ||
| 5129 | if something is a pure object or not. */ | ||
| 5130 | garbage_collection_inhibited++; | ||
| 5123 | goto again; | 5131 | goto again; |
| 5124 | } | 5132 | } |
| 5125 | 5133 | ||
| @@ -5486,12 +5494,19 @@ staticpro (Lisp_Object const *varaddress) | |||
| 5486 | 5494 | ||
| 5487 | /* Temporarily prevent garbage collection. */ | 5495 | /* Temporarily prevent garbage collection. */ |
| 5488 | 5496 | ||
| 5497 | static void | ||
| 5498 | allow_garbage_collection (void) | ||
| 5499 | { | ||
| 5500 | garbage_collection_inhibited--; | ||
| 5501 | } | ||
| 5502 | |||
| 5489 | ptrdiff_t | 5503 | ptrdiff_t |
| 5490 | inhibit_garbage_collection (void) | 5504 | inhibit_garbage_collection (void) |
| 5491 | { | 5505 | { |
| 5492 | ptrdiff_t count = SPECPDL_INDEX (); | 5506 | ptrdiff_t count = SPECPDL_INDEX (); |
| 5493 | 5507 | ||
| 5494 | specbind (Qgc_cons_threshold, make_fixnum (MOST_POSITIVE_FIXNUM)); | 5508 | record_unwind_protect_void (allow_garbage_collection); |
| 5509 | garbage_collection_inhibited++; | ||
| 5495 | return count; | 5510 | return count; |
| 5496 | } | 5511 | } |
| 5497 | 5512 | ||
| @@ -5779,9 +5794,7 @@ garbage_collect_1 (struct gcstat *gcst) | |||
| 5779 | 5794 | ||
| 5780 | eassert (weak_hash_tables == NULL); | 5795 | eassert (weak_hash_tables == NULL); |
| 5781 | 5796 | ||
| 5782 | /* Can't GC if pure storage overflowed because we can't determine | 5797 | if (garbage_collection_inhibited) |
| 5783 | if something is a pure object or not. */ | ||
| 5784 | if (pure_bytes_used_before_overflow) | ||
| 5785 | return false; | 5798 | return false; |
| 5786 | 5799 | ||
| 5787 | /* Record this function, so it appears on the profiler's backtraces. */ | 5800 | /* Record this function, so it appears on the profiler's backtraces. */ |