aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2019-09-13 16:09:48 -0700
committerPaul Eggert2019-09-13 16:10:54 -0700
commite4fb98b542c57fa4856fbeb14230ace34d910117 (patch)
tree699813b8e331f5d2fc9f79e15d6e0f97a27e9d19 /src
parent0dba340da54f129750096a5a8704805a94f5535c (diff)
downloademacs-e4fb98b542c57fa4856fbeb14230ace34d910117.tar.gz
emacs-e4fb98b542c57fa4856fbeb14230ace34d910117.zip
Simplify GC statistics-gathering
* src/alloc.c (make_interval, allocate_string, make_float) (free_cons, Fcons, setup_on_free_list) (allocate_vector_from_block, Fmake_symbol): Do not update gcstat, since it is for statistics from the most recent GC, not for a partially-updated hodgepodge. (sweep_vectors): Update gcstat, since setup_on_free_list no longer does. (garbage_collect_1): Rename to garbage_collect and adopt its API. Remove the old garbage_collect, which is no longer needed. All callers changed.
Diffstat (limited to 'src')
-rw-r--r--src/alloc.c66
1 files changed, 15 insertions, 51 deletions
diff --git a/src/alloc.c b/src/alloc.c
index 2d490f3bb75..ca8311cc00a 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -241,7 +241,7 @@ bool gc_in_progress;
241typedef uintptr_t byte_ct; 241typedef uintptr_t byte_ct;
242typedef intptr_t object_ct; 242typedef intptr_t object_ct;
243 243
244/* Number of live and free conses etc. */ 244/* Number of live and free conses etc. counted by the most-recent GC. */
245 245
246static struct gcstat 246static struct gcstat
247{ 247{
@@ -560,7 +560,7 @@ struct Lisp_Finalizer finalizers;
560 560
561/* Head of a circularly-linked list of finalizers that must be invoked 561/* Head of a circularly-linked list of finalizers that must be invoked
562 because we deemed them unreachable. This list must be global, and 562 because we deemed them unreachable. This list must be global, and
563 not a local inside garbage_collect_1, in case we GC again while 563 not a local inside garbage_collect, in case we GC again while
564 running finalizers. */ 564 running finalizers. */
565struct Lisp_Finalizer doomed_finalizers; 565struct Lisp_Finalizer doomed_finalizers;
566 566
@@ -1366,7 +1366,6 @@ make_interval (void)
1366 newi->next = interval_block; 1366 newi->next = interval_block;
1367 interval_block = newi; 1367 interval_block = newi;
1368 interval_block_index = 0; 1368 interval_block_index = 0;
1369 gcstat.total_free_intervals += INTERVAL_BLOCK_SIZE;
1370 } 1369 }
1371 val = &interval_block->intervals[interval_block_index++]; 1370 val = &interval_block->intervals[interval_block_index++];
1372 } 1371 }
@@ -1375,7 +1374,6 @@ make_interval (void)
1375 1374
1376 consing_until_gc -= sizeof (struct interval); 1375 consing_until_gc -= sizeof (struct interval);
1377 intervals_consed++; 1376 intervals_consed++;
1378 gcstat.total_free_intervals--;
1379 RESET_INTERVAL (val); 1377 RESET_INTERVAL (val);
1380 val->gcmarkbit = 0; 1378 val->gcmarkbit = 0;
1381 return val; 1379 return val;
@@ -1730,8 +1728,6 @@ allocate_string (void)
1730 NEXT_FREE_LISP_STRING (s) = string_free_list; 1728 NEXT_FREE_LISP_STRING (s) = string_free_list;
1731 string_free_list = ptr_bounds_clip (s, sizeof *s); 1729 string_free_list = ptr_bounds_clip (s, sizeof *s);
1732 } 1730 }
1733
1734 gcstat.total_free_strings += STRING_BLOCK_SIZE;
1735 } 1731 }
1736 1732
1737 check_string_free_list (); 1733 check_string_free_list ();
@@ -1742,8 +1738,6 @@ allocate_string (void)
1742 1738
1743 MALLOC_UNBLOCK_INPUT; 1739 MALLOC_UNBLOCK_INPUT;
1744 1740
1745 gcstat.total_free_strings--;
1746 gcstat.total_strings++;
1747 ++strings_consed; 1741 ++strings_consed;
1748 consing_until_gc -= sizeof *s; 1742 consing_until_gc -= sizeof *s;
1749 1743
@@ -2461,7 +2455,6 @@ make_float (double float_value)
2461 memset (new->gcmarkbits, 0, sizeof new->gcmarkbits); 2455 memset (new->gcmarkbits, 0, sizeof new->gcmarkbits);
2462 float_block = new; 2456 float_block = new;
2463 float_block_index = 0; 2457 float_block_index = 0;
2464 gcstat.total_free_floats += FLOAT_BLOCK_SIZE;
2465 } 2458 }
2466 XSETFLOAT (val, &float_block->floats[float_block_index]); 2459 XSETFLOAT (val, &float_block->floats[float_block_index]);
2467 float_block_index++; 2460 float_block_index++;
@@ -2473,7 +2466,6 @@ make_float (double float_value)
2473 eassert (!XFLOAT_MARKED_P (XFLOAT (val))); 2466 eassert (!XFLOAT_MARKED_P (XFLOAT (val)));
2474 consing_until_gc -= sizeof (struct Lisp_Float); 2467 consing_until_gc -= sizeof (struct Lisp_Float);
2475 floats_consed++; 2468 floats_consed++;
2476 gcstat.total_free_floats--;
2477 return val; 2469 return val;
2478} 2470}
2479 2471
@@ -2545,7 +2537,6 @@ free_cons (struct Lisp_Cons *ptr)
2545 cons_free_list = ptr; 2537 cons_free_list = ptr;
2546 if (INT_ADD_WRAPV (consing_until_gc, sizeof *ptr, &consing_until_gc)) 2538 if (INT_ADD_WRAPV (consing_until_gc, sizeof *ptr, &consing_until_gc))
2547 consing_until_gc = INTMAX_MAX; 2539 consing_until_gc = INTMAX_MAX;
2548 gcstat.total_free_conses++;
2549} 2540}
2550 2541
2551DEFUN ("cons", Fcons, Scons, 2, 2, 0, 2542DEFUN ("cons", Fcons, Scons, 2, 2, 0,
@@ -2565,26 +2556,12 @@ DEFUN ("cons", Fcons, Scons, 2, 2, 0,
2565 { 2556 {
2566 if (cons_block_index == CONS_BLOCK_SIZE) 2557 if (cons_block_index == CONS_BLOCK_SIZE)
2567 { 2558 {
2568 /* Maximum number of conses that should be active at any
2569 given time, so that list lengths fit into a ptrdiff_t and
2570 into a fixnum. */
2571 ptrdiff_t max_conses = min (PTRDIFF_MAX, MOST_POSITIVE_FIXNUM);
2572
2573 /* This check is typically optimized away, as a runtime
2574 check is needed only on weird platforms where a count of
2575 distinct conses might not fit. */
2576 if (max_conses < INTPTR_MAX / sizeof (struct Lisp_Cons)
2577 && (max_conses - CONS_BLOCK_SIZE
2578 < gcstat.total_free_conses + gcstat.total_conses))
2579 memory_full (sizeof (struct cons_block));
2580
2581 struct cons_block *new 2559 struct cons_block *new
2582 = lisp_align_malloc (sizeof *new, MEM_TYPE_CONS); 2560 = lisp_align_malloc (sizeof *new, MEM_TYPE_CONS);
2583 memset (new->gcmarkbits, 0, sizeof new->gcmarkbits); 2561 memset (new->gcmarkbits, 0, sizeof new->gcmarkbits);
2584 new->next = cons_block; 2562 new->next = cons_block;
2585 cons_block = new; 2563 cons_block = new;
2586 cons_block_index = 0; 2564 cons_block_index = 0;
2587 gcstat.total_free_conses += CONS_BLOCK_SIZE;
2588 } 2565 }
2589 XSETCONS (val, &cons_block->conses[cons_block_index]); 2566 XSETCONS (val, &cons_block->conses[cons_block_index]);
2590 cons_block_index++; 2567 cons_block_index++;
@@ -2596,7 +2573,6 @@ DEFUN ("cons", Fcons, Scons, 2, 2, 0,
2596 XSETCDR (val, cdr); 2573 XSETCDR (val, cdr);
2597 eassert (!XCONS_MARKED_P (XCONS (val))); 2574 eassert (!XCONS_MARKED_P (XCONS (val)));
2598 consing_until_gc -= sizeof (struct Lisp_Cons); 2575 consing_until_gc -= sizeof (struct Lisp_Cons);
2599 gcstat.total_free_conses--;
2600 cons_cells_consed++; 2576 cons_cells_consed++;
2601 return val; 2577 return val;
2602} 2578}
@@ -2855,7 +2831,6 @@ setup_on_free_list (struct Lisp_Vector *v, ptrdiff_t nbytes)
2855 eassert (vindex < VECTOR_MAX_FREE_LIST_INDEX); 2831 eassert (vindex < VECTOR_MAX_FREE_LIST_INDEX);
2856 set_next_vector (v, vector_free_lists[vindex]); 2832 set_next_vector (v, vector_free_lists[vindex]);
2857 vector_free_lists[vindex] = v; 2833 vector_free_lists[vindex] = v;
2858 gcstat.total_free_vector_slots += nbytes / word_size;
2859} 2834}
2860 2835
2861/* Get a new vector block. */ 2836/* Get a new vector block. */
@@ -2903,7 +2878,6 @@ allocate_vector_from_block (ptrdiff_t nbytes)
2903 { 2878 {
2904 vector = vector_free_lists[index]; 2879 vector = vector_free_lists[index];
2905 vector_free_lists[index] = next_vector (vector); 2880 vector_free_lists[index] = next_vector (vector);
2906 gcstat.total_free_vector_slots -= nbytes / word_size;
2907 return vector; 2881 return vector;
2908 } 2882 }
2909 2883
@@ -2917,7 +2891,6 @@ allocate_vector_from_block (ptrdiff_t nbytes)
2917 /* This vector is larger than requested. */ 2891 /* This vector is larger than requested. */
2918 vector = vector_free_lists[index]; 2892 vector = vector_free_lists[index];
2919 vector_free_lists[index] = next_vector (vector); 2893 vector_free_lists[index] = next_vector (vector);
2920 gcstat.total_free_vector_slots -= nbytes / word_size;
2921 2894
2922 /* Excess bytes are used for the smaller vector, 2895 /* Excess bytes are used for the smaller vector,
2923 which should be set on an appropriate free list. */ 2896 which should be set on an appropriate free list. */
@@ -3092,7 +3065,10 @@ sweep_vectors (void)
3092 space was coalesced into the only free vector. */ 3065 space was coalesced into the only free vector. */
3093 free_this_block = true; 3066 free_this_block = true;
3094 else 3067 else
3095 setup_on_free_list (vector, total_bytes); 3068 {
3069 setup_on_free_list (vector, total_bytes);
3070 gcstat.total_free_vector_slots += total_bytes / word_size;
3071 }
3096 } 3072 }
3097 } 3073 }
3098 3074
@@ -3454,7 +3430,6 @@ Its value is void, and its function definition and property list are nil. */)
3454 new->next = symbol_block; 3430 new->next = symbol_block;
3455 symbol_block = new; 3431 symbol_block = new;
3456 symbol_block_index = 0; 3432 symbol_block_index = 0;
3457 gcstat.total_free_symbols += SYMBOL_BLOCK_SIZE;
3458 } 3433 }
3459 XSETSYMBOL (val, &symbol_block->symbols[symbol_block_index]); 3434 XSETSYMBOL (val, &symbol_block->symbols[symbol_block_index]);
3460 symbol_block_index++; 3435 symbol_block_index++;
@@ -3465,7 +3440,6 @@ Its value is void, and its function definition and property list are nil. */)
3465 init_symbol (val, name); 3440 init_symbol (val, name);
3466 consing_until_gc -= sizeof (struct Lisp_Symbol); 3441 consing_until_gc -= sizeof (struct Lisp_Symbol);
3467 symbols_consed++; 3442 symbols_consed++;
3468 gcstat.total_free_symbols--;
3469 return val; 3443 return val;
3470} 3444}
3471 3445
@@ -5723,7 +5697,7 @@ visit_buffer_root (struct gc_root_visitor visitor,
5723 5697
5724 There are other GC roots of course, but these roots are dynamic 5698 There are other GC roots of course, but these roots are dynamic
5725 runtime data structures that pdump doesn't care about and so we can 5699 runtime data structures that pdump doesn't care about and so we can
5726 continue to mark those directly in garbage_collect_1. */ 5700 continue to mark those directly in garbage_collect. */
5727void 5701void
5728visit_static_gc_roots (struct gc_root_visitor visitor) 5702visit_static_gc_roots (struct gc_root_visitor visitor)
5729{ 5703{
@@ -5753,8 +5727,7 @@ mark_object_root_visitor (Lisp_Object const *root_ptr,
5753} 5727}
5754 5728
5755/* List of weak hash tables we found during marking the Lisp heap. 5729/* List of weak hash tables we found during marking the Lisp heap.
5756 Will be NULL on entry to garbage_collect_1 and after it 5730 NULL on entry to garbage_collect and after it returns. */
5757 returns. */
5758static struct Lisp_Hash_Table *weak_hash_tables; 5731static struct Lisp_Hash_Table *weak_hash_tables;
5759 5732
5760NO_INLINE /* For better stack traces */ 5733NO_INLINE /* For better stack traces */
@@ -5860,8 +5833,8 @@ watch_gc_cons_percentage (Lisp_Object symbol, Lisp_Object newval,
5860} 5833}
5861 5834
5862/* Subroutine of Fgarbage_collect that does most of the work. */ 5835/* Subroutine of Fgarbage_collect that does most of the work. */
5863static bool 5836void
5864garbage_collect_1 (struct gcstat *gcst) 5837garbage_collect (void)
5865{ 5838{
5866 struct buffer *nextb; 5839 struct buffer *nextb;
5867 char stack_top_variable; 5840 char stack_top_variable;
@@ -5873,7 +5846,7 @@ garbage_collect_1 (struct gcstat *gcst)
5873 eassert (weak_hash_tables == NULL); 5846 eassert (weak_hash_tables == NULL);
5874 5847
5875 if (garbage_collection_inhibited) 5848 if (garbage_collection_inhibited)
5876 return false; 5849 return;
5877 5850
5878 /* Record this function, so it appears on the profiler's backtraces. */ 5851 /* Record this function, so it appears on the profiler's backtraces. */
5879 record_in_backtrace (QAutomatic_GC, 0, 0); 5852 record_in_backtrace (QAutomatic_GC, 0, 0);
@@ -6014,8 +5987,6 @@ garbage_collect_1 (struct gcstat *gcst)
6014 5987
6015 unbind_to (count, Qnil); 5988 unbind_to (count, Qnil);
6016 5989
6017 *gcst = gcstat;
6018
6019 /* GC is complete: now we can run our finalizer callbacks. */ 5990 /* GC is complete: now we can run our finalizer callbacks. */
6020 run_finalizers (&doomed_finalizers); 5991 run_finalizers (&doomed_finalizers);
6021 5992
@@ -6043,15 +6014,6 @@ garbage_collect_1 (struct gcstat *gcst)
6043 byte_ct swept = tot_before <= tot_after ? 0 : tot_before - tot_after; 6014 byte_ct swept = tot_before <= tot_after ? 0 : tot_before - tot_after;
6044 malloc_probe (min (swept, SIZE_MAX)); 6015 malloc_probe (min (swept, SIZE_MAX));
6045 } 6016 }
6046
6047 return true;
6048}
6049
6050void
6051garbage_collect (void)
6052{
6053 struct gcstat gcst;
6054 garbage_collect_1 (&gcst);
6055} 6017}
6056 6018
6057DEFUN ("garbage-collect", Fgarbage_collect, Sgarbage_collect, 0, 0, "", 6019DEFUN ("garbage-collect", Fgarbage_collect, Sgarbage_collect, 0, 0, "",
@@ -6071,10 +6033,12 @@ returns nil, because real GC can't be done.
6071See Info node `(elisp)Garbage Collection'. */) 6033See Info node `(elisp)Garbage Collection'. */)
6072 (void) 6034 (void)
6073{ 6035{
6074 struct gcstat gcst; 6036 if (garbage_collection_inhibited)
6075 if (!garbage_collect_1 (&gcst))
6076 return Qnil; 6037 return Qnil;
6077 6038
6039 garbage_collect ();
6040 struct gcstat gcst = gcstat;
6041
6078 Lisp_Object total[] = { 6042 Lisp_Object total[] = {
6079 list4 (Qconses, make_fixnum (sizeof (struct Lisp_Cons)), 6043 list4 (Qconses, make_fixnum (sizeof (struct Lisp_Cons)),
6080 make_int (gcst.total_conses), 6044 make_int (gcst.total_conses),