1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-01 12:20:26 +02:00

Ludovic's patch for scm_t_sweep_statistics.

This commit is contained in:
Han-Wen Nienhuys 2006-02-14 11:38:30 +00:00
parent b712c10755
commit 4c7016dc06
6 changed files with 165 additions and 72 deletions

View file

@ -1,3 +1,36 @@
2006-01-04 Ludovic Court<E8>s <ludovic.courtes@laas.fr>
* gc-segment.c (scm_i_sweep_some_cards): Take a SWEEP_STATS
argument. Don't refer to SCM_GC_CELLS_COLLECTED and
SCM_CELLS_ALLOCATED. If SEG->FIRST_TIME, let CELLS_COLLECTED as zero.
Take into account SEG->SPAN when computing CELLS_SWEPT.
(scm_i_sweep_segment): Take one more argument, similarly.
(scm_i_sweep_all_segments): Likewise.
(scm_i_sweep_some_segments): Likewise.
(scm_i_adjust_min_yield): Change the way MIN_CELLS is computed: do not
refer to SCM_GC_CELLS_COLLECTED.
* gc-freelist.c (scm_i_adjust_min_yield): Take one more
argument, an `scm_i_sweep_statistics' object.
Change the way DELTA is collected: don't take into account
SCM_GC_CELLS_COLLECTED_1, only SWEEP_STATS.COLLECTED.
* gc-malloc.c (scm_realloc): Pass an extra argument
to `scm_i_sweep_all_segments ()'.
* gc.c (gc_start_stats): Updated accordingly.
(gc_end_stats): Take an additional SWEEP_STATS argument.
Decrement SCM_CELLS_ALLOCATED after calls to `scm_i_sweep_* ()'.
(scm_gc_for_newcell): Updated callers of `scm_i_sweep_*'.
Decrement SCM_CELLS_ALLOCATED.
(scm_i_gc): Likewise.
* private-gc.h (scm_i_sweep_*): Updated function
prototypes accordingly.
(scm_t_sweep_statistics): New type.
(scm_i_sweep_statistics_init): New macro.
(scm_i_sweep_statistics_sum): New macro
2006-02-12 Marius Vollmer <mvo@zagadka.de>
* unif.c (scm_dimensions_to_uniform_array): Use the prototype for

View file

@ -78,7 +78,8 @@ SCM_DEFINE (scm_gc_set_debug_check_freelist_x, "gc-set-debug-check-freelist!", 1
*/
void
scm_i_adjust_min_yield (scm_t_cell_type_statistics *freelist)
scm_i_adjust_min_yield (scm_t_cell_type_statistics *freelist,
scm_t_sweep_statistics sweep_stats)
{
/* min yield is adjusted upwards so that next predicted total yield
* (allocated cells actually freed by GC) becomes
@ -98,7 +99,7 @@ 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) SCM_MAX (scm_gc_cells_collected_1, scm_gc_cells_collected));
- (long) sweep_stats.collected);
#ifdef DEBUGINFO
fprintf (stderr, " after GC = %lu, delta = %ld\n",
(unsigned long) scm_cells_allocated,

View file

@ -105,6 +105,7 @@ void *
scm_realloc (void *mem, size_t size)
{
void *ptr;
scm_t_sweep_statistics sweep_stats;
SCM_SYSCALL (ptr = realloc (mem, size));
if (ptr)
@ -113,7 +114,7 @@ scm_realloc (void *mem, size_t size)
scm_i_scm_pthread_mutex_lock (&scm_i_sweep_mutex);
scm_gc_running_p = 1;
scm_i_sweep_all_segments ("realloc");
scm_i_sweep_all_segments ("realloc", &sweep_stats);
SCM_SYSCALL (ptr = realloc (mem, size));
if (ptr)
@ -124,7 +125,7 @@ scm_realloc (void *mem, size_t size)
}
scm_i_gc ("realloc");
scm_i_sweep_all_segments ("realloc");
scm_i_sweep_all_segments ("realloc", &sweep_stats);
scm_gc_running_p = 0;
scm_i_pthread_mutex_unlock (&scm_i_sweep_mutex);
@ -220,13 +221,14 @@ increase_mtrigger (size_t size, const char *what)
{
unsigned long prev_alloced;
float yield;
scm_t_sweep_statistics sweep_stats;
scm_i_scm_pthread_mutex_lock (&scm_i_sweep_mutex);
scm_gc_running_p = 1;
prev_alloced = mallocated;
scm_i_gc (what);
scm_i_sweep_all_segments ("mtrigger");
scm_i_sweep_all_segments ("mtrigger", &sweep_stats);
yield = (((float) prev_alloced - (float) scm_mallocated)
/ (float) prev_alloced);

View file

@ -140,15 +140,13 @@ scm_i_clear_segment_mark_space (scm_t_heap_segment *seg)
scm_i_segment_card_count (seg) * SCM_GC_CARD_BVEC_SIZE_IN_LONGS * SCM_SIZEOF_LONG);
}
/*
Sweep cards from SEG until we've gathered THRESHOLD cells
RETURN:
Freelist.
*/
/* 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. */
SCM
scm_i_sweep_some_cards (scm_t_heap_segment *seg)
scm_i_sweep_some_cards (scm_t_heap_segment *seg,
scm_t_sweep_statistics *sweep_stats)
{
SCM cells = SCM_EOL;
int threshold = 512;
@ -158,7 +156,7 @@ scm_i_sweep_some_cards (scm_t_heap_segment *seg)
scm_t_cell * next_free = seg->next_free_card;
int cards_swept = 0;
while (collected < threshold && next_free < seg->bounds[1])
{
collected += (*sweeper) (next_free, &cells, seg);
@ -166,14 +164,18 @@ scm_i_sweep_some_cards (scm_t_heap_segment *seg)
cards_swept ++;
}
scm_gc_cells_swept += cards_swept * (SCM_GC_CARD_N_CELLS - SCM_GC_CARD_N_HEADER_CELLS);
scm_gc_cells_collected += collected * seg->span;
sweep_stats->swept = cards_swept * seg->span
* (SCM_GC_CARD_N_CELLS - SCM_GC_CARD_N_HEADER_CELLS);
if (!seg->first_time)
scm_cells_allocated -= collected * seg->span;
seg->freelist->collected += collected * seg->span;
{
/* scm_cells_allocated -= collected * seg->span; */
sweep_stats->collected = collected * seg->span;
}
else
sweep_stats->collected = 0;
seg->freelist->collected += collected * seg->span;
if(next_free == seg->bounds[1])
{
@ -196,31 +198,33 @@ scm_i_sweep_some_cards (scm_t_heap_segment *seg)
segment again, the statistics are off.
*/
void
scm_i_sweep_segment (scm_t_heap_segment * seg)
scm_i_sweep_segment (scm_t_heap_segment *seg,
scm_t_sweep_statistics *sweep_stats)
{
scm_t_sweep_statistics sweep;
scm_t_cell * p = seg->next_free_card;
int yield = scm_gc_cells_collected;
int coll = seg->freelist->collected;
unsigned long 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;
scm_i_sweep_statistics_init (sweep_stats);
while (scm_i_sweep_some_cards (seg, &sweep) != SCM_EOL)
scm_i_sweep_statistics_sum (sweep_stats, sweep);
seg->next_free_card =p;
}
void
scm_i_sweep_all_segments (char const *reason)
scm_i_sweep_all_segments (char const *reason,
scm_t_sweep_statistics *sweep_stats)
{
int i= 0;
unsigned i= 0;
scm_i_sweep_statistics_init (sweep_stats);
for (i = 0; i < scm_i_heap_segment_table_size; i++)
{
scm_i_sweep_segment (scm_i_heap_segment_table[i]);
scm_t_sweep_statistics sweep;
scm_i_sweep_segment (scm_i_heap_segment_table[i], &sweep);
scm_i_sweep_statistics_sum (sweep_stats, sweep);
}
}
@ -317,29 +321,35 @@ scm_i_insert_segment (scm_t_heap_segment * seg)
}
SCM
scm_i_sweep_some_segments (scm_t_cell_type_statistics * fl)
scm_i_sweep_some_segments (scm_t_cell_type_statistics *fl,
scm_t_sweep_statistics *sweep_stats)
{
int i = fl->heap_segment_idx;
SCM collected = SCM_EOL;
scm_i_sweep_statistics_init (sweep_stats);
if (i == -1)
i++;
for (;
i < scm_i_heap_segment_table_size; i++)
{
scm_t_sweep_statistics sweep;
if (scm_i_heap_segment_table[i]->freelist != fl)
continue;
collected = scm_i_sweep_some_cards (scm_i_heap_segment_table[i]);
collected = scm_i_sweep_some_cards (scm_i_heap_segment_table[i],
&sweep);
scm_i_sweep_statistics_sum (sweep_stats, sweep);
if (collected != SCM_EOL) /* Don't increment i */
break;
}
fl->heap_segment_idx = i;
return collected;
}
@ -479,8 +489,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 - scm_gc_cells_collected) / (1.0 - f);
/* Make heap grow with factor 1.5 */
len = freelist->heap_size / 2;

View file

@ -403,31 +403,32 @@ gc_start_stats (const char *what SCM_UNUSED)
{
t_before_gc = scm_c_get_internal_run_time ();
scm_gc_cells_marked_acc += (double) scm_gc_cells_swept
- (double) scm_gc_cells_collected;
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;
/*
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_collected = 0;
scm_gc_malloc_collected = 0;
scm_gc_ports_collected = 0;
}
static void
gc_end_stats ()
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;
scm_gc_cell_yield_percentage = (sweep_stats.collected * 100) / SCM_HEAP_SIZE;
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_times;
}
@ -478,15 +479,19 @@ scm_gc_for_newcell (scm_t_cell_type_statistics *freelist, SCM *free_cells)
{
SCM cell;
int did_gc = 0;
scm_t_sweep_statistics sweep_stats;
scm_i_scm_pthread_mutex_lock (&scm_i_sweep_mutex);
scm_gc_running_p = 1;
*free_cells = scm_i_sweep_some_segments (freelist);
*free_cells = scm_i_sweep_some_segments (freelist, &sweep_stats);
scm_cells_allocated -= sweep_stats.collected;
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);
*free_cells = scm_i_sweep_some_segments (freelist);
*free_cells = scm_i_sweep_some_segments (freelist, &sweep_stats);
scm_cells_allocated -= sweep_stats.collected;
}
if (*free_cells == SCM_EOL)
@ -495,7 +500,7 @@ 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);
scm_i_adjust_min_yield (freelist, sweep_stats);
/*
out of fresh cells. Try to get some new ones.
@ -504,7 +509,8 @@ scm_gc_for_newcell (scm_t_cell_type_statistics *freelist, SCM *free_cells)
did_gc = 1;
scm_i_gc ("cells");
*free_cells = scm_i_sweep_some_segments (freelist);
*free_cells = scm_i_sweep_some_segments (freelist, &sweep_stats);
scm_cells_allocated -= sweep_stats.collected;
}
if (*free_cells == SCM_EOL)
@ -513,7 +519,8 @@ 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);
*free_cells = scm_i_sweep_some_segments (freelist);
*free_cells = scm_i_sweep_some_segments (freelist, &sweep_stats);
scm_cells_allocated -= sweep_stats.collected;
}
if (*free_cells == SCM_EOL)
@ -545,6 +552,8 @@ scm_t_c_hook scm_after_gc_c_hook;
void
scm_i_gc (const char *what)
{
scm_t_sweep_statistics sweep_stats;
scm_i_thread_put_to_sleep ();
scm_c_hook_run (&scm_before_gc_c_hook, 0);
@ -571,7 +580,12 @@ scm_i_gc (const char *what)
Let's finish the sweep. The conservative GC might point into the
garbage, and marking that would create a mess.
*/
scm_i_sweep_all_segments("GC");
scm_i_sweep_all_segments ("GC", &sweep_stats);
/* Invariant: the number of cells collected (i.e., freed) must always be
lower than or equal to the number of cells "swept" (i.e., visited). */
assert (sweep_stats.collected <= sweep_stats.swept);
if (scm_mallocated < scm_i_deprecated_memory_return)
{
/* The byte count of allocated objects has underflowed. This is
@ -624,7 +638,7 @@ scm_i_gc (const char *what)
scm_gc_sweep ();
scm_c_hook_run (&scm_after_sweep_c_hook, 0);
gc_end_stats ();
gc_end_stats (sweep_stats);
scm_i_thread_wake_up ();
@ -635,6 +649,7 @@ scm_i_gc (const char *what)
*/
}
/* {GC Protection Helper Functions}
*/

View file

@ -118,11 +118,40 @@ typedef struct scm_t_cell_type_statistics {
} scm_t_cell_type_statistics;
/* Sweep statistics. */
typedef struct scm_sweep_statistics
{
/* Number of cells "swept", i.e., visited during the sweep operation. */
unsigned swept;
/* Number of cells collected during the sweep operation. This number must
alsways be lower than or equal to SWEPT. */
unsigned collected;
} scm_t_sweep_statistics;
#define scm_i_sweep_statistics_init(_stats) \
do \
{ \
(_stats)->swept = (_stats)->collected = 0; \
} \
while (0)
#define scm_i_sweep_statistics_sum(_sum, _addition) \
do \
{ \
(_sum)->swept += (_addition).swept; \
(_sum)->collected += (_addition).collected; \
} \
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);
void scm_i_adjust_min_yield (scm_t_cell_type_statistics *freelist,
scm_t_sweep_statistics sweep_stats);
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);
@ -221,8 +250,10 @@ int scm_i_segment_cell_count (scm_t_heap_segment * seg);
void scm_i_clear_segment_mark_space (scm_t_heap_segment *seg);
scm_t_heap_segment * scm_i_make_empty_heap_segment (scm_t_cell_type_statistics*);
SCM scm_i_sweep_some_cards (scm_t_heap_segment *seg);
void scm_i_sweep_segment (scm_t_heap_segment * seg);
SCM scm_i_sweep_some_cards (scm_t_heap_segment *seg,
scm_t_sweep_statistics *sweep_stats);
void scm_i_sweep_segment (scm_t_heap_segment *seg,
scm_t_sweep_statistics *sweep_stats);
void scm_i_heap_segment_statistics (scm_t_heap_segment *seg, SCM tab);
@ -232,9 +263,11 @@ 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);
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);
SCM scm_i_sweep_some_segments (scm_t_cell_type_statistics *fl,
scm_t_sweep_statistics *sweep_stats);
void scm_i_reset_segments (void);
void scm_i_sweep_all_segments (char const *reason);
void scm_i_sweep_all_segments (char const *reason,
scm_t_sweep_statistics *sweep_stats);
SCM scm_i_all_segments_statistics (SCM hashtab);
void scm_i_make_initial_segment (int init_heap_size, scm_t_cell_type_statistics *freelist);