diff options
| author | Paul Eggert | 2019-01-01 15:06:50 -0800 |
|---|---|---|
| committer | Paul Eggert | 2019-01-01 15:07:16 -0800 |
| commit | 8b5f05e93871a6a6f853b3f0807eb0a3660f5f5e (patch) | |
| tree | e9ee28ae75a293f7abb469f14ad2f9458b8f2348 /src/alloc.c | |
| parent | ba1b340988ab79a1173f402f8f66bff06e0dd7c5 (diff) | |
| download | emacs-8b5f05e93871a6a6f853b3f0807eb0a3660f5f5e.tar.gz emacs-8b5f05e93871a6a6f853b3f0807eb0a3660f5f5e.zip | |
Bignums from garbage-collect, memory-use-counts
Do not limit the results of garbage-collect and memory-use-counts
to fixnums, as they might be bignums now on 32-bit hosts.
* src/lisp.h (byte_ct): New type.
* src/alloc.c (object_ct): New type.
(consing_since_gc, gc_relative_threshold)
(memory_full_cons_threshold, total_string_bytes):
Now byte_ct, not EMACS_INT.
(total_conses, total_symbols, total_buffers, total_free_conses)
(total_free_symbols, total_free_floats, total_floats)
(total_free_intervals, total_intervals, total_strings)
(total_free_strings, total_vectors, total_vector_slots)
(total_free_vector_slots): Now object_ct, not EMACS_INT.
(bounded_number): Remove. All uses removed.
(object_bytes): New function.
(total_bytes_of_live_objects, garbage_collect_1): Use byte_ct,
not size_t, to count total GC bytes where multiple objects are
involved.
(garbage_collect_1, Fmemory_use_counts):
Do not limit returned counts to fixnums.
(sweep_conses, sweep_floats, sweep_intervals, sweep_symbols):
Use object_ct, not EMACS_INT, to count GC objects.
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 143 |
1 files changed, 71 insertions, 72 deletions
diff --git a/src/alloc.c b/src/alloc.c index 70e417e9f88..407ac725414 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -231,26 +231,31 @@ struct emacs_globals globals; | |||
| 231 | 231 | ||
| 232 | /* Number of bytes of consing done since the last gc. */ | 232 | /* Number of bytes of consing done since the last gc. */ |
| 233 | 233 | ||
| 234 | EMACS_INT consing_since_gc; | 234 | byte_ct consing_since_gc; |
| 235 | 235 | ||
| 236 | /* Similar minimum, computed from Vgc_cons_percentage. */ | 236 | /* Similar minimum, computed from Vgc_cons_percentage. */ |
| 237 | 237 | ||
| 238 | EMACS_INT gc_relative_threshold; | 238 | byte_ct gc_relative_threshold; |
| 239 | 239 | ||
| 240 | /* Minimum number of bytes of consing since GC before next GC, | 240 | /* Minimum number of bytes of consing since GC before next GC, |
| 241 | when memory is full. */ | 241 | when memory is full. */ |
| 242 | 242 | ||
| 243 | EMACS_INT memory_full_cons_threshold; | 243 | byte_ct memory_full_cons_threshold; |
| 244 | 244 | ||
| 245 | /* True during GC. */ | 245 | /* True during GC. */ |
| 246 | 246 | ||
| 247 | bool gc_in_progress; | 247 | bool gc_in_progress; |
| 248 | 248 | ||
| 249 | /* Type of object counts reported by GC. Unlike byte_ct, this can be | ||
| 250 | signed, e.g., it is less than 2**31 on a typical 32-bit machine. */ | ||
| 251 | |||
| 252 | typedef intptr_t object_ct; | ||
| 253 | |||
| 249 | /* Number of live and free conses etc. */ | 254 | /* Number of live and free conses etc. */ |
| 250 | 255 | ||
| 251 | static EMACS_INT total_conses, total_symbols, total_buffers; | 256 | static object_ct total_conses, total_symbols, total_buffers; |
| 252 | static EMACS_INT total_free_conses, total_free_symbols; | 257 | static object_ct total_free_conses, total_free_symbols; |
| 253 | static EMACS_INT total_free_floats, total_floats; | 258 | static object_ct total_free_floats, total_floats; |
| 254 | 259 | ||
| 255 | /* Points to memory space allocated as "spare", to be freed if we run | 260 | /* Points to memory space allocated as "spare", to be freed if we run |
| 256 | out of memory. We keep one large block, four cons-blocks, and | 261 | out of memory. We keep one large block, four cons-blocks, and |
| @@ -1515,7 +1520,7 @@ static int interval_block_index = INTERVAL_BLOCK_SIZE; | |||
| 1515 | 1520 | ||
| 1516 | /* Number of free and live intervals. */ | 1521 | /* Number of free and live intervals. */ |
| 1517 | 1522 | ||
| 1518 | static EMACS_INT total_free_intervals, total_intervals; | 1523 | static object_ct total_free_intervals, total_intervals; |
| 1519 | 1524 | ||
| 1520 | /* List of free intervals. */ | 1525 | /* List of free intervals. */ |
| 1521 | 1526 | ||
| @@ -1731,11 +1736,11 @@ static struct Lisp_String *string_free_list; | |||
| 1731 | 1736 | ||
| 1732 | /* Number of live and free Lisp_Strings. */ | 1737 | /* Number of live and free Lisp_Strings. */ |
| 1733 | 1738 | ||
| 1734 | static EMACS_INT total_strings, total_free_strings; | 1739 | static object_ct total_strings, total_free_strings; |
| 1735 | 1740 | ||
| 1736 | /* Number of bytes used by live strings. */ | 1741 | /* Number of bytes used by live strings. */ |
| 1737 | 1742 | ||
| 1738 | static EMACS_INT total_string_bytes; | 1743 | static byte_ct total_string_bytes; |
| 1739 | 1744 | ||
| 1740 | /* Given a pointer to a Lisp_String S which is on the free-list | 1745 | /* Given a pointer to a Lisp_String S which is on the free-list |
| 1741 | string_free_list, return a pointer to its successor in the | 1746 | string_free_list, return a pointer to its successor in the |
| @@ -3039,11 +3044,11 @@ Lisp_Object zero_vector; | |||
| 3039 | 3044 | ||
| 3040 | /* Number of live vectors. */ | 3045 | /* Number of live vectors. */ |
| 3041 | 3046 | ||
| 3042 | static EMACS_INT total_vectors; | 3047 | static object_ct total_vectors; |
| 3043 | 3048 | ||
| 3044 | /* Total size of live and free vectors, in Lisp_Object units. */ | 3049 | /* Total size of live and free vectors, in Lisp_Object units. */ |
| 3045 | 3050 | ||
| 3046 | static EMACS_INT total_vector_slots, total_free_vector_slots; | 3051 | static object_ct total_vector_slots, total_free_vector_slots; |
| 3047 | 3052 | ||
| 3048 | /* Common shortcut to setup vector on a free list. */ | 3053 | /* Common shortcut to setup vector on a free list. */ |
| 3049 | 3054 | ||
| @@ -5556,28 +5561,29 @@ inhibit_garbage_collection (void) | |||
| 5556 | return count; | 5561 | return count; |
| 5557 | } | 5562 | } |
| 5558 | 5563 | ||
| 5559 | /* Used to avoid possible overflows when | 5564 | /* Return the number of bytes in N objects each of size S, guarding |
| 5560 | converting from C to Lisp integers. */ | 5565 | against overflow if size_t is narrower than byte_ct. */ |
| 5561 | 5566 | ||
| 5562 | static Lisp_Object | 5567 | static byte_ct |
| 5563 | bounded_number (EMACS_INT number) | 5568 | object_bytes (object_ct n, size_t s) |
| 5564 | { | 5569 | { |
| 5565 | return make_fixnum (min (MOST_POSITIVE_FIXNUM, number)); | 5570 | byte_ct b = s; |
| 5571 | return n * b; | ||
| 5566 | } | 5572 | } |
| 5567 | 5573 | ||
| 5568 | /* Calculate total bytes of live objects. */ | 5574 | /* Calculate total bytes of live objects. */ |
| 5569 | 5575 | ||
| 5570 | static size_t | 5576 | static byte_ct |
| 5571 | total_bytes_of_live_objects (void) | 5577 | total_bytes_of_live_objects (void) |
| 5572 | { | 5578 | { |
| 5573 | size_t tot = 0; | 5579 | byte_ct tot = 0; |
| 5574 | tot += total_conses * sizeof (struct Lisp_Cons); | 5580 | tot += object_bytes (total_conses, sizeof (struct Lisp_Cons)); |
| 5575 | tot += total_symbols * sizeof (struct Lisp_Symbol); | 5581 | tot += object_bytes (total_symbols, sizeof (struct Lisp_Symbol)); |
| 5576 | tot += total_string_bytes; | 5582 | tot += total_string_bytes; |
| 5577 | tot += total_vector_slots * word_size; | 5583 | tot += object_bytes (total_vector_slots, word_size); |
| 5578 | tot += total_floats * sizeof (struct Lisp_Float); | 5584 | tot += object_bytes (total_floats, sizeof (struct Lisp_Float)); |
| 5579 | tot += total_intervals * sizeof (struct interval); | 5585 | tot += object_bytes (total_intervals, sizeof (struct interval)); |
| 5580 | tot += total_strings * sizeof (struct Lisp_String); | 5586 | tot += object_bytes (total_strings, sizeof (struct Lisp_String)); |
| 5581 | return tot; | 5587 | return tot; |
| 5582 | } | 5588 | } |
| 5583 | 5589 | ||
| @@ -5743,7 +5749,7 @@ garbage_collect_1 (void *end) | |||
| 5743 | ptrdiff_t count = SPECPDL_INDEX (); | 5749 | ptrdiff_t count = SPECPDL_INDEX (); |
| 5744 | struct timespec start; | 5750 | struct timespec start; |
| 5745 | Lisp_Object retval = Qnil; | 5751 | Lisp_Object retval = Qnil; |
| 5746 | size_t tot_before = 0; | 5752 | byte_ct tot_before = 0; |
| 5747 | 5753 | ||
| 5748 | /* Can't GC if pure storage overflowed because we can't determine | 5754 | /* Can't GC if pure storage overflowed because we can't determine |
| 5749 | if something is a pure object or not. */ | 5755 | if something is a pure object or not. */ |
| @@ -5898,10 +5904,10 @@ garbage_collect_1 (void *end) | |||
| 5898 | tot *= XFLOAT_DATA (Vgc_cons_percentage); | 5904 | tot *= XFLOAT_DATA (Vgc_cons_percentage); |
| 5899 | if (0 < tot) | 5905 | if (0 < tot) |
| 5900 | { | 5906 | { |
| 5901 | if (tot < TYPE_MAXIMUM (EMACS_INT)) | 5907 | if (tot < UINTPTR_MAX) |
| 5902 | gc_relative_threshold = tot; | 5908 | gc_relative_threshold = tot; |
| 5903 | else | 5909 | else |
| 5904 | gc_relative_threshold = TYPE_MAXIMUM (EMACS_INT); | 5910 | gc_relative_threshold = UINTPTR_MAX; |
| 5905 | } | 5911 | } |
| 5906 | } | 5912 | } |
| 5907 | 5913 | ||
| @@ -5917,35 +5923,35 @@ garbage_collect_1 (void *end) | |||
| 5917 | 5923 | ||
| 5918 | Lisp_Object total[] = { | 5924 | Lisp_Object total[] = { |
| 5919 | list4 (Qconses, make_fixnum (sizeof (struct Lisp_Cons)), | 5925 | list4 (Qconses, make_fixnum (sizeof (struct Lisp_Cons)), |
| 5920 | bounded_number (total_conses), | 5926 | make_int (total_conses), |
| 5921 | bounded_number (total_free_conses)), | 5927 | make_int (total_free_conses)), |
| 5922 | list4 (Qsymbols, make_fixnum (sizeof (struct Lisp_Symbol)), | 5928 | list4 (Qsymbols, make_fixnum (sizeof (struct Lisp_Symbol)), |
| 5923 | bounded_number (total_symbols), | 5929 | make_int (total_symbols), |
| 5924 | bounded_number (total_free_symbols)), | 5930 | make_int (total_free_symbols)), |
| 5925 | list4 (Qstrings, make_fixnum (sizeof (struct Lisp_String)), | 5931 | list4 (Qstrings, make_fixnum (sizeof (struct Lisp_String)), |
| 5926 | bounded_number (total_strings), | 5932 | make_int (total_strings), |
| 5927 | bounded_number (total_free_strings)), | 5933 | make_int (total_free_strings)), |
| 5928 | list3 (Qstring_bytes, make_fixnum (1), | 5934 | list3 (Qstring_bytes, make_fixnum (1), |
| 5929 | bounded_number (total_string_bytes)), | 5935 | make_int (total_string_bytes)), |
| 5930 | list3 (Qvectors, | 5936 | list3 (Qvectors, |
| 5931 | make_fixnum (header_size + sizeof (Lisp_Object)), | 5937 | make_fixnum (header_size + sizeof (Lisp_Object)), |
| 5932 | bounded_number (total_vectors)), | 5938 | make_int (total_vectors)), |
| 5933 | list4 (Qvector_slots, make_fixnum (word_size), | 5939 | list4 (Qvector_slots, make_fixnum (word_size), |
| 5934 | bounded_number (total_vector_slots), | 5940 | make_int (total_vector_slots), |
| 5935 | bounded_number (total_free_vector_slots)), | 5941 | make_int (total_free_vector_slots)), |
| 5936 | list4 (Qfloats, make_fixnum (sizeof (struct Lisp_Float)), | 5942 | list4 (Qfloats, make_fixnum (sizeof (struct Lisp_Float)), |
| 5937 | bounded_number (total_floats), | 5943 | make_int (total_floats), |
| 5938 | bounded_number (total_free_floats)), | 5944 | make_int (total_free_floats)), |
| 5939 | list4 (Qintervals, make_fixnum (sizeof (struct interval)), | 5945 | list4 (Qintervals, make_fixnum (sizeof (struct interval)), |
| 5940 | bounded_number (total_intervals), | 5946 | make_int (total_intervals), |
| 5941 | bounded_number (total_free_intervals)), | 5947 | make_int (total_free_intervals)), |
| 5942 | list3 (Qbuffers, make_fixnum (sizeof (struct buffer)), | 5948 | list3 (Qbuffers, make_fixnum (sizeof (struct buffer)), |
| 5943 | bounded_number (total_buffers)), | 5949 | make_int (total_buffers)), |
| 5944 | 5950 | ||
| 5945 | #ifdef DOUG_LEA_MALLOC | 5951 | #ifdef DOUG_LEA_MALLOC |
| 5946 | list4 (Qheap, make_fixnum (1024), | 5952 | list4 (Qheap, make_fixnum (1024), |
| 5947 | bounded_number ((mallinfo ().uordblks + 1023) >> 10), | 5953 | make_int ((mallinfo ().uordblks + 1023) >> 10), |
| 5948 | bounded_number ((mallinfo ().fordblks + 1023) >> 10)), | 5954 | make_int ((mallinfo ().fordblks + 1023) >> 10)), |
| 5949 | #endif | 5955 | #endif |
| 5950 | }; | 5956 | }; |
| 5951 | retval = CALLMANY (Flist, total); | 5957 | retval = CALLMANY (Flist, total); |
| @@ -5973,11 +5979,9 @@ garbage_collect_1 (void *end) | |||
| 5973 | /* Collect profiling data. */ | 5979 | /* Collect profiling data. */ |
| 5974 | if (profiler_memory_running) | 5980 | if (profiler_memory_running) |
| 5975 | { | 5981 | { |
| 5976 | size_t swept = 0; | 5982 | byte_ct tot_after = total_bytes_of_live_objects (); |
| 5977 | size_t tot_after = total_bytes_of_live_objects (); | 5983 | byte_ct swept = tot_before <= tot_after ? 0 : tot_before - tot_after; |
| 5978 | if (tot_before > tot_after) | 5984 | malloc_probe (min (swept, SIZE_MAX)); |
| 5979 | swept = tot_before - tot_after; | ||
| 5980 | malloc_probe (swept); | ||
| 5981 | } | 5985 | } |
| 5982 | 5986 | ||
| 5983 | return retval; | 5987 | return retval; |
| @@ -6584,14 +6588,13 @@ NO_INLINE /* For better stack traces */ | |||
| 6584 | static void | 6588 | static void |
| 6585 | sweep_conses (void) | 6589 | sweep_conses (void) |
| 6586 | { | 6590 | { |
| 6587 | struct cons_block *cblk; | ||
| 6588 | struct cons_block **cprev = &cons_block; | 6591 | struct cons_block **cprev = &cons_block; |
| 6589 | int lim = cons_block_index; | 6592 | int lim = cons_block_index; |
| 6590 | EMACS_INT num_free = 0, num_used = 0; | 6593 | object_ct num_free = 0, num_used = 0; |
| 6591 | 6594 | ||
| 6592 | cons_free_list = 0; | 6595 | cons_free_list = 0; |
| 6593 | 6596 | ||
| 6594 | for (cblk = cons_block; cblk; cblk = *cprev) | 6597 | for (struct cons_block *cblk; (cblk = *cprev); ) |
| 6595 | { | 6598 | { |
| 6596 | int i = 0; | 6599 | int i = 0; |
| 6597 | int this_free = 0; | 6600 | int this_free = 0; |
| @@ -6663,18 +6666,16 @@ NO_INLINE /* For better stack traces */ | |||
| 6663 | static void | 6666 | static void |
| 6664 | sweep_floats (void) | 6667 | sweep_floats (void) |
| 6665 | { | 6668 | { |
| 6666 | register struct float_block *fblk; | ||
| 6667 | struct float_block **fprev = &float_block; | 6669 | struct float_block **fprev = &float_block; |
| 6668 | register int lim = float_block_index; | 6670 | int lim = float_block_index; |
| 6669 | EMACS_INT num_free = 0, num_used = 0; | 6671 | object_ct num_free = 0, num_used = 0; |
| 6670 | 6672 | ||
| 6671 | float_free_list = 0; | 6673 | float_free_list = 0; |
| 6672 | 6674 | ||
| 6673 | for (fblk = float_block; fblk; fblk = *fprev) | 6675 | for (struct float_block *fblk; (fblk = *fprev); ) |
| 6674 | { | 6676 | { |
| 6675 | register int i; | ||
| 6676 | int this_free = 0; | 6677 | int this_free = 0; |
| 6677 | for (i = 0; i < lim; i++) | 6678 | for (int i = 0; i < lim; i++) |
| 6678 | { | 6679 | { |
| 6679 | struct Lisp_Float *afloat = ptr_bounds_copy (&fblk->floats[i], fblk); | 6680 | struct Lisp_Float *afloat = ptr_bounds_copy (&fblk->floats[i], fblk); |
| 6680 | if (!FLOAT_MARKED_P (afloat)) | 6681 | if (!FLOAT_MARKED_P (afloat)) |
| @@ -6714,19 +6715,17 @@ NO_INLINE /* For better stack traces */ | |||
| 6714 | static void | 6715 | static void |
| 6715 | sweep_intervals (void) | 6716 | sweep_intervals (void) |
| 6716 | { | 6717 | { |
| 6717 | register struct interval_block *iblk; | ||
| 6718 | struct interval_block **iprev = &interval_block; | 6718 | struct interval_block **iprev = &interval_block; |
| 6719 | register int lim = interval_block_index; | 6719 | int lim = interval_block_index; |
| 6720 | EMACS_INT num_free = 0, num_used = 0; | 6720 | object_ct num_free = 0, num_used = 0; |
| 6721 | 6721 | ||
| 6722 | interval_free_list = 0; | 6722 | interval_free_list = 0; |
| 6723 | 6723 | ||
| 6724 | for (iblk = interval_block; iblk; iblk = *iprev) | 6724 | for (struct interval_block *iblk; (iblk = *iprev); ) |
| 6725 | { | 6725 | { |
| 6726 | register int i; | ||
| 6727 | int this_free = 0; | 6726 | int this_free = 0; |
| 6728 | 6727 | ||
| 6729 | for (i = 0; i < lim; i++) | 6728 | for (int i = 0; i < lim; i++) |
| 6730 | { | 6729 | { |
| 6731 | if (!iblk->intervals[i].gcmarkbit) | 6730 | if (!iblk->intervals[i].gcmarkbit) |
| 6732 | { | 6731 | { |
| @@ -6768,7 +6767,7 @@ sweep_symbols (void) | |||
| 6768 | struct symbol_block *sblk; | 6767 | struct symbol_block *sblk; |
| 6769 | struct symbol_block **sprev = &symbol_block; | 6768 | struct symbol_block **sprev = &symbol_block; |
| 6770 | int lim = symbol_block_index; | 6769 | int lim = symbol_block_index; |
| 6771 | EMACS_INT num_free = 0, num_used = ARRAYELTS (lispsym); | 6770 | object_ct num_free = 0, num_used = ARRAYELTS (lispsym); |
| 6772 | 6771 | ||
| 6773 | symbol_free_list = NULL; | 6772 | symbol_free_list = NULL; |
| 6774 | 6773 | ||
| @@ -6955,13 +6954,13 @@ Frames, windows, buffers, and subprocesses count as vectors | |||
| 6955 | (void) | 6954 | (void) |
| 6956 | { | 6955 | { |
| 6957 | return listn (CONSTYPE_HEAP, 7, | 6956 | return listn (CONSTYPE_HEAP, 7, |
| 6958 | bounded_number (cons_cells_consed), | 6957 | make_int (cons_cells_consed), |
| 6959 | bounded_number (floats_consed), | 6958 | make_int (floats_consed), |
| 6960 | bounded_number (vector_cells_consed), | 6959 | make_int (vector_cells_consed), |
| 6961 | bounded_number (symbols_consed), | 6960 | make_int (symbols_consed), |
| 6962 | bounded_number (string_chars_consed), | 6961 | make_int (string_chars_consed), |
| 6963 | bounded_number (intervals_consed), | 6962 | make_int (intervals_consed), |
| 6964 | bounded_number (strings_consed)); | 6963 | make_int (strings_consed)); |
| 6965 | } | 6964 | } |
| 6966 | 6965 | ||
| 6967 | static bool | 6966 | static bool |