[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] master 26de2d4 3/6: Simplify maybe_gc implementation
From: |
Paul Eggert |
Subject: |
[Emacs-diffs] master 26de2d4 3/6: Simplify maybe_gc implementation |
Date: |
Sat, 20 Jul 2019 23:13:53 -0400 (EDT) |
branch: master
commit 26de2d42d0460c5b193456950a568cb04a29dc00
Author: Paul Eggert <address@hidden>
Commit: Paul Eggert <address@hidden>
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.
---
src/alloc.c | 68 ++++++++++++++++++++++++++++++-------------------------------
src/lisp.h | 12 ++++-------
2 files changed, 38 insertions(+), 42 deletions(-)
diff --git a/src/alloc.c b/src/alloc.c
index 8649d4e..9d18fd9 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -222,13 +222,9 @@ my_heap_start (void)
/* Global variables. */
struct emacs_globals globals;
-/* Number of bytes of consing done since the last gc. */
+/* maybe_gc collects garbage if this goes negative. */
-byte_ct consing_since_gc;
-
-/* Similar minimum, computed from Vgc_cons_percentage. */
-
-byte_ct gc_relative_threshold;
+object_ct consing_until_gc;
#ifdef HAVE_PDUMPER
/* Number of finalizers run: used to loop over GC until we stop
@@ -240,10 +236,9 @@ int number_finalizers_run;
bool gc_in_progress;
-/* Type of object counts reported by GC. Unlike byte_ct, this can be
- signed, e.g., it is less than 2**31 on a typical 32-bit machine. */
+/* System byte counts reported by GC. */
-typedef intptr_t object_ct;
+typedef uintptr_t byte_ct;
/* Number of live and free conses etc. */
@@ -1373,7 +1368,7 @@ make_interval (void)
MALLOC_UNBLOCK_INPUT;
- consing_since_gc += sizeof (struct interval);
+ consing_until_gc -= sizeof (struct interval);
intervals_consed++;
gcstat.total_free_intervals--;
RESET_INTERVAL (val);
@@ -1745,7 +1740,7 @@ allocate_string (void)
gcstat.total_free_strings--;
gcstat.total_strings++;
++strings_consed;
- consing_since_gc += sizeof *s;
+ consing_until_gc -= sizeof *s;
#ifdef GC_CHECK_STRING_BYTES
if (!noninteractive)
@@ -1865,7 +1860,7 @@ allocate_string_data (struct Lisp_String *s,
old_data->string = NULL;
}
- consing_since_gc += needed;
+ consing_until_gc -= needed;
}
@@ -2471,7 +2466,7 @@ make_float (double float_value)
XFLOAT_INIT (val, float_value);
eassert (!XFLOAT_MARKED_P (XFLOAT (val)));
- consing_since_gc += sizeof (struct Lisp_Float);
+ consing_until_gc -= sizeof (struct Lisp_Float);
floats_consed++;
gcstat.total_free_floats--;
return val;
@@ -2521,7 +2516,7 @@ struct cons_block
/* Minimum number of bytes of consing since GC before next GC,
when memory is full. */
-byte_ct const memory_full_cons_threshold = sizeof (struct cons_block);
+enum { memory_full_cons_threshold = sizeof (struct cons_block) };
/* Current cons_block. */
@@ -2543,7 +2538,8 @@ free_cons (struct Lisp_Cons *ptr)
ptr->u.s.u.chain = cons_free_list;
ptr->u.s.car = dead_object ();
cons_free_list = ptr;
- consing_since_gc -= sizeof *ptr;
+ if (INT_ADD_WRAPV (consing_until_gc, sizeof *ptr, &consing_until_gc))
+ consing_until_gc = OBJECT_CT_MAX;
gcstat.total_free_conses++;
}
@@ -2594,7 +2590,7 @@ DEFUN ("cons", Fcons, Scons, 2, 2, 0,
XSETCAR (val, car);
XSETCDR (val, cdr);
eassert (!XCONS_MARKED_P (XCONS (val)));
- consing_since_gc += sizeof (struct Lisp_Cons);
+ consing_until_gc -= sizeof (struct Lisp_Cons);
gcstat.total_free_conses--;
cons_cells_consed++;
return val;
@@ -3176,7 +3172,7 @@ allocate_vectorlike (ptrdiff_t len)
if (find_suspicious_object_in_range (p, (char *) p + nbytes))
emacs_abort ();
- consing_since_gc += nbytes;
+ consing_until_gc -= nbytes;
vector_cells_consed += len;
MALLOC_UNBLOCK_INPUT;
@@ -3462,7 +3458,7 @@ Its value is void, and its function definition and
property list are nil. */)
MALLOC_UNBLOCK_INPUT;
init_symbol (val, name);
- consing_since_gc += sizeof (struct Lisp_Symbol);
+ consing_until_gc -= sizeof (struct Lisp_Symbol);
symbols_consed++;
gcstat.total_free_symbols--;
return val;
@@ -3862,6 +3858,7 @@ memory_full (size_t nbytes)
if (! enough_free_memory)
{
Vmemory_full = Qt;
+ consing_until_gc = memory_full_cons_threshold;
/* The first time we get here, free the spare memory. */
for (int i = 0; i < ARRAYELTS (spare_memory); i++)
@@ -5802,7 +5799,7 @@ garbage_collect_1 (struct gcstat *gcst)
/* In case user calls debug_print during GC,
don't let that cause a recursive GC. */
- consing_since_gc = 0;
+ consing_until_gc = OBJECT_CT_MAX;
/* Save what's currently displayed in the echo area. Don't do that
if we are GC'ing because we've run out of memory, since
@@ -5913,23 +5910,26 @@ garbage_collect_1 (struct gcstat *gcst)
unblock_input ();
- consing_since_gc = 0;
- if (gc_cons_threshold < GC_DEFAULT_THRESHOLD / 10)
- gc_cons_threshold = GC_DEFAULT_THRESHOLD / 10;
-
- gc_relative_threshold = 0;
- if (FLOATP (Vgc_cons_percentage))
- { /* Set gc_cons_combined_threshold. */
- double tot = total_bytes_of_live_objects ();
-
- tot *= XFLOAT_DATA (Vgc_cons_percentage);
- if (0 < tot)
+ if (!NILP (Vmemory_full))
+ consing_until_gc = memory_full_cons_threshold;
+ else
+ {
+ intptr_t threshold = min (max (GC_DEFAULT_THRESHOLD,
+ gc_cons_threshold >> 3),
+ OBJECT_CT_MAX);
+ if (FLOATP (Vgc_cons_percentage))
{
- if (tot < UINTPTR_MAX)
- gc_relative_threshold = tot;
- else
- gc_relative_threshold = UINTPTR_MAX;
+ double tot = (XFLOAT_DATA (Vgc_cons_percentage)
+ * total_bytes_of_live_objects ());
+ if (threshold < tot)
+ {
+ if (tot < OBJECT_CT_MAX)
+ threshold = tot;
+ else
+ threshold = OBJECT_CT_MAX;
+ }
}
+ consing_until_gc = threshold;
}
if (garbage_collection_messages && NILP (Vmemory_full))
diff --git a/src/lisp.h b/src/lisp.h
index 8f60963..50a61ca 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);
extern void garbage_collect (void);
extern const char *pending_malloc_warning;
extern Lisp_Object zero_vector;
-typedef uintptr_t byte_ct; /* System byte counts reported by GC. */
-extern byte_ct consing_since_gc;
-extern byte_ct gc_relative_threshold;
-extern byte_ct const memory_full_cons_threshold;
+typedef intptr_t object_ct; /* Signed type of object counts reported by GC. */
+#define OBJECT_CT_MAX INTPTR_MAX
+extern object_ct consing_until_gc;
#ifdef HAVE_PDUMPER
extern int number_finalizers_run;
#endif
@@ -4993,10 +4992,7 @@ struct for_each_tail_internal
INLINE void
maybe_gc (void)
{
- if ((consing_since_gc > gc_cons_threshold
- && consing_since_gc > gc_relative_threshold)
- || (!NILP (Vmemory_full)
- && consing_since_gc > memory_full_cons_threshold))
+ if (consing_until_gc < 0)
garbage_collect ();
}
- [Emacs-diffs] master updated (6490269 -> 515afc9), Paul Eggert, 2019/07/20
- [Emacs-diffs] master df5024d 2/6: Rename ‘pure’ to ‘purecopy’, Paul Eggert, 2019/07/20
- [Emacs-diffs] master 26de2d4 3/6: Simplify maybe_gc implementation,
Paul Eggert <=
- [Emacs-diffs] master b0908a0 1/6: Fix hash table overallocation etc., Paul Eggert, 2019/07/20
- [Emacs-diffs] master 5018b66 4/6: Inhibit GC after inhibit_garbage_collection, Paul Eggert, 2019/07/20
- [Emacs-diffs] master 515afc9 6/6: Fix crash if user test munges hash table, Paul Eggert, 2019/07/20
- [Emacs-diffs] master b6f194a 5/6: Simplify hashfn/cmpfn calling convention, Paul Eggert, 2019/07/20