more fixes for garbage collector

git-svn-id: https://yap.svn.sf.net/svnroot/yap/trunk@1394 b08c6af1-5177-4d33-ba66-4b1c6b8b522a
This commit is contained in:
vsc 2005-09-21 03:49:33 +00:00
parent c6c9e71e31
commit 129efd83d8
6 changed files with 124 additions and 65 deletions

View File

@ -1607,6 +1607,7 @@ Yap_InitYaamRegs(void)
MutableList = Yap_NewTimedVar(TermNil);
AttsMutableList = Yap_NewTimedVar(MkIntTerm(0));
#endif
GcGeneration = Yap_NewTimedVar(MkIntTerm(0));
#if defined(YAPOR) || defined(THREADS)
PP = NULL;
WPP = NULL;

View File

@ -159,6 +159,7 @@ SetHeapRegs(void)
if (WokenGoals)
WokenGoals = AbsAppl(PtoGloAdjust(RepAppl(WokenGoals)));
#endif
GcGeneration = AbsAppl(PtoGloAdjust(RepAppl(GcGeneration)));
}
static void
@ -209,6 +210,7 @@ SetStackRegs(void)
if (WokenGoals)
WokenGoals = AbsAppl(PtoGloAdjust(RepAppl(WokenGoals)));
#endif
GcGeneration = AbsAppl(PtoGloAdjust(RepAppl(GcGeneration)));
}
static void

View File

@ -34,7 +34,7 @@ static char SccsId[] = "%W% %G%";
/* global variables for garbage collection */
/* in a single gc */
static unsigned long int total_marked; /* number of heap objects marked */
static unsigned long int total_marked, total_oldies; /* number of heap objects marked */
#if DEBUG
#ifdef COROUTINING
@ -55,6 +55,8 @@ static CELL *prev_HB;
static tr_fr_ptr new_TR;
static CELL *HGEN;
STATIC_PROTO(void push_registers, (Int, yamop *));
STATIC_PROTO(void marking_phase, (tr_fr_ptr, CELL *, yamop *, CELL *));
STATIC_PROTO(void compaction_phase, (tr_fr_ptr, CELL *, yamop *, CELL *));
@ -231,7 +233,7 @@ insort(CELL *a[], Int p, Int q)
key = a[j];
i = j;
while (i > p && a[i-1] > key) {
a[i] = a[i-1];
i --;
@ -379,6 +381,8 @@ push_registers(Int num_regs, yamop *nextop)
}
al = al->NextArrayE;
}
TrailTerm(TR) = GcGeneration;
TR++;
#ifdef COROUTINING
TrailTerm(TR) = WokenGoals;
TrailTerm(TR+1) = MutableList;
@ -429,6 +433,7 @@ pop_registers(Int num_regs, yamop *nextop)
}
al = al->NextArrayE;
}
GcGeneration = TrailTerm(ptr++);
#ifdef COROUTINING
#ifdef MULTI_ASSIGNMENT_VARIABLES
WokenGoals = TrailTerm(ptr++);
@ -1071,13 +1076,17 @@ mark_variable(CELL_PTR current)
unsigned int arity;
begin:
ccur = *current;
if (MARKED_PTR(current)) {
POP_CONTINUATION();
}
MARK(current);
total_marked++;
if (current >= H0 && current < H) {
total_marked++;
if (current < HGEN)
total_oldies++;
}
PUSH_POINTER(current);
ccur = *current;
next = GET_NEXT(ccur);
if (IsVarTerm(ccur)) {
@ -1086,6 +1095,7 @@ mark_variable(CELL_PTR current)
CELL cnext;
/* do variable shunting between variables in the global */
cnext = *next;
if (!MARKED_PTR(next)) {
if (IsVarTerm(cnext) && (CELL)next == cnext) {
/* new global variable to new global variable */
@ -1116,7 +1126,11 @@ mark_variable(CELL_PTR current)
UNMARK(current);
#endif
*current = cnext;
total_marked--;
if (current >= H0 && current < H) {
total_marked--;
if (current < HGEN)
total_oldies--;
}
POP_POINTER();
} else {
#ifdef INSTRUMENT_GC
@ -1133,7 +1147,11 @@ mark_variable(CELL_PTR current)
#if GC_NO_TAGS
UNMARK(current);
#endif
total_marked--;
if (current >= H0 && current < H) {
total_marked--;
if (current < HGEN)
total_oldies--;
}
POP_POINTER();
} else
#endif
@ -1207,6 +1225,9 @@ mark_variable(CELL_PTR current)
#if GC_NO_TAGS
MARK(next+2);
#endif
if (next >= H0 && next < HGEN) {
total_oldies+=3;
}
total_marked += 3;
PUSH_POINTER(next);
PUSH_POINTER(next+1);
@ -1214,6 +1235,9 @@ mark_variable(CELL_PTR current)
POP_CONTINUATION();
case (CELL)FunctorDouble:
MARK(next);
if (next >= H0 && next < HGEN) {
total_oldies+=2+SIZEOF_DOUBLE/SIZEOF_LONG_INT;
}
total_marked += 2+SIZEOF_DOUBLE/SIZEOF_LONG_INT;
PUSH_POINTER(next);
PUSH_POINTER(next+1);
@ -1231,6 +1255,11 @@ mark_variable(CELL_PTR current)
case (CELL)FunctorBigInt:
MARK(next);
/* size is given by functor + friends */
if (next >= H0 && next < HGEN) {
total_oldies+=2+
(sizeof(MP_INT)+
(((MP_INT *)(next+1))->_mp_alloc*sizeof(mp_limb_t)))/CellSize;
}
total_marked += 2+
(sizeof(MP_INT)+
(((MP_INT *)(next+1))->_mp_alloc*sizeof(mp_limb_t)))/CellSize;
@ -1260,6 +1289,9 @@ mark_variable(CELL_PTR current)
arity = ArityOfFunctor((Functor)(cnext));
MARK(next);
++total_marked;
if (next >= H0 && next < HGEN) {
++total_oldies;
}
PUSH_POINTER(next);
current = next+1;
PUSH_CONTINUATION(current+1,arity-1);
@ -1310,7 +1342,6 @@ mark_external_reference(CELL *ptr) {
CELL_PTR *old = iptop;
#endif
mark_variable(ptr);
total_marked--;
POPSWAP_POINTER(old);
} else {
MARK(ptr);
@ -1327,7 +1358,6 @@ mark_external_reference2(CELL *ptr) {
CELL_PTR *old = iptop;
#endif
mark_variable(ptr);
total_marked--;
POPSWAP_POINTER(old);
} else {
mark_code(ptr,next);
@ -2746,15 +2776,17 @@ update_relocation_chain(CELL_PTR current, CELL_PTR dest)
#if GC_NO_TAGS
int rmarked = RMARKED(current);
UNRMARK(current);
while (rmarked) {
CELL current_tag;
next = GET_NEXT(ccur);
current_tag = TAG(ccur);
ccur = *next;
rmarked = RMARKED(next);
rmarked = RMARKED(next);
UNRMARK(next);
*next = (CELL) dest | current_tag;
/* UNRMARK(next); we are not going to use this */
}
*current = ccur;
#elif TAGS_FAST_OPS
while (RMARKED(current)) {
register CELL cnext;
@ -2839,34 +2871,6 @@ set_next_hb(choiceptr gc_B)
}
}
static void
fast_compact(CELL *current)
{
/* all cells are marked */
CELL_PTR top = current;
for (; current >= H0; current--) {
CELL ccell = *current;
CELL_PTR next;
if (
IN_BETWEEN(EndSpecials, ccell, MAX_SPECIALS_TAG) /* two first pages */
&& IsVarTerm(ccell)
) {
int nofcells = (UNMARK_CELL(*current)-EndSpecials) / sizeof(CELL);
current -= nofcells ;
ccell = *current;
}
update_relocation_chain(current, current);
next = GET_NEXT(ccell);
if (next > top && next < H) {
/* push into reloc. */
into_relocation_chain(current, next);
}
UNMARK(current);
}
}
/*
* move marked objects on the heap upwards over unmarked objects, and reset
* all pointers to point to new locations
@ -2895,21 +2899,10 @@ compact_heap(void)
gl_depfr = LOCAL_top_dep_fr;
#endif /* TABLING */
dest = (CELL_PTR) H0 + total_marked - 1;
for (current = H - 1; current >= start_from; current--) {
if (MARKED_PTR(current)) {
CELL ccell = UNMARK_CELL(*current);
if (FALSE && current == dest) {
#ifdef DEBUG
found_marked+=1+(current-H0);
#endif /* DEBUG */
fast_compact(current);
start_from = current+1;
if (in_garbage > 0) {
current[1] = in_garbage;
in_garbage = 0;
}
break;
}
if (
IN_BETWEEN(EndSpecials, ccell, MAX_SPECIALS_TAG) /* two first pages */
&& IsVarTerm(ccell)
@ -3312,6 +3305,24 @@ marking_phase(tr_fr_ptr old_TR, CELL *current_env, yamop *curp, CELL *max)
#endif
}
static void
sweep_oldgen(CELL *max, CELL *base)
{
CELL *ptr = base;
long int nof = 0;
while (ptr < max) {
if (MARKED_PTR(ptr)) {
nof++;
UNMARK(ptr);
if (HEAP_PTR(*ptr)) {
into_relocation_chain(ptr, GET_NEXT(*ptr));
}
}
ptr++;
}
/* fprintf(stderr,"found %d, %p-%p\n", nof, base, max); */
}
#ifdef COROUTINING
static void
sweep_delays(CELL *max)
@ -3338,6 +3349,23 @@ sweep_delays(CELL *max)
static void
compaction_phase(tr_fr_ptr old_TR, CELL *current_env, yamop *curp, CELL *max)
{
CELL *CurrentH0 = NULL;
int icompact = (iptop < (CELL_PTR *)ASP && 10*total_marked < H-H0);
if (icompact) {
/* we are going to reuse the total space */
if (HGEN != H0) {
/* undo optimisation */
total_marked += total_oldies;
}
} else {
if (HGEN != H0) {
CurrentH0 = H0;
H0 = HGEN;
sweep_oldgen(HGEN, CurrentH0);
}
}
#ifdef COROUTINING
sweep_delays(max);
#endif
@ -3345,19 +3373,25 @@ compaction_phase(tr_fr_ptr old_TR, CELL *current_env, yamop *curp, CELL *max)
sweep_choicepoints(B);
sweep_trail(B, old_TR);
#ifdef HYBRID_SCHEME
if (icompact) {
#ifdef DEBUG
if (total_marked
if (total_marked
#ifdef COROUTINING
-total_smarked
-total_smarked
#endif
!= iptop-(CELL_PTR *)H && iptop < (CELL_PTR *)ASP -1024)
fprintf(Yap_stderr,"%% Oops on iptop-H (%ld) vs %ld\n", (unsigned long int)(iptop-(CELL_PTR *)H), total_marked);
!= iptop-(CELL_PTR *)H && iptop < (CELL_PTR *)ASP -1024)
fprintf(Yap_stderr,"%% Oops on iptop-H (%ld) vs %ld\n", (unsigned long int)(iptop-(CELL_PTR *)H), total_marked);
#endif
if (iptop < (CELL_PTR *)ASP && 10*total_marked < H-H0) {
#ifdef INSTRUMENT_GC
#if DEBUGX
int effectiveness = (((H-H0)-total_marked)*100)/(H-H0);
fprintf(Yap_stderr,"%% using pointers (%d)\n", effectiveness);
#endif
if (CurrentH0) {
H0 = CurrentH0;
HGEN = H0;
total_marked += total_oldies;
CurrentH0 = NULL;
}
quicksort((CELL_PTR *)H, 0, (iptop-(CELL_PTR *)H)-1);
adjust_cp_hbs();
icompact_heap();
@ -3375,6 +3409,9 @@ compaction_phase(tr_fr_ptr old_TR, CELL *current_env, yamop *curp, CELL *max)
#endif
compact_heap();
}
if (CurrentH0) {
H0 = CurrentH0;
}
}
static Int
@ -3385,7 +3422,7 @@ do_gc(Int predarity, CELL *current_env, yamop *nextop)
tr_fr_ptr old_TR = NULL;
UInt m_time, c_time, time_start, gc_time;
CELL *max;
Int effectiveness;
Int effectiveness, tot;
int gc_trace;
if (setjmp(Yap_gc_restore) == 2) {
@ -3472,6 +3509,7 @@ do_gc(Int predarity, CELL *current_env, yamop *nextop)
#endif
time_start = Yap_cputime();
total_marked = 0;
total_oldies = 0;
#ifdef COROUTING
total_smarked = 0;
#endif
@ -3499,22 +3537,33 @@ do_gc(Int predarity, CELL *current_env, yamop *nextop)
iptop = (CELL_PTR *)H;
#endif
/* get the number of active registers */
HGEN = H0+IntegerOfTerm(Yap_ReadTimedVar(GcGeneration));
/* fprintf(stderr,"HGEN is %ld, %p, %p/%p\n", IntegerOfTerm(Yap_ReadTimedVar(GcGeneration)), HGEN, H,H0);*/
YAPEnterCriticalSection();
OldTR = (tr_fr_ptr)(old_TR = TR);
push_registers(predarity, nextop);
marking_phase(old_TR, current_env, nextop, max);
if (total_oldies > ((HGEN-H0)*8)/10) {
total_marked -= total_oldies;
tot = total_marked+(HGEN-H0);
} else {
HGEN = H0;
tot = total_marked;
}
m_time = Yap_cputime();
gc_time = m_time-time_start;
if (heap_cells) {
if (heap_cells > 1000000)
effectiveness = (heap_cells-total_marked)/(heap_cells/100);
effectiveness = (heap_cells-tot)/(heap_cells/100);
else
effectiveness = 100*(heap_cells-total_marked)/heap_cells;
effectiveness = 100*(heap_cells-tot)/heap_cells;
} else
effectiveness = 0;
if (gc_verbose) {
fprintf(Yap_stderr, "%% Mark: Recovered %ld cells of %ld (%ld%%) in %g sec\n",
(long int)(heap_cells-total_marked), (long int)heap_cells, (long int)effectiveness, (double)(m_time-time_start)/1000);
(long int)tot, (long int)heap_cells, (long int)effectiveness, (double)(m_time-time_start)/1000);
if (HGEN-H0)
fprintf(Yap_stderr,"%% previous generation has size %lu, with %lu (%ld%%) unmarked\n", HGEN-H0, (HGEN-H0)-total_oldies, 100*((HGEN-H0)-total_oldies)/(HGEN-H0));
#ifdef INSTRUMENT_GC
{
int i;
@ -3523,7 +3572,7 @@ do_gc(Int predarity, CELL *current_env, yamop *nextop)
fprintf(Yap_stderr, "%% chain[%d]=%lu\n", i, chain[i]);
}
}
put_type_info((unsigned long int)total_marked);
put_type_info((unsigned long int)tot);
fprintf(Yap_stderr,"%% %lu/%ld before and %lu/%ld after\n", old_vars, (unsigned long int)(B->cp_h-H0), new_vars, (unsigned long int)(H-B->cp_h));
fprintf(Yap_stderr,"%% %ld choicepoints\n", num_bs);
}
@ -3535,13 +3584,15 @@ do_gc(Int predarity, CELL *current_env, yamop *nextop)
pop_registers(predarity, nextop);
TR = new_TR;
YAPLeaveCriticalSection();
/* fprintf(Yap_stderr,"NEW HGEN %ld (%ld)\n", H-H0, HGEN-H0);*/
Yap_UpdateTimedVar(GcGeneration, MkIntegerTerm(H-H0));
c_time = Yap_cputime();
if (gc_verbose) {
fprintf(Yap_stderr, "%% Compress: took %g sec\n", (double)(c_time-time_start)/1000);
}
gc_time += (c_time-time_start);
TotGcTime += gc_time;
TotGcRecovered += heap_cells-total_marked;
TotGcRecovered += heap_cells-tot;
if (gc_verbose) {
fprintf(Yap_stderr, "%% GC %d took %g sec, total of %g sec doing GC so far.\n", GcCalls, (double)gc_time/1000, (double)TotGcTime/1000);
fprintf(Yap_stderr, "%% Left %ld cells free in stacks.\n",

View File

@ -417,6 +417,7 @@ save_regs(int mode)
#ifdef DEPTH_LIMIT
putout(DEPTH);
#endif
putout(GcGeneration);
}
/* The operand base */
putcellptr(CellPtr(XREGS));
@ -812,6 +813,9 @@ get_regs(int flag)
if (Yap_ErrorMessage)
return -1;
#endif
GcGeneration = get_cell();
if (Yap_ErrorMessage)
return -1;
}
/* Get the old bases */
OldXREGS = get_cellptr();

View File

@ -120,8 +120,6 @@ low_level_trace(yap_low_level_port port, PredEntry *pred, CELL *args)
/* extern int gc_calls; */
vsc_count++;
if (vsc_count < 487000)
return;
#ifdef COMMENTED
// if (vsc_count == 218280)
// vsc_xstop = 1;

View File

@ -10,7 +10,7 @@
* File: Heap.h *
* mods: *
* comments: Heap Init Structure *
* version: $Id: Heap.h,v 1.83 2005-09-09 17:24:39 vsc Exp $ *
* version: $Id: Heap.h,v 1.84 2005-09-21 03:49:33 vsc Exp $ *
*************************************************************************/
/* information that can be stored in Code Space */
@ -86,6 +86,7 @@ typedef struct worker_local_struct {
Term atts_mutable_list;
#endif
/* gc_stuff */
Term gc_generation; /* global stack limit at last generation */
unsigned int gc_calls; /* number of times GC has been called */
Int tot_gc_time; /* total time spent in GC */
Int tot_gc_recovered; /* number of heap objects in all garbage collections */
@ -732,6 +733,7 @@ struct various_codes *Yap_heap_regs;
#define MutableList Yap_heap_regs->wl[worker_id].mutable_list
#define AttsMutableList Yap_heap_regs->wl[worker_id].atts_mutable_list
#endif
#define GcGeneration Yap_heap_regs->wl[worker_id].gc_generation
#define GcCalls Yap_heap_regs->wl[worker_id].gc_calls
#define TotGcTime Yap_heap_regs->wl[worker_id].tot_gc_time
#define TotGcRecovered Yap_heap_regs->wl[worker_id].tot_gc_recovered
@ -769,6 +771,7 @@ struct various_codes *Yap_heap_regs;
#define MutableList Yap_heap_regs->wl.mutable_list
#define AttsMutableList Yap_heap_regs->wl.atts_mutable_list
#endif
#define GcGeneration Yap_heap_regs->wl.gc_generation
#define GcCalls Yap_heap_regs->wl.gc_calls
#define TotGcTime Yap_heap_regs->wl.tot_gc_time
#define TotGcRecovered Yap_heap_regs->wl.tot_gc_recovered