diff options
| author | Paul Eggert | 2019-09-07 18:08:12 -0700 |
|---|---|---|
| committer | Paul Eggert | 2019-09-07 18:08:44 -0700 |
| commit | b6b7c7fc985eaadef2f059fac4442d23a3b706de (patch) | |
| tree | 6656c932098f554e9791abbea18b6c457ac665f8 /src/alloc.c | |
| parent | 8e93e6da7cda4de82e3532cf74fc585451641398 (diff) | |
| download | emacs-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.c | 45 |
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 | ||
| 298 | static intptr_t garbage_collection_inhibited; | 298 | static 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. */ | ||
| 302 | static 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. */ | ||
| 5812 | static Lisp_Object | 5817 | static Lisp_Object |
| 5813 | bump_consing_until_gc (intmax_t diff) | 5818 | bump_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 | |||
| 5825 | watch_gc_cons_threshold (Lisp_Object symbol, Lisp_Object newval, | 5842 | watch_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 | |||
| 5839 | watch_gc_cons_percentage (Lisp_Object symbol, Lisp_Object newval, | 5853 | watch_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 | { |