aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
authorPaul Eggert2019-01-01 15:06:50 -0800
committerPaul Eggert2019-01-01 15:07:16 -0800
commit8b5f05e93871a6a6f853b3f0807eb0a3660f5f5e (patch)
treee9ee28ae75a293f7abb469f14ad2f9458b8f2348 /src/alloc.c
parentba1b340988ab79a1173f402f8f66bff06e0dd7c5 (diff)
downloademacs-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.c143
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
234EMACS_INT consing_since_gc; 234byte_ct consing_since_gc;
235 235
236/* Similar minimum, computed from Vgc_cons_percentage. */ 236/* Similar minimum, computed from Vgc_cons_percentage. */
237 237
238EMACS_INT gc_relative_threshold; 238byte_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
243EMACS_INT memory_full_cons_threshold; 243byte_ct memory_full_cons_threshold;
244 244
245/* True during GC. */ 245/* True during GC. */
246 246
247bool gc_in_progress; 247bool 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
252typedef intptr_t object_ct;
253
249/* Number of live and free conses etc. */ 254/* Number of live and free conses etc. */
250 255
251static EMACS_INT total_conses, total_symbols, total_buffers; 256static object_ct total_conses, total_symbols, total_buffers;
252static EMACS_INT total_free_conses, total_free_symbols; 257static object_ct total_free_conses, total_free_symbols;
253static EMACS_INT total_free_floats, total_floats; 258static 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
1518static EMACS_INT total_free_intervals, total_intervals; 1523static 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
1734static EMACS_INT total_strings, total_free_strings; 1739static 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
1738static EMACS_INT total_string_bytes; 1743static 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
3042static EMACS_INT total_vectors; 3047static 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
3046static EMACS_INT total_vector_slots, total_free_vector_slots; 3051static 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
5562static Lisp_Object 5567static byte_ct
5563bounded_number (EMACS_INT number) 5568object_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
5570static size_t 5576static byte_ct
5571total_bytes_of_live_objects (void) 5577total_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 */
6584static void 6588static void
6585sweep_conses (void) 6589sweep_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 */
6663static void 6666static void
6664sweep_floats (void) 6667sweep_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 */
6714static void 6715static void
6715sweep_intervals (void) 6716sweep_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
6967static bool 6966static bool