Subject: bug#37006: Emacs 27 master consumes more memory than 26 and freezes regularly

From: Paul Eggert <[email-masked]>
Date: Thu, 5 Sep 2019 13:30:18 -0700

I reproduced the problem on Fedora 30 x86-64 and installed the attached 
fix. Please give it a try.
>From 2c246fde5ebe76bf48322c09fd685e48c0737f2a Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email-masked]>
Date: Thu, 5 Sep 2019 13:25:43 -0700
Subject: [PATCH] Fix bugs when recalculating consing_until_gc
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Problem reported by Joseph Mingrone (Bug#37006#72).
* src/alloc.c (watch_gc_cons_threshold)
(watch_gc_cons_percentage):
Don’t try to store an intmax_t into an int.
Redo to make the code clearer.
(watch_gc_cons_percentage):
Use gc_cons_threshold, not consing_until_gc.
---
 src/alloc.c | 24 +++++++++++++-----------
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/src/alloc.c b/src/alloc.c
index 089f61f833..5fc515f33b 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -5783,18 +5783,18 @@ mark_and_sweep_weak_table_contents (void)
 
 /* Return the number of bytes to cons between GCs, assuming
    gc-cons-threshold is THRESHOLD and gc-cons-percentage is
-   GC_CONS_PERCENTAGE.  */
+   PERCENTAGE.  */
 static intmax_t
-consing_threshold (intmax_t threshold, Lisp_Object gc_cons_percentage)
+consing_threshold (intmax_t threshold, Lisp_Object percentage)
 {
   if (!NILP (Vmemory_full))
     return memory_full_cons_threshold;
   else
     {
       threshold = max (threshold, GC_DEFAULT_THRESHOLD / 10);
-      if (FLOATP (gc_cons_percentage))
+      if (FLOATP (percentage))
 	{
-	  double tot = (XFLOAT_DATA (gc_cons_percentage)
+	  double tot = (XFLOAT_DATA (percentage)
 			* total_bytes_of_live_objects ());
 	  if (threshold < tot)
 	    {
@@ -5825,11 +5825,12 @@ bump_consing_until_gc (intmax_t diff)
 watch_gc_cons_threshold (Lisp_Object symbol, Lisp_Object newval,
 			 Lisp_Object operation, Lisp_Object where)
 {
-  intmax_t new_threshold;
-  int diff = (INTEGERP (newval) && integer_to_intmax (newval, &new_threshold)
-	      ? (consing_threshold (new_threshold, Vgc_cons_percentage)
-		 - consing_threshold (gc_cons_threshold, Vgc_cons_percentage))
-	      : 0);
+  Lisp_Object percentage = Vgc_cons_percentage;
+  intmax_t threshold;
+  intmax_t diff = (INTEGERP (newval) && integer_to_intmax (newval, &threshold)
+		   ? (consing_threshold (threshold, percentage)
+		      - consing_threshold (gc_cons_threshold, percentage))
+		   : 0);
   return bump_consing_until_gc (diff);
 }
 
@@ -5838,8 +5839,9 @@ watch_gc_cons_threshold (Lisp_Object symbol, Lisp_Object newval,
 watch_gc_cons_percentage (Lisp_Object symbol, Lisp_Object newval,
 			  Lisp_Object operation, Lisp_Object where)
 {
-  int diff = (consing_threshold (consing_until_gc, newval)
-	      - consing_threshold (consing_until_gc, Vgc_cons_percentage));
+  intmax_t threshold = gc_cons_threshold;
+  intmax_t diff = (consing_threshold (threshold, newval)
+		   - consing_threshold (threshold, Vgc_cons_percentage));
   return bump_consing_until_gc (diff);
 }
 
-- 
2.21.0