aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
authorPaul Eggert2019-09-07 18:08:12 -0700
committerPaul Eggert2019-09-07 18:08:44 -0700
commitb6b7c7fc985eaadef2f059fac4442d23a3b706de (patch)
tree6656c932098f554e9791abbea18b6c457ac665f8 /src/alloc.c
parent8e93e6da7cda4de82e3532cf74fc585451641398 (diff)
downloademacs-b6b7c7fc985eaadef2f059fac4442d23a3b706de.tar.gz
emacs-b6b7c7fc985eaadef2f059fac4442d23a3b706de.zip
Fix bug when gc-cons-percentage is bumped to 0.8
Problem reported by Michael Heerdegen (Bug#37321). * src/alloc.c (gc_threshold): New static var. (bump_consing_until_gc): Change args from DIFF to THRESHOLD and PERCENTAGE. All uses changed. When accounting for a changed gc-cons-percentage, do not assume that total_bytes_of_live_objects returns the same value now that it did the last time we were called.
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c45
1 files changed, 28 insertions, 17 deletions
diff --git a/src/alloc.c b/src/alloc.c
index 5fc515f33be..be98cfd5f53 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -297,6 +297,10 @@ static ptrdiff_t pure_bytes_used_non_lisp;
297 297
298static intptr_t garbage_collection_inhibited; 298static intptr_t garbage_collection_inhibited;
299 299
300/* The GC threshold in bytes, the last time it was calculated
301 from gc-cons-threshold and gc-cons-percentage. */
302static intmax_t gc_threshold;
303
300/* If nonzero, this is a warning delivered by malloc and not yet 304/* If nonzero, this is a warning delivered by malloc and not yet
301 displayed. */ 305 displayed. */
302 306
@@ -5808,15 +5812,28 @@ consing_threshold (intmax_t threshold, Lisp_Object percentage)
5808 } 5812 }
5809} 5813}
5810 5814
5811/* Increment consing_until_gc by DIFF, avoiding overflow. */ 5815/* Adjust consing_until_gc, assuming gc-cons-threshold is THRESHOLD and
5816 gc-cons-percentage is PERCENTAGE. */
5812static Lisp_Object 5817static Lisp_Object
5813bump_consing_until_gc (intmax_t diff) 5818bump_consing_until_gc (intmax_t threshold, Lisp_Object percentage)
5814{ 5819{
5815 /* If consing_until_gc is negative leave it alone, since this prevents 5820 /* If consing_until_gc is negative leave it alone, since this prevents
5816 negative integer overflow and a GC would have been done soon anyway. */ 5821 negative integer overflow and a GC would have been done soon anyway. */
5817 if (0 <= consing_until_gc 5822 if (0 <= consing_until_gc)
5818 && INT_ADD_WRAPV (consing_until_gc, diff, &consing_until_gc)) 5823 {
5819 consing_until_gc = INTMAX_MAX; 5824 threshold = consing_threshold (threshold, percentage);
5825 intmax_t sum;
5826 if (INT_ADD_WRAPV (consing_until_gc, threshold - gc_threshold, &sum))
5827 {
5828 /* Scale the threshold down so that consing_until_gc does
5829 not overflow. */
5830 sum = INTMAX_MAX;
5831 threshold = INTMAX_MAX - consing_until_gc + gc_threshold;
5832 }
5833 consing_until_gc = sum;
5834 gc_threshold = threshold;
5835 }
5836
5820 return Qnil; 5837 return Qnil;
5821} 5838}
5822 5839
@@ -5825,13 +5842,10 @@ static Lisp_Object
5825watch_gc_cons_threshold (Lisp_Object symbol, Lisp_Object newval, 5842watch_gc_cons_threshold (Lisp_Object symbol, Lisp_Object newval,
5826 Lisp_Object operation, Lisp_Object where) 5843 Lisp_Object operation, Lisp_Object where)
5827{ 5844{
5828 Lisp_Object percentage = Vgc_cons_percentage;
5829 intmax_t threshold; 5845 intmax_t threshold;
5830 intmax_t diff = (INTEGERP (newval) && integer_to_intmax (newval, &threshold) 5846 if (! (INTEGERP (newval) && integer_to_intmax (newval, &threshold)))
5831 ? (consing_threshold (threshold, percentage) 5847 return Qnil;
5832 - consing_threshold (gc_cons_threshold, percentage)) 5848 return bump_consing_until_gc (threshold, Vgc_cons_percentage);
5833 : 0);
5834 return bump_consing_until_gc (diff);
5835} 5849}
5836 5850
5837/* Watch changes to gc-cons-percentage. */ 5851/* Watch changes to gc-cons-percentage. */
@@ -5839,10 +5853,7 @@ static Lisp_Object
5839watch_gc_cons_percentage (Lisp_Object symbol, Lisp_Object newval, 5853watch_gc_cons_percentage (Lisp_Object symbol, Lisp_Object newval,
5840 Lisp_Object operation, Lisp_Object where) 5854 Lisp_Object operation, Lisp_Object where)
5841{ 5855{
5842 intmax_t threshold = gc_cons_threshold; 5856 return bump_consing_until_gc (gc_cons_threshold, newval);
5843 intmax_t diff = (consing_threshold (threshold, newval)
5844 - consing_threshold (threshold, Vgc_cons_percentage));
5845 return bump_consing_until_gc (diff);
5846} 5857}
5847 5858
5848/* Subroutine of Fgarbage_collect that does most of the work. */ 5859/* Subroutine of Fgarbage_collect that does most of the work. */
@@ -5987,8 +5998,8 @@ garbage_collect_1 (struct gcstat *gcst)
5987 5998
5988 unblock_input (); 5999 unblock_input ();
5989 6000
5990 consing_until_gc = consing_threshold (gc_cons_threshold, 6001 consing_until_gc = gc_threshold
5991 Vgc_cons_percentage); 6002 = consing_threshold (gc_cons_threshold, Vgc_cons_percentage);
5992 6003
5993 if (garbage_collection_messages && NILP (Vmemory_full)) 6004 if (garbage_collection_messages && NILP (Vmemory_full))
5994 { 6005 {