summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--NEWS23
-rw-r--r--libguile/ChangeLog7
-rw-r--r--libguile/dynl.c13
-rw-r--r--libguile/gc-malloc.c10
-rw-r--r--libguile/gc-segment.c15
-rw-r--r--libguile/gc.c35
-rw-r--r--libguile/gc.h4
-rw-r--r--libguile/private-gc.h1
9 files changed, 83 insertions, 29 deletions
diff --git a/ChangeLog b/ChangeLog
index 9f3b87388..fd4a89dc1 100644
--- 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 1655989ff..611ca7239 100644
--- 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
diff --git a/libguile/ChangeLog b/libguile/ChangeLog
index 7ec6feb57..8bbe74abb 100644
--- a/libguile/ChangeLog
+++ b/libguile/ChangeLog
@@ -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
diff --git a/libguile/dynl.c b/libguile/dynl.c
index 4cc46d1e3..cb1e71fbd 100644
--- a/libguile/dynl.c
+++ b/libguile/dynl.c
@@ -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 *
diff --git a/libguile/gc-malloc.c b/libguile/gc-malloc.c
index 40d4ef907..a1d8f2dc8 100644
--- a/libguile/gc-malloc.c
+++ b/libguile/gc-malloc.c
@@ -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
diff --git a/libguile/gc-segment.c b/libguile/gc-segment.c
index a3859df7b..d3a48f2ab 100644
--- a/libguile/gc-segment.c
+++ b/libguile/gc-segment.c
@@ -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;
diff --git a/libguile/gc.c b/libguile/gc.c
index 0a4a1cfad..58ede2266 100644
--- a/libguile/gc.c
+++ b/libguile/gc.c
@@ -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);
diff --git a/libguile/gc.h b/libguile/gc.h
index bd86ad1f0..1e688d65a 100644
--- a/libguile/gc.h
+++ b/libguile/gc.h
@@ -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;
diff --git a/libguile/private-gc.h b/libguile/private-gc.h
index 52556bee6..3924e5044 100644
--- a/libguile/private-gc.h
+++ b/libguile/private-gc.h
@@ -109,6 +109,7 @@ typedef struct scm_t_cell_type_statistics {
*/
unsigned long heap_size;
+
} scm_t_cell_type_statistics;