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:
parent
b712c10755
commit
4c7016dc06
6 changed files with 165 additions and 72 deletions
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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}
|
||||
*/
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue