summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog10
-rw-r--r--configure.in3
-rw-r--r--libguile/ChangeLog39
-rw-r--r--libguile/gc-freelist.c14
-rw-r--r--libguile/gc-segment.c26
-rw-r--r--libguile/gc.c107
-rw-r--r--libguile/gc.h4
-rw-r--r--libguile/private-gc.h9
8 files changed, 149 insertions, 63 deletions
diff --git a/ChangeLog b/ChangeLog
index 637b8fcd2..4cb803ce0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2006-11-08 Ludovic Courtès <ludovic.courtes@laas.fr>
+
+ * configure.in: Pass `bug-guile@gnu.org' as a third argument to
+ `AC_INIT'.
+
2006-10-25 Neil Jerram <neil@ossau.uklinux.net>
IA64 HP-UX patch from Hrvoje Nikšić. (Thanks!)
@@ -2973,3 +2978,8 @@ Thu Aug 1 02:31:53 1996 Jim Blandy <jimb@totoro.cyclic.com>
Makefile. Build doc/Makefile from doc/Makefile.in.
* doc/Makefile.in: New file.
+
+
+;; Local Variables:
+;; coding: utf-8
+;; End:
diff --git a/configure.in b/configure.in
index e63c0a749..6dd983933 100644
--- a/configure.in
+++ b/configure.in
@@ -28,7 +28,8 @@ Boston, MA 02110-1301, USA.
AC_PREREQ(2.53)
AC_INIT(m4_esyscmd(. ./GUILE-VERSION && echo -n ${PACKAGE}),
- m4_esyscmd(. ./GUILE-VERSION && echo -n ${GUILE_VERSION}))
+ m4_esyscmd(. ./GUILE-VERSION && echo -n ${GUILE_VERSION}),
+ [bug-guile@gnu.org])
AC_CONFIG_AUX_DIR([.])
AC_CONFIG_SRCDIR(GUILE-VERSION)
AM_INIT_AUTOMAKE([no-define])
diff --git a/libguile/ChangeLog b/libguile/ChangeLog
index 4443132e7..9def3cd9a 100644
--- a/libguile/ChangeLog
+++ b/libguile/ChangeLog
@@ -1,3 +1,38 @@
+2006-11-08 Ludovic Courtès <ludovic.courtes@laas.fr>
+
+ * libguile/gc-freelist.c (scm_i_adjust_min_yield): Take two
+ "sweep_stats" arguments; use them instead of accessing the global
+ variables `scm_gc_cells_collected' and `scm_gc_cells_collected_1'.
+
+ * libguile/gc-segment.c (scm_i_sweep_some_cards): Reset SWEEP
+ before each iteration of the loop.
+ (scm_i_sweep_some_segments): Reset SWEEP at each iteration.
+ (scm_i_get_new_heap_segment): Take an additional argument
+ SWEEP_STATS. Compute MIN_CELLS as a function of it.
+
+ * libguile/gc.c (scm_gc_cells_collected,
+ scm_gc_cells_collected_1): Removed.
+ (scm_i_gc_sweep_stats, scm_i_gc_sweep_stats_1): New.
+ (scm_gc_cells_marked_acc, scm_gc_cells_swept_acc,
+ scm_gc_time_taken, scm_gc_mark_time_taken, scm_gc_times,
+ scm_gc_cell_yield_percentage, protected_obj_count): Made `static'.
+ (scm_gc_stats): Use `scm_i_gc_sweep_stats' instead of
+ `scm_gc_cells_(collected|swept)'.
+ (gc_update_stats): New.
+ (gc_end_stats): Use `scm_i_gc_sweep_stats' and
+ `scm_i_gc_sweep_stats_1' instead of the former globals.
+ (scm_gc_for_newcell): Invoke `gc_update_stats ()' after each
+ `scm_i_sweep_some_segments' call. This fixes a bug where the GC
+ would keep allocating new segments instead of re-using collected
+ cells (because `scm_gc_cells_collected' would remain zero).
+
+ * libguile/gc.h (scm_gc_cells_swept, scm_gc_cells_collected,
+ scm_gc_cell_yield_percentage): Removed.
+
+ * libguile/private-gc.h (scm_gc_cells_collected_1): Removed.
+ (scm_i_adjust_min_yield): Updated.
+ (scm_i_get_new_heap_segment): Updated.
+
2006-11-02 Neil Jerram <neil@ossau.uklinux.net>
* modules.c: Correct comment saying that low-level environments
@@ -13546,3 +13581,7 @@
(write_all): new helper procedure.
The ChangeLog continues in the file: "ChangeLog-2000"
+
+;; Local Variables:
+;; coding: utf-8
+;; End:
diff --git a/libguile/gc-freelist.c b/libguile/gc-freelist.c
index b3b558257..83c20f867 100644
--- a/libguile/gc-freelist.c
+++ b/libguile/gc-freelist.c
@@ -72,14 +72,13 @@ SCM_DEFINE (scm_gc_set_debug_check_freelist_x, "gc-set-debug-check-freelist!", 1
-/*
- This adjust FREELIST variables to decide wether or not to allocate
- more heap in the next GC run. It uses scm_gc_cells_collected and scm_gc_cells_collected1
- */
-
+/* Adjust FREELIST variables to decide wether or not to allocate more heap in
+ the next GC run based on SWEEP_STATS on SWEEP_STATS_1 (statistics
+ collected after the two last full GC). */
void
scm_i_adjust_min_yield (scm_t_cell_type_statistics *freelist,
- scm_t_sweep_statistics sweep_stats)
+ scm_t_sweep_statistics sweep_stats,
+ scm_t_sweep_statistics sweep_stats_1)
{
/* min yield is adjusted upwards so that next predicted total yield
* (allocated cells actually freed by GC) becomes
@@ -99,7 +98,8 @@ scm_i_adjust_min_yield (scm_t_cell_type_statistics *freelist,
{
/* Pick largest of last two yields. */
long delta = ((SCM_HEAP_SIZE * freelist->min_yield_fraction / 100)
- - (long) sweep_stats.collected);
+ - (long) SCM_MAX (sweep_stats.collected,
+ sweep_stats_1.collected));
#ifdef DEBUGINFO
fprintf (stderr, " after GC = %lu, delta = %ld\n",
(unsigned long) scm_cells_allocated,
diff --git a/libguile/gc-segment.c b/libguile/gc-segment.c
index 6e744184d..b26f1bd56 100644
--- a/libguile/gc-segment.c
+++ b/libguile/gc-segment.c
@@ -141,9 +141,8 @@ scm_i_clear_segment_mark_space (scm_t_heap_segment *seg)
}
/* Sweep cards from SEG until we've gathered THRESHOLD cells. On return,
- *CELLS_SWEPT contains the number of cells that have been visited and
- *CELLS_COLLECTED contains the number of cells actually collected. A
- freelist is returned, potentially empty. */
+ SWEEP_STATS contains the number of cells that have been visited and
+ collected. A freelist is returned, potentially empty. */
SCM
scm_i_sweep_some_cards (scm_t_heap_segment *seg,
scm_t_sweep_statistics *sweep_stats)
@@ -206,8 +205,12 @@ scm_i_sweep_segment (scm_t_heap_segment *seg,
scm_i_sweep_statistics_init (sweep_stats);
+ scm_i_sweep_statistics_init (&sweep);
while (scm_i_sweep_some_cards (seg, &sweep) != SCM_EOL)
- scm_i_sweep_statistics_sum (sweep_stats, sweep);
+ {
+ scm_i_sweep_statistics_sum (sweep_stats, sweep);
+ scm_i_sweep_statistics_init (&sweep);
+ }
seg->next_free_card =p;
}
@@ -339,6 +342,7 @@ scm_i_sweep_some_segments (scm_t_cell_type_statistics *fl,
if (scm_i_heap_segment_table[i]->freelist != fl)
continue;
+ scm_i_sweep_statistics_init (&sweep);
collected = scm_i_sweep_some_cards (scm_i_heap_segment_table[i],
&sweep);
@@ -461,14 +465,12 @@ scm_i_find_heap_segment_containing_object (SCM obj)
}
-/*
- Important entry point: try to grab some memory, and make it into a
- segment.
-
- RETURN: the index of the segment.
- */
-int
+/* Important entry point: try to grab some memory, and make it into a
+ segment; return the index of the segment. SWEEP_STATS should contain
+ global GC sweep statistics collected since the last full GC. */
+int
scm_i_get_new_heap_segment (scm_t_cell_type_statistics *freelist,
+ scm_t_sweep_statistics sweep_stats,
policy_on_error error_policy)
{
size_t len;
@@ -489,7 +491,7 @@ scm_i_get_new_heap_segment (scm_t_cell_type_statistics *freelist,
*/
float f = freelist->min_yield_fraction / 100.0;
float h = SCM_HEAP_SIZE;
- float min_cells = (f * h - scm_gc_cells_collected) / (1.0 - f);
+ float min_cells = (f * h - sweep_stats.collected) / (1.0 - f);
/* Make heap grow with factor 1.5 */
len = freelist->heap_size / 2;
diff --git a/libguile/gc.c b/libguile/gc.c
index 89984888a..ead6d30be 100644
--- a/libguile/gc.c
+++ b/libguile/gc.c
@@ -209,20 +209,28 @@ unsigned long scm_mtrigger;
*/
unsigned 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 */
-unsigned long scm_gc_malloc_collected;
-unsigned long scm_gc_ports_collected;
-unsigned long scm_gc_time_taken = 0;
+
+/* Global GC sweep statistics since the last full GC. */
+static scm_t_sweep_statistics scm_i_gc_sweep_stats = { 0, 0 };
+static scm_t_sweep_statistics scm_i_gc_sweep_stats_1 = { 0, 0 };
+
+/* Total count of cells marked/swept. */
+static double scm_gc_cells_marked_acc = 0.;
+static double scm_gc_cells_swept_acc = 0.;
+
+static unsigned long scm_gc_time_taken = 0;
static unsigned long t_before_gc;
-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;
+static unsigned long scm_gc_mark_time_taken = 0;
+
+static unsigned long scm_gc_times = 0;
+
+static int scm_gc_cell_yield_percentage = 0;
+static unsigned long protected_obj_count = 0;
+
+/* The following are accessed from `gc-malloc.c' and `gc-card.c'. */
int scm_gc_malloc_yield_percentage = 0;
-unsigned long protected_obj_count = 0;
+unsigned long scm_gc_malloc_collected = 0;
+unsigned long scm_gc_ports_collected = 0;
SCM_SYMBOL (sym_cells_allocated, "cells-allocated");
@@ -346,10 +354,10 @@ SCM_DEFINE (scm_gc_stats, "gc-stats", 0, 0, 0,
local_protected_obj_count = protected_obj_count;
local_scm_gc_cells_swept =
(double) scm_gc_cells_swept_acc
- + (double) scm_gc_cells_swept;
+ + (double) scm_i_gc_sweep_stats.swept;
local_scm_gc_cells_marked = scm_gc_cells_marked_acc
- +(double) scm_gc_cells_swept
- -(double) scm_gc_cells_collected;
+ +(double) scm_i_gc_sweep_stats.swept
+ -(double) scm_i_gc_sweep_stats.collected;
for (i = table_size; i--;)
{
@@ -393,6 +401,30 @@ SCM_DEFINE (scm_gc_stats, "gc-stats", 0, 0, 0,
}
#undef FUNC_NAME
+/* Update the global sweeping/collection statistics by adding SWEEP_STATS to
+ SCM_I_GC_SWEEP_STATS and updating related variables. */
+static inline void
+gc_update_stats (scm_t_sweep_statistics sweep_stats)
+{
+ /* CELLS SWEPT is another word for the number of cells that were examined
+ during GC. YIELD is the number that we cleaned out. MARKED is the number
+ that weren't cleaned. */
+
+ scm_gc_cell_yield_percentage = (sweep_stats.collected * 100) / SCM_HEAP_SIZE;
+
+ scm_i_sweep_statistics_sum (&scm_i_gc_sweep_stats, sweep_stats);
+
+ if ((scm_i_gc_sweep_stats.collected > scm_i_gc_sweep_stats.swept)
+ || (scm_cells_allocated < sweep_stats.collected))
+ {
+ printf ("internal GC error, please report to `"
+ PACKAGE_BUGREPORT "'\n");
+ abort ();
+ }
+
+ scm_cells_allocated -= sweep_stats.collected;
+}
+
static void
gc_start_stats (const char *what SCM_UNUSED)
{
@@ -406,23 +438,18 @@ static void
gc_end_stats (scm_t_sweep_statistics sweep_stats)
{
unsigned long t = scm_c_get_internal_run_time ();
+
scm_gc_time_taken += (t - t_before_gc);
- /*
- CELLS SWEPT is another word for the number of cells that were
- examined during GC. YIELD is the number that we cleaned
- out. MARKED is the number that weren't cleaned.
- */
- scm_gc_cells_marked_acc += (double) sweep_stats.swept
- - (double) scm_gc_cells_collected;
- scm_gc_cells_swept_acc += (double) sweep_stats.swept;
+ /* Reset the number of cells swept/collected since the last full GC. */
+ scm_i_gc_sweep_stats_1 = scm_i_gc_sweep_stats;
+ scm_i_gc_sweep_stats.collected = scm_i_gc_sweep_stats.swept = 0;
- scm_gc_cell_yield_percentage = (sweep_stats.collected * 100) / SCM_HEAP_SIZE;
+ gc_update_stats (sweep_stats);
- scm_gc_cells_swept = sweep_stats.swept;
- scm_gc_cells_collected_1 = scm_gc_cells_collected;
- scm_gc_cells_collected = sweep_stats.collected;
- scm_cells_allocated -= sweep_stats.collected;
+ scm_gc_cells_marked_acc += (double) scm_i_gc_sweep_stats.swept
+ - (double) scm_i_gc_sweep_stats.collected;
+ scm_gc_cells_swept_acc += (double) scm_i_gc_sweep_stats.swept;
++scm_gc_times;
}
@@ -480,13 +507,17 @@ scm_gc_for_newcell (scm_t_cell_type_statistics *freelist, SCM *free_cells)
scm_gc_running_p = 1;
*free_cells = scm_i_sweep_some_segments (freelist, &sweep_stats);
- scm_cells_allocated -= sweep_stats.collected;
+ gc_update_stats (sweep_stats);
if (*free_cells == SCM_EOL && scm_i_gc_grow_heap_p (freelist))
{
- freelist->heap_segment_idx = scm_i_get_new_heap_segment (freelist, abort_on_error);
+ freelist->heap_segment_idx =
+ scm_i_get_new_heap_segment (freelist,
+ scm_i_gc_sweep_stats,
+ abort_on_error);
+
*free_cells = scm_i_sweep_some_segments (freelist, &sweep_stats);
- scm_cells_allocated -= sweep_stats.collected;
+ gc_update_stats (sweep_stats);
}
if (*free_cells == SCM_EOL)
@@ -495,7 +526,9 @@ scm_gc_for_newcell (scm_t_cell_type_statistics *freelist, SCM *free_cells)
with the advent of lazy sweep, GC yield is only known just
before doing the GC.
*/
- scm_i_adjust_min_yield (freelist, sweep_stats);
+ scm_i_adjust_min_yield (freelist,
+ scm_i_gc_sweep_stats,
+ scm_i_gc_sweep_stats_1);
/*
out of fresh cells. Try to get some new ones.
@@ -505,7 +538,7 @@ scm_gc_for_newcell (scm_t_cell_type_statistics *freelist, SCM *free_cells)
scm_i_gc ("cells");
*free_cells = scm_i_sweep_some_segments (freelist, &sweep_stats);
- scm_cells_allocated -= sweep_stats.collected;
+ gc_update_stats (sweep_stats);
}
if (*free_cells == SCM_EOL)
@@ -513,9 +546,13 @@ scm_gc_for_newcell (scm_t_cell_type_statistics *freelist, SCM *free_cells)
/*
failed getting new cells. Get new juice or die.
*/
- freelist->heap_segment_idx = scm_i_get_new_heap_segment (freelist, abort_on_error);
+ freelist->heap_segment_idx =
+ scm_i_get_new_heap_segment (freelist,
+ scm_i_gc_sweep_stats,
+ abort_on_error);
+
*free_cells = scm_i_sweep_some_segments (freelist, &sweep_stats);
- scm_cells_allocated -= sweep_stats.collected;
+ gc_update_stats (sweep_stats);
}
if (*free_cells == SCM_EOL)
diff --git a/libguile/gc.h b/libguile/gc.h
index 7c991bfbb..78ff02474 100644
--- a/libguile/gc.h
+++ b/libguile/gc.h
@@ -277,13 +277,9 @@ SCM_API scm_i_pthread_key_t scm_i_freelist2;
SCM_API struct scm_t_cell_type_statistics scm_i_master_freelist;
SCM_API struct scm_t_cell_type_statistics scm_i_master_freelist2;
-
-SCM_API unsigned long scm_gc_cells_swept;
-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 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 8bda190c4..7c0fd883b 100644
--- a/libguile/private-gc.h
+++ b/libguile/private-gc.h
@@ -144,14 +144,13 @@ typedef struct scm_sweep_statistics
} \
while (0)
-
extern scm_t_cell_type_statistics scm_i_master_freelist;
extern scm_t_cell_type_statistics scm_i_master_freelist2;
-extern unsigned long scm_gc_cells_collected_1;
void scm_i_adjust_min_yield (scm_t_cell_type_statistics *freelist,
- scm_t_sweep_statistics sweep_stats);
+ scm_t_sweep_statistics sweep_stats,
+ scm_t_sweep_statistics sweep_stats_1);
void scm_i_gc_sweep_freelist_reset (scm_t_cell_type_statistics *freelist);
int scm_i_gc_grow_heap_p (scm_t_cell_type_statistics * freelist);
@@ -270,7 +269,9 @@ void scm_i_heap_segment_statistics (scm_t_heap_segment *seg, SCM tab);
int scm_i_insert_segment (scm_t_heap_segment * seg);
long int scm_i_find_heap_segment_containing_object (SCM obj);
-int scm_i_get_new_heap_segment (scm_t_cell_type_statistics *, policy_on_error);
+int scm_i_get_new_heap_segment (scm_t_cell_type_statistics *,
+ scm_t_sweep_statistics,
+ policy_on_error);
void scm_i_clear_mark_space (void);
void scm_i_sweep_segments (void);
SCM scm_i_sweep_some_segments (scm_t_cell_type_statistics *fl,