diff options
| author | Paul Eggert <eggert@cs.ucla.edu> | 2019-07-20 19:40:03 -0700 |
|---|---|---|
| committer | Paul Eggert <eggert@cs.ucla.edu> | 2019-07-20 20:13:46 -0700 |
| commit | 5018b663c6c0d31f27fb44630a69d9e0bd73273d (patch) | |
| tree | e256994675a86333f69cbfc045f82e0460fd2a97 /src/alloc.c | |
| parent | 26de2d42d0460c5b193456950a568cb04a29dc00 (diff) | |
| download | emacs-5018b663c6c0d31f27fb44630a69d9e0bd73273d.tar.gz | |
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; static ptrdiff_t pure_bytes_used_non_lisp; +/* If positive, garbage collection is inhibited. Otherwise, zero. */ + +static intptr_t garbage_collection_inhibited; + /* If nonzero, this is a warning delivered by malloc and not yet displayed. */ @@ -5120,6 +5124,10 @@ pure_alloc (size_t size, int type) pure_bytes_used_before_overflow += pure_bytes_used - size; pure_bytes_used = 0; pure_bytes_used_lisp = pure_bytes_used_non_lisp = 0; + + /* Can't GC if pure storage overflowed because we can't determine + if something is a pure object or not. */ + garbage_collection_inhibited++; goto again; } @@ -5486,12 +5494,19 @@ staticpro (Lisp_Object const *varaddress) /* Temporarily prevent garbage collection. */ +static void +allow_garbage_collection (void) +{ + garbage_collection_inhibited--; +} + ptrdiff_t inhibit_garbage_collection (void) { ptrdiff_t count = SPECPDL_INDEX (); - specbind (Qgc_cons_threshold, make_fixnum (MOST_POSITIVE_FIXNUM)); + record_unwind_protect_void (allow_garbage_collection); + garbage_collection_inhibited++; return count; } @@ -5779,9 +5794,7 @@ garbage_collect_1 (struct gcstat *gcst) eassert (weak_hash_tables == NULL); - /* Can't GC if pure storage overflowed because we can't determine - if something is a pure object or not. */ - if (pure_bytes_used_before_overflow) + if (garbage_collection_inhibited) return false; /* Record this function, so it appears on the profiler's backtraces. */ |
