aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
authorPaul Eggert2019-07-20 19:40:03 -0700
committerPaul Eggert2019-07-20 20:13:46 -0700
commit5018b663c6c0d31f27fb44630a69d9e0bd73273d (patch)
treee256994675a86333f69cbfc045f82e0460fd2a97 /src/alloc.c
parent26de2d42d0460c5b193456950a568cb04a29dc00 (diff)
downloademacs-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.c21
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
293static ptrdiff_t pure_bytes_used_non_lisp; 293static ptrdiff_t pure_bytes_used_non_lisp;
294 294
295/* If positive, garbage collection is inhibited. Otherwise, zero. */
296
297static 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
5497static void
5498allow_garbage_collection (void)
5499{
5500 garbage_collection_inhibited--;
5501}
5502
5489ptrdiff_t 5503ptrdiff_t
5490inhibit_garbage_collection (void) 5504inhibit_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. */