aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2019-07-20 19:40:03 -0700
committerPaul Eggert2019-07-20 20:13:46 -0700
commit26de2d42d0460c5b193456950a568cb04a29dc00 (patch)
tree4631c2f8901f2c9fa3cdfc266279c1667103c238 /src
parentdf5024dbaef5e1f7e39a2a8268523f9fc1af3118 (diff)
downloademacs-26de2d42d0460c5b193456950a568cb04a29dc00.tar.gz
emacs-26de2d42d0460c5b193456950a568cb04a29dc00.zip
Simplify maybe_gc implementation
* src/alloc.c (consing_until_gc): New variable, replacing the combination of consing_since_gc and gc_relative_threshold. All uses changed. (byte_ct): Move decl here from lisp.h. (memory_full_cons_threshold): New an enum constant. (free_cons): Check for integer overflow in statistics calculation. * src/lisp.h (object_ct): Move decl here from alloc.c. (OBJECT_CT_MAX): New macro. (maybe_gc): Simplify accordingly.
Diffstat (limited to 'src')
-rw-r--r--src/alloc.c68
-rw-r--r--src/lisp.h12
2 files changed, 38 insertions, 42 deletions
diff --git a/src/alloc.c b/src/alloc.c
index 8649d4e0f4c..9d18fd918bd 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -222,13 +222,9 @@ my_heap_start (void)
222/* Global variables. */ 222/* Global variables. */
223struct emacs_globals globals; 223struct emacs_globals globals;
224 224
225/* Number of bytes of consing done since the last gc. */ 225/* maybe_gc collects garbage if this goes negative. */
226 226
227byte_ct consing_since_gc; 227object_ct consing_until_gc;
228
229/* Similar minimum, computed from Vgc_cons_percentage. */
230
231byte_ct gc_relative_threshold;
232 228
233#ifdef HAVE_PDUMPER 229#ifdef HAVE_PDUMPER
234/* Number of finalizers run: used to loop over GC until we stop 230/* Number of finalizers run: used to loop over GC until we stop
@@ -240,10 +236,9 @@ int number_finalizers_run;
240 236
241bool gc_in_progress; 237bool gc_in_progress;
242 238
243/* Type of object counts reported by GC. Unlike byte_ct, this can be 239/* System byte counts reported by GC. */
244 signed, e.g., it is less than 2**31 on a typical 32-bit machine. */
245 240
246typedef intptr_t object_ct; 241typedef uintptr_t byte_ct;
247 242
248/* Number of live and free conses etc. */ 243/* Number of live and free conses etc. */
249 244
@@ -1373,7 +1368,7 @@ make_interval (void)
1373 1368
1374 MALLOC_UNBLOCK_INPUT; 1369 MALLOC_UNBLOCK_INPUT;
1375 1370
1376 consing_since_gc += sizeof (struct interval); 1371 consing_until_gc -= sizeof (struct interval);
1377 intervals_consed++; 1372 intervals_consed++;
1378 gcstat.total_free_intervals--; 1373 gcstat.total_free_intervals--;
1379 RESET_INTERVAL (val); 1374 RESET_INTERVAL (val);
@@ -1745,7 +1740,7 @@ allocate_string (void)
1745 gcstat.total_free_strings--; 1740 gcstat.total_free_strings--;
1746 gcstat.total_strings++; 1741 gcstat.total_strings++;
1747 ++strings_consed; 1742 ++strings_consed;
1748 consing_since_gc += sizeof *s; 1743 consing_until_gc -= sizeof *s;
1749 1744
1750#ifdef GC_CHECK_STRING_BYTES 1745#ifdef GC_CHECK_STRING_BYTES
1751 if (!noninteractive) 1746 if (!noninteractive)
@@ -1865,7 +1860,7 @@ allocate_string_data (struct Lisp_String *s,
1865 old_data->string = NULL; 1860 old_data->string = NULL;
1866 } 1861 }
1867 1862
1868 consing_since_gc += needed; 1863 consing_until_gc -= needed;
1869} 1864}
1870 1865
1871 1866
@@ -2471,7 +2466,7 @@ make_float (double float_value)
2471 2466
2472 XFLOAT_INIT (val, float_value); 2467 XFLOAT_INIT (val, float_value);
2473 eassert (!XFLOAT_MARKED_P (XFLOAT (val))); 2468 eassert (!XFLOAT_MARKED_P (XFLOAT (val)));
2474 consing_since_gc += sizeof (struct Lisp_Float); 2469 consing_until_gc -= sizeof (struct Lisp_Float);
2475 floats_consed++; 2470 floats_consed++;
2476 gcstat.total_free_floats--; 2471 gcstat.total_free_floats--;
2477 return val; 2472 return val;
@@ -2521,7 +2516,7 @@ struct cons_block
2521/* Minimum number of bytes of consing since GC before next GC, 2516/* Minimum number of bytes of consing since GC before next GC,
2522 when memory is full. */ 2517 when memory is full. */
2523 2518
2524byte_ct const memory_full_cons_threshold = sizeof (struct cons_block); 2519enum { memory_full_cons_threshold = sizeof (struct cons_block) };
2525 2520
2526/* Current cons_block. */ 2521/* Current cons_block. */
2527 2522
@@ -2543,7 +2538,8 @@ free_cons (struct Lisp_Cons *ptr)
2543 ptr->u.s.u.chain = cons_free_list; 2538 ptr->u.s.u.chain = cons_free_list;
2544 ptr->u.s.car = dead_object (); 2539 ptr->u.s.car = dead_object ();
2545 cons_free_list = ptr; 2540 cons_free_list = ptr;
2546 consing_since_gc -= sizeof *ptr; 2541 if (INT_ADD_WRAPV (consing_until_gc, sizeof *ptr, &consing_until_gc))
2542 consing_until_gc = OBJECT_CT_MAX;
2547 gcstat.total_free_conses++; 2543 gcstat.total_free_conses++;
2548} 2544}
2549 2545
@@ -2594,7 +2590,7 @@ DEFUN ("cons", Fcons, Scons, 2, 2, 0,
2594 XSETCAR (val, car); 2590 XSETCAR (val, car);
2595 XSETCDR (val, cdr); 2591 XSETCDR (val, cdr);
2596 eassert (!XCONS_MARKED_P (XCONS (val))); 2592 eassert (!XCONS_MARKED_P (XCONS (val)));
2597 consing_since_gc += sizeof (struct Lisp_Cons); 2593 consing_until_gc -= sizeof (struct Lisp_Cons);
2598 gcstat.total_free_conses--; 2594 gcstat.total_free_conses--;
2599 cons_cells_consed++; 2595 cons_cells_consed++;
2600 return val; 2596 return val;
@@ -3176,7 +3172,7 @@ allocate_vectorlike (ptrdiff_t len)
3176 if (find_suspicious_object_in_range (p, (char *) p + nbytes)) 3172 if (find_suspicious_object_in_range (p, (char *) p + nbytes))
3177 emacs_abort (); 3173 emacs_abort ();
3178 3174
3179 consing_since_gc += nbytes; 3175 consing_until_gc -= nbytes;
3180 vector_cells_consed += len; 3176 vector_cells_consed += len;
3181 3177
3182 MALLOC_UNBLOCK_INPUT; 3178 MALLOC_UNBLOCK_INPUT;
@@ -3462,7 +3458,7 @@ Its value is void, and its function definition and property list are nil. */)
3462 MALLOC_UNBLOCK_INPUT; 3458 MALLOC_UNBLOCK_INPUT;
3463 3459
3464 init_symbol (val, name); 3460 init_symbol (val, name);
3465 consing_since_gc += sizeof (struct Lisp_Symbol); 3461 consing_until_gc -= sizeof (struct Lisp_Symbol);
3466 symbols_consed++; 3462 symbols_consed++;
3467 gcstat.total_free_symbols--; 3463 gcstat.total_free_symbols--;
3468 return val; 3464 return val;
@@ -3862,6 +3858,7 @@ memory_full (size_t nbytes)
3862 if (! enough_free_memory) 3858 if (! enough_free_memory)
3863 { 3859 {
3864 Vmemory_full = Qt; 3860 Vmemory_full = Qt;
3861 consing_until_gc = memory_full_cons_threshold;
3865 3862
3866 /* The first time we get here, free the spare memory. */ 3863 /* The first time we get here, free the spare memory. */
3867 for (int i = 0; i < ARRAYELTS (spare_memory); i++) 3864 for (int i = 0; i < ARRAYELTS (spare_memory); i++)
@@ -5802,7 +5799,7 @@ garbage_collect_1 (struct gcstat *gcst)
5802 5799
5803 /* In case user calls debug_print during GC, 5800 /* In case user calls debug_print during GC,
5804 don't let that cause a recursive GC. */ 5801 don't let that cause a recursive GC. */
5805 consing_since_gc = 0; 5802 consing_until_gc = OBJECT_CT_MAX;
5806 5803
5807 /* Save what's currently displayed in the echo area. Don't do that 5804 /* Save what's currently displayed in the echo area. Don't do that
5808 if we are GC'ing because we've run out of memory, since 5805 if we are GC'ing because we've run out of memory, since
@@ -5913,23 +5910,26 @@ garbage_collect_1 (struct gcstat *gcst)
5913 5910
5914 unblock_input (); 5911 unblock_input ();
5915 5912
5916 consing_since_gc = 0; 5913 if (!NILP (Vmemory_full))
5917 if (gc_cons_threshold < GC_DEFAULT_THRESHOLD / 10) 5914 consing_until_gc = memory_full_cons_threshold;
5918 gc_cons_threshold = GC_DEFAULT_THRESHOLD / 10; 5915 else
5919 5916 {
5920 gc_relative_threshold = 0; 5917 intptr_t threshold = min (max (GC_DEFAULT_THRESHOLD,
5921 if (FLOATP (Vgc_cons_percentage)) 5918 gc_cons_threshold >> 3),
5922 { /* Set gc_cons_combined_threshold. */ 5919 OBJECT_CT_MAX);
5923 double tot = total_bytes_of_live_objects (); 5920 if (FLOATP (Vgc_cons_percentage))
5924
5925 tot *= XFLOAT_DATA (Vgc_cons_percentage);
5926 if (0 < tot)
5927 { 5921 {
5928 if (tot < UINTPTR_MAX) 5922 double tot = (XFLOAT_DATA (Vgc_cons_percentage)
5929 gc_relative_threshold = tot; 5923 * total_bytes_of_live_objects ());
5930 else 5924 if (threshold < tot)
5931 gc_relative_threshold = UINTPTR_MAX; 5925 {
5926 if (tot < OBJECT_CT_MAX)
5927 threshold = tot;
5928 else
5929 threshold = OBJECT_CT_MAX;
5930 }
5932 } 5931 }
5932 consing_until_gc = threshold;
5933 } 5933 }
5934 5934
5935 if (garbage_collection_messages && NILP (Vmemory_full)) 5935 if (garbage_collection_messages && NILP (Vmemory_full))
diff --git a/src/lisp.h b/src/lisp.h
index 8f60963eb7e..50a61cadd7b 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3763,10 +3763,9 @@ extern void flush_stack_call_func (void (*func) (void *arg), void *arg);
3763extern void garbage_collect (void); 3763extern void garbage_collect (void);
3764extern const char *pending_malloc_warning; 3764extern const char *pending_malloc_warning;
3765extern Lisp_Object zero_vector; 3765extern Lisp_Object zero_vector;
3766typedef uintptr_t byte_ct; /* System byte counts reported by GC. */ 3766typedef intptr_t object_ct; /* Signed type of object counts reported by GC. */
3767extern byte_ct consing_since_gc; 3767#define OBJECT_CT_MAX INTPTR_MAX
3768extern byte_ct gc_relative_threshold; 3768extern object_ct consing_until_gc;
3769extern byte_ct const memory_full_cons_threshold;
3770#ifdef HAVE_PDUMPER 3769#ifdef HAVE_PDUMPER
3771extern int number_finalizers_run; 3770extern int number_finalizers_run;
3772#endif 3771#endif
@@ -4993,10 +4992,7 @@ struct for_each_tail_internal
4993INLINE void 4992INLINE void
4994maybe_gc (void) 4993maybe_gc (void)
4995{ 4994{
4996 if ((consing_since_gc > gc_cons_threshold 4995 if (consing_until_gc < 0)
4997 && consing_since_gc > gc_relative_threshold)
4998 || (!NILP (Vmemory_full)
4999 && consing_since_gc > memory_full_cons_threshold))
5000 garbage_collect (); 4996 garbage_collect ();
5001} 4997}
5002 4998