fix garbage collector to handle multi-assigned variables and to not mess around

with cp_tr fields.


git-svn-id: https://yap.svn.sf.net/svnroot/yap/trunk@1606 b08c6af1-5177-4d33-ba66-4b1c6b8b522a
This commit is contained in:
vsc 2006-04-21 21:50:33 +00:00
parent 9c12627e84
commit 9cbe63778e
3 changed files with 76 additions and 43 deletions

View File

@ -149,26 +149,17 @@ static rb_red_blk_node *db_root, *db_nil;
static void static void
gc_growtrail(int committed) gc_growtrail(int committed)
{ {
#if !GC_TAGS
YAPLeaveCriticalSection();
#endif
#if USE_SYSTEM_MALLOC #if USE_SYSTEM_MALLOC
TR = OldTR; TR = OldTR;
#endif save_machine_regs();
longjmp(Yap_gc_restore, 2);
#else
if (!Yap_growtrail(64 * 1024L, TRUE)) { if (!Yap_growtrail(64 * 1024L, TRUE)) {
/* could not find more trail */ /* could not find more trail */
longjmp(Yap_gc_restore, 2);
}
#if USE_SYSTEM_MALLOC
#if !GC_NO_TAGS
if (committed) {
save_machine_regs(); save_machine_regs();
longjmp(Yap_gc_restore, 2); longjmp(Yap_gc_restore, 2);
} }
#endif #endif
save_machine_regs();
longjmp(Yap_gc_restore, 1);
#endif
} }
@ -1640,8 +1631,21 @@ mark_trail(tr_fr_ptr trail_ptr, tr_fr_ptr trail_base, CELL *gc_H, choiceptr gc_B
value. value.
*/ */
if (cptr < (CELL *)gc_B && cptr >= gc_H) {
goto remove_trash_entry;
}
if (!gc_lookup_ma_var(cptr, trail_base)) { if (!gc_lookup_ma_var(cptr, trail_base)) {
/* check whether this is the first time we see it*/ /* check whether this is the first time we see it*/
Term t0 = TrailTerm(trail_base+1);
if (!IsAtomicTerm(t0)) {
CELL *next = GET_NEXT(t0);
/* check if we have a garbage entry, where we are setting a
pointer to ourselves. */
if (next < (CELL *)gc_B && next >= gc_H) {
goto remove_trash_entry;
}
}
if (HEAP_PTR(trail_cell)) { if (HEAP_PTR(trail_cell)) {
/* fool the gc into thinking this is a variable */ /* fool the gc into thinking this is a variable */
TrailTerm(trail_base) = (CELL)cptr; TrailTerm(trail_base) = (CELL)cptr;
@ -1668,6 +1672,7 @@ mark_trail(tr_fr_ptr trail_ptr, tr_fr_ptr trail_base, CELL *gc_H, choiceptr gc_B
#endif #endif
} }
} else { } else {
remove_trash_entry:
/* we can safely ignore this little monster */ /* we can safely ignore this little monster */
discard_trail_entries += 3; discard_trail_entries += 3;
RESET_VARIABLE(&TrailTerm(trail_base)); RESET_VARIABLE(&TrailTerm(trail_base));
@ -1806,16 +1811,8 @@ mark_choicepoints(register choiceptr gc_B, tr_fr_ptr saved_TR, int very_verbose)
} }
{ {
/* find out how many cells are still alive in the trail */ /* find out how many cells are still alive in the trail */
#ifndef FROZEN_STACKS
UInt d0 = discard_trail_entries, diff, orig;
orig = saved_TR-gc_B->cp_tr;
#endif
mark_trail(saved_TR, gc_B->cp_tr, gc_B->cp_h, gc_B); mark_trail(saved_TR, gc_B->cp_tr, gc_B->cp_h, gc_B);
saved_TR = gc_B->cp_tr; saved_TR = gc_B->cp_tr;
#ifndef FROZEN_STACKS
diff = discard_trail_entries-d0;
gc_B->cp_tr = (tr_fr_ptr)(orig-diff);
#endif /* FROZEN_STACKS */
} }
if (opnum == _or_else || opnum == _or_last) { if (opnum == _or_else || opnum == _or_last) {
/* ; choice point */ /* ; choice point */
@ -2191,17 +2188,44 @@ sweep_trail(choiceptr gc_B, tr_fr_ptr old_TR)
#endif #endif
#ifndef FROZEN_STACKS #ifndef FROZEN_STACKS
/*
adjust cp_tr pointers,
we don't compress TR if we have freeze.
*/
{ {
Int size = old_TR-(tr_fr_ptr)Yap_TrailBase; choiceptr current = gc_B;
size -= discard_trail_entries; choiceptr next = gc_B->cp_b;
while (gc_B != NULL) { tr_fr_ptr source, dest;
size -= (UInt)(gc_B->cp_tr);
gc_B->cp_tr = (tr_fr_ptr)Yap_TrailBase+size; /* invert cp ptrs */
gc_B = gc_B->cp_b; current->cp_b = NULL;
while (next) {
choiceptr n = next;
next = n->cp_b;
n->cp_b = current;
current = n;
}
next = current;
current = NULL;
/* next, clean trail */
source = dest = (tr_fr_ptr)Yap_TrailBase;
while (source < old_TR) {
while (next && source == next->cp_tr) {
choiceptr b = next;
b->cp_tr = dest;
next = b->cp_b;
b->cp_b = current;
current = b;
}
CELL trail_cell = TrailTerm(source);
if (trail_cell != (CELL)source) {
dest++;
}
source++;
}
while (next) {
choiceptr b = next;
b->cp_tr = dest;
next = b->cp_b;
b->cp_b = current;
current = b;
} }
} }
#endif /* FROZEN_STACKS */ #endif /* FROZEN_STACKS */
@ -3398,23 +3422,23 @@ marking_phase(tr_fr_ptr old_TR, CELL *current_env, yamop *curp, CELL *max)
#ifdef EASY_SHUNTING #ifdef EASY_SHUNTING
current_B = B; current_B = B;
prev_HB = H;
#endif #endif
init_dbtable(old_TR); init_dbtable(old_TR);
#ifdef EASY_SHUNTING #ifdef EASY_SHUNTING
sTR0 = (tr_fr_ptr)db_vec; sTR0 = (tr_fr_ptr)db_vec;
sTR = (tr_fr_ptr)db_vec; sTR = (tr_fr_ptr)db_vec;
/* make sure we set HB before we do any variable shunting!!! */ /* make sure we set HB before we do any variable shunting!!! */
HB = H;
#else #else
cont_top0 = (cont *)db_vec; cont_top0 = (cont *)db_vec;
#endif #endif
cont_top = (cont *)db_vec; cont_top = (cont *)db_vec;
/* These two must be marked first so that our trail optimisation won't lose
values */
mark_regs(old_TR); /* active registers & trail */
#ifdef COROUTINING #ifdef COROUTINING
mark_delays(max); mark_delays(max);
#endif #endif
/* These two must be marked first so that our trail optimisation won't lose
values */
mark_regs(old_TR); /* active registers & trail */
/* active environments */ /* active environments */
mark_environments(current_env, EnvSize(curp), EnvBMap((CELL *)curp)); mark_environments(current_env, EnvSize(curp), EnvBMap((CELL *)curp));
mark_choicepoints(B, old_TR, is_gc_very_verbose()); /* choicepoints, and environs */ mark_choicepoints(B, old_TR, is_gc_very_verbose()); /* choicepoints, and environs */
@ -3665,6 +3689,12 @@ do_gc(Int predarity, CELL *current_env, yamop *nextop)
return 0; return 0;
#endif #endif
} else { } else {
total_marked = 0;
total_oldies = 0;
#ifdef COROUTING
total_smarked = 0;
#endif
discard_trail_entries = 0;
current_env = (CELL *)*ASP; current_env = (CELL *)*ASP;
ASP++; ASP++;
#if COROUTINING #if COROUTINING
@ -3683,9 +3713,6 @@ do_gc(Int predarity, CELL *current_env, yamop *nextop)
HGEN = H0; HGEN = H0;
} }
/* fprintf(stderr,"HGEN is %ld, %p, %p/%p\n", IntegerOfTerm(Yap_ReadTimedVar(GcGeneration)), HGEN, H,H0);*/ /* fprintf(stderr,"HGEN is %ld, %p, %p/%p\n", IntegerOfTerm(Yap_ReadTimedVar(GcGeneration)), HGEN, H,H0);*/
#if !GC_TAGS
YAPEnterCriticalSection();
#endif
OldTR = (tr_fr_ptr)(old_TR = TR); OldTR = (tr_fr_ptr)(old_TR = TR);
push_registers(predarity, nextop); push_registers(predarity, nextop);
marking_phase(old_TR, current_env, nextop, max); marking_phase(old_TR, current_env, nextop, max);
@ -3732,9 +3759,6 @@ do_gc(Int predarity, CELL *current_env, yamop *nextop)
TR = old_TR; TR = old_TR;
pop_registers(predarity, nextop); pop_registers(predarity, nextop);
TR = new_TR; TR = new_TR;
#if !GC_TAGS
YAPLeaveCriticalSection();
#endif
/* fprintf(Yap_stderr,"NEW HGEN %ld (%ld)\n", H-H0, HGEN-H0);*/ /* fprintf(Yap_stderr,"NEW HGEN %ld (%ld)\n", H-H0, HGEN-H0);*/
Yap_UpdateTimedVar(GcGeneration, MkIntegerTerm(H-H0)); Yap_UpdateTimedVar(GcGeneration, MkIntegerTerm(H-H0));
Yap_UpdateTimedVar(GcPhase, MkIntegerTerm(GcCurrentPhase)); Yap_UpdateTimedVar(GcPhase, MkIntegerTerm(GcCurrentPhase));

View File

@ -137,6 +137,10 @@ low_level_trace(yap_low_level_port port, PredEntry *pred, CELL *args)
LOCK(Yap_heap_regs->low_level_trace_lock); LOCK(Yap_heap_regs->low_level_trace_lock);
sc = Yap_heap_regs; sc = Yap_heap_regs;
vsc_count++; vsc_count++;
// if (vsc_count < 13600) {
// UNLOCK(Yap_heap_regs->low_level_trace_lock);
// return;
// }
#ifdef COMMENTED #ifdef COMMENTED
// if (vsc_count == 218280) // if (vsc_count == 218280)
// vsc_xstop = 1; // vsc_xstop = 1;

View File

@ -16,6 +16,11 @@
<h2>Yap-5.1.2:</h2> <h2>Yap-5.1.2:</h2>
<ul> <ul>
<li> FIXED: garbage collector should no rewrite cp_tr fields until
after marking (obs Paulo Moura).</li>
<li> FIXED: garbage collector was allowing garbage trail entries for
multi-assignment variables. Namely, old var value might point to new space
(obs Paulo Moura).</li>
<li> FIXED: thread aliases were being cleaned up just after being <li> FIXED: thread aliases were being cleaned up just after being
installed (obs Paulo Moura).</li> installed (obs Paulo Moura).</li>
<li> FIXED: rb_partial_map was broken.</li> <li> FIXED: rb_partial_map was broken.</li>