emacs-diffs
[Top][All Lists]
Advanced

[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 ();
 }
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]