gc statistic tweaks
authorHan-Wen Nienhuys <hanwen@lilypond.org>
Sun, 4 Aug 2002 14:09:14 +0000 (14:09 +0000)
committerHan-Wen Nienhuys <hanwen@lilypond.org>
Sun, 4 Aug 2002 14:09:14 +0000 (14:09 +0000)
ChangeLog
NEWS
libguile/ChangeLog
libguile/dynl.c
libguile/gc-malloc.c
libguile/gc-segment.c
libguile/gc.c
libguile/gc.h
libguile/private-gc.h

index 9f3b873..fd4a89d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2002-08-04  Han-Wen  <hanwen@cs.uu.nl>
+
+       * NEWS: add entries for GC and vector WB.
+
 2002-07-22  Han-Wen  <hanwen@cs.uu.nl>
 
        * autogen.sh (mscripts): find and check version number of
diff --git a/NEWS b/NEWS
index 1655989..611ca72 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,29 @@ Changes since the stable branch:
 
 * Changes to the standalone interpreter
 
+** SCM_VELTS macros is now read-only. For writing, use the new macros
+SCM_WRITABLE_VELTS, SCM_SET_VECTOR_LENGTH.  The use of
+SCM_WRITABLE_VELTS is discouraged, though. 
+
+** Garbage collector rewrite.
+
+The garbage collector is cleaned up a lot, and now uses lazy
+sweeping. This is reflected in the output of (gc-stats); since cells
+are being freed when they are allocated, the cells-allocated field
+stays roughly constant.
+
+For malloc related triggers, the behavior is changed. It uses the same
+heuristic as the cell-triggered collections.  It may be tuned with the
+environment variables GUILE_MIN_YIELD_MALLOC.  This is the percentage
+for minimum yield of malloc related triggers; (default: 40)
+GUILE_INIT_MALLOC_LIMIT is the trigger for doing a GC. The default is
+200 kb.
+
+Debugging operations for the freelist have been deprecated, along with
+the C variables that control garbage collection.  The environment
+variables GUILE_MAX_SEGMENT_SIZE, GUILE_INIT_SEGMENT_SIZE_2,
+GUILE_INIT_SEGMENT_SIZE_1, and GUILE_MIN_YIELD_2 should be used.
+
 ** New command line option `--no-debug'.
 
 Specifying `--no-debug' on the command line will keep the debugging
index 7ec6feb..8bbe74a 100644 (file)
@@ -1,9 +1,12 @@
 2002-08-04  Han-Wen  <hanwen@cs.uu.nl>
 
+       * gc.c (s_scm_gc_stats): add cell-yield and malloc-yield statistic
+       to gc-stats.
+
        * numbers.c (big2str): return "0" for 0 iso. ""
 
-        * gc-segment.c, gc-malloc.c gc-mark.c, gc-freelist.c, gc-card.c, private-gc.h:
-        new file
+        * gc-segment.c, gc-malloc.c gc-mark.c, gc-freelist.c, gc-card.c,
+       private-gc.h: new file
 
         * gc.c: completely revised and cleaned up the GC. It now uses lazy
         sweeping. More documentation in workbook/newgc.text
index 4cc46d1..cb1e71f 100644 (file)
@@ -77,13 +77,14 @@ maybe_drag_in_eprintf ()
 
 #include "libltdl/ltdl.h"
 
-/* From the libtool manual: "Note that libltdl is not threadsafe,
-   i.e. a multithreaded application has to use a mutex for libltdl.".
+/*
+  From the libtool manual: "Note that libltdl is not threadsafe,
+  i.e. a multithreaded application has to use a mutex for libltdl.".
 
-   Guile does not currently support pre-emptive threads, so there is
-   no mutex.  Previously SCM_DEFER_INTS and SCM_ALLOW_INTS were used:
-   they are mentioned here in case somebody is grepping for thread
-   problems ;)
+  Guile does not currently support pre-emptive threads, so there is
+  no mutex.  Previously SCM_DEFER_INTS and SCM_ALLOW_INTS were used:
+  they are mentioned here in case somebody is grepping for thread
+  problems ;)
 */
 
 static void *
index 40d4ef9..a1d8f2d 100644 (file)
@@ -92,7 +92,7 @@ extern unsigned long * __libc_ia64_register_backing_store_base;
   alloced memory, which won't go away on GC. Let's set the init such
   that we get a nice yield on the next allocation:
 */
-#define SCM_DEFAULT_INIT_MALLOC_LIMIT 200000
+#define SCM_DEFAULT_INIT_MALLOC_LIMIT 200*1024
 #define SCM_DEFAULT_MALLOC_MINYIELD 40
 
 
@@ -203,8 +203,8 @@ scm_gc_register_collectable_memory (void *mem, size_t size, const char *what)
       scm_igc (what);
       scm_i_sweep_all_segments("mtrigger");
 
-      yield  = (prev_alloced - scm_mallocated) / (float) prev_alloced;
-
+      yield = (prev_alloced - scm_mallocated) / (float) prev_alloced;
+      scm_gc_malloc_yield_percentage = (int) (100  * yield);
       /*
       fprintf (stderr,  "prev %lud , now %lud, yield %4.2lf, want %d",
               prev_alloced, scm_mallocated, 100.0*yield, scm_i_minyield_malloc);
@@ -225,9 +225,9 @@ scm_gc_register_collectable_memory (void *mem, size_t size, const char *what)
          /*
          fprintf (stderr, "Mtrigger sweep: ineffective. New trigger %d\n", scm_mtrigger);
          */
-
-         
        }
+
+
     }
   
 #ifdef GUILE_DEBUG_MALLOC
index a3859df..d3a48f2 100644 (file)
@@ -195,7 +195,12 @@ scm_i_sweep_some_cards (scm_t_heap_segment *seg)
 
   scm_gc_cells_swept +=  cards_swept * (SCM_GC_CARD_N_CELLS - SCM_GC_CARD_N_HEADER_CELLS);
   scm_gc_cells_collected += collected * seg->span;
+
+  if (!seg->first_time)
+    scm_cells_allocated -= collected * seg->span;
+  
   seg->freelist->collected += collected  * seg->span;
+  
 
   if(next_free == seg->bounds[1])
     {
@@ -212,8 +217,10 @@ scm_i_sweep_some_cards (scm_t_heap_segment *seg)
   statistics, it just frees the memory pointed to by to-be-swept
   cells.
 
-  Implementation is slightly ugh, and how do we handle the swept_cells
-  statistic?
+  Implementation is slightly ugh.
+
+  FIXME: if you do scm_i_sweep_segment(), and then allocate from this
+  segment again, the statistics are off.
  */
 void
 scm_i_sweep_segment (scm_t_heap_segment * seg)
@@ -221,11 +228,13 @@ scm_i_sweep_segment (scm_t_heap_segment * seg)
   scm_t_cell * p = seg->next_free_card;
   int yield = scm_gc_cells_collected;
   int coll = seg->freelist->collected;
-
+  int alloc = scm_cells_allocated ;
+  
   while (scm_i_sweep_some_cards (seg) != SCM_EOL)
     ;
 
   scm_gc_cells_collected = yield;
+  scm_cells_allocated = alloc;
   seg->freelist->collected = coll; 
   
   seg->next_free_card =p;
index 0a4a1cf..58ede22 100644 (file)
@@ -256,7 +256,7 @@ SCM scm_structs_to_free;
 
 /* GC Statistics Keeping
  */
-unsigned long scm_cells_allocated = 0;
+long scm_cells_allocated = 0;
 unsigned long scm_mallocated = 0;
 unsigned long scm_gc_cells_collected;
 unsigned long scm_gc_cells_collected_1 = 0; /* previous GC yield */
@@ -264,12 +264,14 @@ unsigned long scm_gc_malloc_collected;
 unsigned long scm_gc_ports_collected;
 unsigned long scm_gc_time_taken = 0;
 static unsigned long t_before_gc;
-static unsigned long t_before_sweep;
 unsigned long scm_gc_mark_time_taken = 0;
 unsigned long scm_gc_times = 0;
 unsigned long scm_gc_cells_swept = 0;
 double scm_gc_cells_marked_acc = 0.;
 double scm_gc_cells_swept_acc = 0.;
+int scm_gc_cell_yield_percentage =0;
+int scm_gc_malloc_yield_percentage = 0;
+
 
 SCM_SYMBOL (sym_cells_allocated, "cells-allocated");
 SCM_SYMBOL (sym_heap_size, "cell-heap-size");
@@ -281,6 +283,8 @@ SCM_SYMBOL (sym_gc_mark_time_taken, "gc-mark-time-taken");
 SCM_SYMBOL (sym_times, "gc-times");
 SCM_SYMBOL (sym_cells_marked, "cells-marked");
 SCM_SYMBOL (sym_cells_swept, "cells-swept");
+SCM_SYMBOL (sym_malloc_yield, "malloc-yield");
+SCM_SYMBOL (sym_cell_yield, "cell-yield");
 
 
 
@@ -292,7 +296,7 @@ unsigned scm_newcell2_count;
 
 /* {Scheme Interface to GC}
  */
-
+extern int scm_gc_malloc_yield_percentage;
 SCM_DEFINE (scm_gc_stats, "gc-stats", 0, 0, 0,
             (),
            "Return an association list of statistics about Guile's current\n"
@@ -304,7 +308,9 @@ SCM_DEFINE (scm_gc_stats, "gc-stats", 0, 0, 0,
   unsigned long int local_scm_mtrigger;
   unsigned long int local_scm_mallocated;
   unsigned long int local_scm_heap_size;
-  unsigned long int local_scm_cells_allocated;
+  int local_scm_gc_cell_yield_percentage;
+  int local_scm_gc_malloc_yield_percentage;
+  long int local_scm_cells_allocated;
   unsigned long int local_scm_gc_time_taken;
   unsigned long int local_scm_gc_times;
   unsigned long int local_scm_gc_mark_time_taken;
@@ -341,14 +347,16 @@ SCM_DEFINE (scm_gc_stats, "gc-stats", 0, 0, 0,
   local_scm_gc_time_taken = scm_gc_time_taken;
   local_scm_gc_mark_time_taken = scm_gc_mark_time_taken;
   local_scm_gc_times = scm_gc_times;
-
-
-  local_scm_gc_cells_swept = scm_gc_cells_swept_acc  + scm_gc_cells_swept;
+  local_scm_gc_malloc_yield_percentage = scm_gc_malloc_yield_percentage;
+  local_scm_gc_cell_yield_percentage=  scm_gc_cell_yield_percentage;
+  
+  local_scm_gc_cells_swept =
+    (double) scm_gc_cells_swept_acc
+    + (double) scm_gc_cells_swept;
   local_scm_gc_cells_marked = scm_gc_cells_marked_acc 
     +(double) scm_gc_cells_swept 
     -(double) scm_gc_cells_collected;
 
-
   for (i = table_size; i--;)
     {
       heap_segs = scm_cons (scm_cons (scm_ulong2num (bounds[2*i]),
@@ -357,7 +365,7 @@ SCM_DEFINE (scm_gc_stats, "gc-stats", 0, 0, 0,
     }
   
   answer = scm_list_n (scm_cons (sym_gc_time_taken, scm_ulong2num (local_scm_gc_time_taken)),
-                      scm_cons (sym_cells_allocated, scm_ulong2num (local_scm_cells_allocated)),
+                      scm_cons (sym_cells_allocated, scm_long2num (local_scm_cells_allocated)),
                       scm_cons (sym_heap_size, scm_ulong2num (local_scm_heap_size)),
                       scm_cons (sym_mallocated, scm_ulong2num (local_scm_mallocated)),
                       scm_cons (sym_mtrigger, scm_ulong2num (local_scm_mtrigger)),
@@ -365,6 +373,8 @@ SCM_DEFINE (scm_gc_stats, "gc-stats", 0, 0, 0,
                       scm_cons (sym_gc_mark_time_taken, scm_ulong2num (local_scm_gc_mark_time_taken)),
                       scm_cons (sym_cells_marked, scm_i_dbl2big (local_scm_gc_cells_marked)),
                       scm_cons (sym_cells_swept, scm_i_dbl2big (local_scm_gc_cells_swept)),
+                      scm_cons (sym_malloc_yield, scm_long2num (local_scm_gc_malloc_yield_percentage)),
+                      scm_cons (sym_cell_yield, scm_long2num (local_scm_gc_cell_yield_percentage)),                   
                       scm_cons (sym_heap_segments, heap_segs),
                       SCM_UNDEFINED);
   SCM_ALLOW_INTS;
@@ -381,8 +391,10 @@ gc_start_stats (const char *what SCM_UNUSED)
 
   scm_gc_cells_marked_acc += (double) scm_gc_cells_swept
     - (double) scm_gc_cells_collected;
-  scm_gc_cells_swept_acc += scm_gc_cells_swept;
+  scm_gc_cells_swept_acc += (double) scm_gc_cells_swept;
 
+  scm_gc_cell_yield_percentage = ( scm_gc_cells_collected * 100 ) / SCM_HEAP_SIZE; 
+  
   scm_gc_cells_swept = 0;
   scm_gc_cells_collected_1 = scm_gc_cells_collected;
 
@@ -554,8 +566,7 @@ scm_igc (const char *what)
 
   scm_mark_all ();
   
-  t_before_sweep = scm_c_get_internal_run_time ();
-  scm_gc_mark_time_taken += (t_before_sweep - t_before_gc);
+  scm_gc_mark_time_taken += (scm_c_get_internal_run_time () - t_before_gc);
 
   scm_c_hook_run (&scm_before_sweep_c_hook, 0);
 
index bd86ad1..1e688d6 100644 (file)
@@ -284,7 +284,9 @@ SCM_API unsigned long scm_gc_cells_collected;
 SCM_API unsigned long scm_gc_cells_collected;
 SCM_API unsigned long scm_gc_malloc_collected;
 SCM_API unsigned long scm_gc_ports_collected;
-SCM_API unsigned long scm_cells_allocated;
+SCM_API long scm_cells_allocated;
+SCM_API int scm_gc_cell_yield_percentage;
+SCM_API int scm_gc_malloc_yield_percentage;
 SCM_API unsigned long scm_mallocated;
 SCM_API unsigned long scm_mtrigger;
 
index 52556be..3924e50 100644 (file)
@@ -109,6 +109,7 @@ typedef struct scm_t_cell_type_statistics {
    */
   unsigned long heap_size;
 
+  
 } scm_t_cell_type_statistics;