diff options
| author | Paul Eggert | 2019-09-03 13:03:34 -0700 |
|---|---|---|
| committer | Paul Eggert | 2019-09-03 13:03:47 -0700 |
| commit | 97ffa339b6d67cebcbefbdfaa2880214adab639c (patch) | |
| tree | dcc425367088b475426c1b385f99de83c96ee70b /src | |
| parent | c34dbd80e72204cd0ac65254ff3145dbd916f5c5 (diff) | |
| download | emacs-97ffa339b6d67cebcbefbdfaa2880214adab639c.tar.gz emacs-97ffa339b6d67cebcbefbdfaa2880214adab639c.zip | |
Sync consing_until_gc with gc-cons-threshold
Add watchers for gc-cons-threshold and gc-cons-percentage
that update consing_until_gc accordingly.
Suggested by Eli Zaretskii (Bug#37006#52).
* src/alloc.c (consing_threshold, bump_consing_until_gc)
(watch_gc_cons_threshold, watch_gc_cons_percentage):
New functions.
(garbage_collect_1): Use consing_threshold.
(syms_of_alloc): Arrange to watch gc-cons-threshold and
gc-cons-percentage.
Diffstat (limited to 'src')
| -rw-r--r-- | src/alloc.c | 100 |
1 files changed, 81 insertions, 19 deletions
diff --git a/src/alloc.c b/src/alloc.c index 39964c4b293..5f8ef0a5dda 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -5781,6 +5781,68 @@ mark_and_sweep_weak_table_contents (void) | |||
| 5781 | } | 5781 | } |
| 5782 | } | 5782 | } |
| 5783 | 5783 | ||
| 5784 | /* Return the number of bytes to cons between GCs, assuming | ||
| 5785 | gc-cons-threshold is THRESHOLD and gc-cons-percentage is | ||
| 5786 | GC_CONS_PERCENTAGE. */ | ||
| 5787 | static intmax_t | ||
| 5788 | consing_threshold (intmax_t threshold, Lisp_Object gc_cons_percentage) | ||
| 5789 | { | ||
| 5790 | if (!NILP (Vmemory_full)) | ||
| 5791 | return memory_full_cons_threshold; | ||
| 5792 | else | ||
| 5793 | { | ||
| 5794 | threshold = max (threshold, GC_DEFAULT_THRESHOLD / 10); | ||
| 5795 | if (FLOATP (gc_cons_percentage)) | ||
| 5796 | { | ||
| 5797 | double tot = (XFLOAT_DATA (gc_cons_percentage) | ||
| 5798 | * total_bytes_of_live_objects ()); | ||
| 5799 | if (threshold < tot) | ||
| 5800 | { | ||
| 5801 | if (tot < INTMAX_MAX) | ||
| 5802 | threshold = tot; | ||
| 5803 | else | ||
| 5804 | threshold = INTMAX_MAX; | ||
| 5805 | } | ||
| 5806 | } | ||
| 5807 | return threshold; | ||
| 5808 | } | ||
| 5809 | } | ||
| 5810 | |||
| 5811 | /* Increment consing_until_gc by DIFF, avoiding overflow. */ | ||
| 5812 | static Lisp_Object | ||
| 5813 | bump_consing_until_gc (intmax_t diff) | ||
| 5814 | { | ||
| 5815 | /* 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. */ | ||
| 5817 | if (0 <= consing_until_gc | ||
| 5818 | && INT_ADD_WRAPV (consing_until_gc, diff, &consing_until_gc)) | ||
| 5819 | consing_until_gc = INTMAX_MAX; | ||
| 5820 | return Qnil; | ||
| 5821 | } | ||
| 5822 | |||
| 5823 | /* Watch changes to gc-cons-threshold. */ | ||
| 5824 | static Lisp_Object | ||
| 5825 | watch_gc_cons_threshold (Lisp_Object symbol, Lisp_Object newval, | ||
| 5826 | Lisp_Object operation, Lisp_Object where) | ||
| 5827 | { | ||
| 5828 | intmax_t new_threshold; | ||
| 5829 | int diff = (INTEGERP (newval) && integer_to_intmax (newval, &new_threshold) | ||
| 5830 | ? (consing_threshold (new_threshold, Vgc_cons_percentage) | ||
| 5831 | - consing_threshold (gc_cons_threshold, Vgc_cons_percentage)) | ||
| 5832 | : 0); | ||
| 5833 | return bump_consing_until_gc (diff); | ||
| 5834 | } | ||
| 5835 | |||
| 5836 | /* Watch changes to gc-cons-percentage. */ | ||
| 5837 | static Lisp_Object | ||
| 5838 | watch_gc_cons_percentage (Lisp_Object symbol, Lisp_Object newval, | ||
| 5839 | Lisp_Object operation, Lisp_Object where) | ||
| 5840 | { | ||
| 5841 | int diff = (consing_threshold (consing_until_gc, newval) | ||
| 5842 | - consing_threshold (consing_until_gc, Vgc_cons_percentage)); | ||
| 5843 | return bump_consing_until_gc (diff); | ||
| 5844 | } | ||
| 5845 | |||
| 5784 | /* Subroutine of Fgarbage_collect that does most of the work. */ | 5846 | /* Subroutine of Fgarbage_collect that does most of the work. */ |
| 5785 | static bool | 5847 | static bool |
| 5786 | garbage_collect_1 (struct gcstat *gcst) | 5848 | garbage_collect_1 (struct gcstat *gcst) |
| @@ -5923,25 +5985,8 @@ garbage_collect_1 (struct gcstat *gcst) | |||
| 5923 | 5985 | ||
| 5924 | unblock_input (); | 5986 | unblock_input (); |
| 5925 | 5987 | ||
| 5926 | if (!NILP (Vmemory_full)) | 5988 | consing_until_gc = consing_threshold (gc_cons_threshold, |
| 5927 | consing_until_gc = memory_full_cons_threshold; | 5989 | Vgc_cons_percentage); |
| 5928 | else | ||
| 5929 | { | ||
| 5930 | intmax_t threshold = max (gc_cons_threshold, GC_DEFAULT_THRESHOLD / 10); | ||
| 5931 | if (FLOATP (Vgc_cons_percentage)) | ||
| 5932 | { | ||
| 5933 | double tot = (XFLOAT_DATA (Vgc_cons_percentage) | ||
| 5934 | * total_bytes_of_live_objects ()); | ||
| 5935 | if (threshold < tot) | ||
| 5936 | { | ||
| 5937 | if (tot < INTMAX_MAX) | ||
| 5938 | threshold = tot; | ||
| 5939 | else | ||
| 5940 | threshold = INTMAX_MAX; | ||
| 5941 | } | ||
| 5942 | } | ||
| 5943 | consing_until_gc = threshold; | ||
| 5944 | } | ||
| 5945 | 5990 | ||
| 5946 | if (garbage_collection_messages && NILP (Vmemory_full)) | 5991 | if (garbage_collection_messages && NILP (Vmemory_full)) |
| 5947 | { | 5992 | { |
| @@ -7362,6 +7407,7 @@ do hash-consing of the objects allocated to pure space. */); | |||
| 7362 | DEFSYM (Qheap, "heap"); | 7407 | DEFSYM (Qheap, "heap"); |
| 7363 | DEFSYM (QAutomatic_GC, "Automatic GC"); | 7408 | DEFSYM (QAutomatic_GC, "Automatic GC"); |
| 7364 | 7409 | ||
| 7410 | DEFSYM (Qgc_cons_percentage, "gc-cons-percentage"); | ||
| 7365 | DEFSYM (Qgc_cons_threshold, "gc-cons-threshold"); | 7411 | DEFSYM (Qgc_cons_threshold, "gc-cons-threshold"); |
| 7366 | DEFSYM (Qchar_table_extra_slots, "char-table-extra-slots"); | 7412 | DEFSYM (Qchar_table_extra_slots, "char-table-extra-slots"); |
| 7367 | 7413 | ||
| @@ -7395,6 +7441,22 @@ N should be nonnegative. */); | |||
| 7395 | defsubr (&Smemory_info); | 7441 | defsubr (&Smemory_info); |
| 7396 | defsubr (&Smemory_use_counts); | 7442 | defsubr (&Smemory_use_counts); |
| 7397 | defsubr (&Ssuspicious_object); | 7443 | defsubr (&Ssuspicious_object); |
| 7444 | |||
| 7445 | Lisp_Object watcher; | ||
| 7446 | |||
| 7447 | static union Aligned_Lisp_Subr Swatch_gc_cons_threshold = | ||
| 7448 | {{{ PSEUDOVECTOR_FLAG | (PVEC_SUBR << PSEUDOVECTOR_AREA_BITS) }, | ||
| 7449 | { .a4 = watch_gc_cons_threshold }, | ||
| 7450 | 4, 4, "watch_gc_cons_threshold", 0, 0}}; | ||
| 7451 | XSETSUBR (watcher, &Swatch_gc_cons_threshold.s); | ||
| 7452 | Fadd_variable_watcher (Qgc_cons_threshold, watcher); | ||
| 7453 | |||
| 7454 | static union Aligned_Lisp_Subr Swatch_gc_cons_percentage = | ||
| 7455 | {{{ PSEUDOVECTOR_FLAG | (PVEC_SUBR << PSEUDOVECTOR_AREA_BITS) }, | ||
| 7456 | { .a4 = watch_gc_cons_percentage }, | ||
| 7457 | 4, 4, "watch_gc_cons_percentage", 0, 0}}; | ||
| 7458 | XSETSUBR (watcher, &Swatch_gc_cons_percentage.s); | ||
| 7459 | Fadd_variable_watcher (Qgc_cons_percentage, watcher); | ||
| 7398 | } | 7460 | } |
| 7399 | 7461 | ||
| 7400 | #ifdef HAVE_X_WINDOWS | 7462 | #ifdef HAVE_X_WINDOWS |