improve error handling during garbage collection.

git-svn-id: https://yap.svn.sf.net/svnroot/yap/trunk@1475 b08c6af1-5177-4d33-ba66-4b1c6b8b522a
This commit is contained in:
vsc 2005-12-07 12:55:31 +00:00
parent 5c2e06ad50
commit 147c2cee15
2 changed files with 62 additions and 37 deletions

View File

@ -103,6 +103,7 @@ static void
gc_growtrail(int committed) gc_growtrail(int committed)
{ {
#if THREADS #if THREADS
YAPLeaveCriticalSection();
longjmp(Yap_gc_restore, 2); longjmp(Yap_gc_restore, 2);
#endif #endif
#if USE_SYSTEM_MALLOC #if USE_SYSTEM_MALLOC
@ -524,6 +525,7 @@ typedef enum {
typedef struct db_entry { typedef struct db_entry {
CODEADDR val; CODEADDR val;
db_entry_type db_type; db_entry_type db_type;
int in_use;
struct db_entry *left; struct db_entry *left;
CODEADDR lim; CODEADDR lim;
struct db_entry *right; struct db_entry *right;
@ -535,6 +537,7 @@ typedef struct RB_red_blk_node {
CODEADDR key; CODEADDR key;
CODEADDR lim; CODEADDR lim;
db_entry_type db_type; db_entry_type db_type;
int in_use;
int red; /* if red=0 then the node is black */ int red; /* if red=0 then the node is black */
struct RB_red_blk_node* left; struct RB_red_blk_node* left;
struct RB_red_blk_node* right; struct RB_red_blk_node* right;
@ -758,6 +761,7 @@ RBTreeInsert(CODEADDR key, CODEADDR end, db_entry_type db_type) {
x->key=key; x->key=key;
x->lim=end; x->lim=end;
x->db_type=db_type; x->db_type=db_type;
x->in_use = FALSE;
TreeInsertHelp(x); TreeInsertHelp(x);
newNode=x; newNode=x;
@ -832,29 +836,28 @@ find_ref_in_dbtable(CODEADDR entry)
return current; return current;
} }
/* find an element in the dbentries table */
static void
mark_ref_in_use(DBRef ref)
{
rb_red_blk_node *el = find_ref_in_dbtable((CODEADDR)ref);
el->in_use = TRUE;
}
static int
ref_in_use(DBRef ref)
{
rb_red_blk_node *el = find_ref_in_dbtable((CODEADDR)ref);
return el->in_use;
}
static void static void
mark_db_fixed(CELL *ptr) { mark_db_fixed(CELL *ptr) {
rb_red_blk_node *el; rb_red_blk_node *el;
el = find_ref_in_dbtable((CODEADDR)ptr); el = find_ref_in_dbtable((CODEADDR)ptr);
if (el != db_nil) { if (el != db_nil) {
switch (el->db_type) { el->in_use = TRUE;
case db_entry:
((DBRef)(el->key))->Flags |= GcFoundMask;
break;
case cl_entry:
((DynamicClause *)(el->key))->ClFlags |= GcFoundMask;
break;
case lcl_entry:
((LogUpdClause *)(el->key))->ClFlags |= GcFoundMask;
break;
case li_entry:
((LogUpdIndex *)(el->key))->ClFlags |= GcFoundMask;
break;
case dcl_entry:
((DeadClause *)(el->key))->ClFlags |= GcFoundMask;
break;
}
} }
} }
@ -1236,7 +1239,7 @@ mark_variable(CELL_PTR current)
*current = MkDBRefTerm(DBErasedMarker); *current = MkDBRefTerm(DBErasedMarker);
MARK(current); MARK(current);
} else { } else {
tref->Flags |= GcFoundMask; mark_ref_in_use(tref);
} }
} else { } else {
mark_db_fixed(next); mark_db_fixed(next);
@ -1354,7 +1357,7 @@ mark_code(CELL_PTR ptr, CELL *next)
tref->Parent->KindOfPE & LogUpdDBBit) { tref->Parent->KindOfPE & LogUpdDBBit) {
*ptr = MkDBRefTerm(DBErasedMarker); *ptr = MkDBRefTerm(DBErasedMarker);
} else { } else {
tref->Flags |= GcFoundMask; mark_ref_in_use(tref);
} }
} else { } else {
mark_db_fixed(next); mark_db_fixed(next);
@ -1863,9 +1866,9 @@ mark_choicepoints(register choiceptr gc_B, tr_fr_ptr saved_TR, int very_verbose)
DBRef ref; DBRef ref;
B = gc_B; B = gc_B;
ref = (DBRef)EXTRA_CBACK_ARG(3,1); ref = (DBRef)EXTRA_CBACK_ARG(3,1);
if (IsVarTerm((CELL)ref)) if (IsVarTerm((CELL)ref)) {
ref->Flags |= GcFoundMask; mark_ref_in_use(ref);
else { } else {
if (ONCODE((CELL)ref)) { if (ONCODE((CELL)ref)) {
mark_db_fixed(RepAppl((CELL)ref)); mark_db_fixed(RepAppl((CELL)ref));
} }
@ -2006,7 +2009,7 @@ mark_choicepoints(register choiceptr gc_B, tr_fr_ptr saved_TR, int very_verbose)
case _profiled_retry_and_mark: case _profiled_retry_and_mark:
case _count_retry_and_mark: case _count_retry_and_mark:
case _retry_and_mark: case _retry_and_mark:
ClauseCodeToDynamicClause(gc_B->cp_ap)->ClFlags |= GcFoundMask; mark_ref_in_use((DBRef)ClauseCodeToDynamicClause(gc_B->cp_ap));
case _retry2: case _retry2:
nargs = 2; nargs = 2;
break; break;
@ -2215,7 +2218,7 @@ sweep_trail(choiceptr gc_B, tr_fr_ptr old_TR)
flags = *pt0; flags = *pt0;
#ifdef DEBUG #ifdef DEBUG
hp_entrs++; hp_entrs++;
if (!FlagOn(GcFoundMask, flags)) { if (!ref_in_use((DBRef)pt0)) {
hp_not_in_use++; hp_not_in_use++;
if (!FlagOn(DBClMask, flags)) { if (!FlagOn(DBClMask, flags)) {
code_entries++; code_entries++;
@ -2229,7 +2232,7 @@ sweep_trail(choiceptr gc_B, tr_fr_ptr old_TR)
} }
} }
#endif #endif
if (!FlagOn(GcFoundMask, flags)) { if (!ref_in_use((DBRef)pt0)) {
if (FlagOn(DBClMask, flags)) { if (FlagOn(DBClMask, flags)) {
DBRef dbr = (DBRef) ((CELL)pt0 - (CELL) &(((DBRef) NIL)->Flags)); DBRef dbr = (DBRef) ((CELL)pt0 - (CELL) &(((DBRef) NIL)->Flags));
dbr->Flags &= ~InUseMask; dbr->Flags &= ~InUseMask;
@ -2283,8 +2286,6 @@ sweep_trail(choiceptr gc_B, tr_fr_ptr old_TR)
} }
RESET_VARIABLE(&TrailTerm(dest)); RESET_VARIABLE(&TrailTerm(dest));
discard_trail_entries++; discard_trail_entries++;
} else {
*pt0 = ResetFlag(GcFoundMask, flags);
} }
#if MULTI_ASSIGNMENT_VARIABLES #if MULTI_ASSIGNMENT_VARIABLES
} else { } else {
@ -2394,13 +2395,12 @@ sweep_trail(choiceptr gc_B, tr_fr_ptr old_TR)
cptr = &(DeadClauses); cptr = &(DeadClauses);
cl = DeadClauses; cl = DeadClauses;
while (cl != NULL) { while (cl != NULL) {
if (!(cl->ClFlags & GcFoundMask)) { if (!ref_in_use((DBRef)cl)) {
char *ocl = (char *)cl; char *ocl = (char *)cl;
cl = cl->NextCl; cl = cl->NextCl;
*cptr = cl; *cptr = cl;
Yap_FreeCodeSpace(ocl); Yap_FreeCodeSpace(ocl);
} else { } else {
cl->ClFlags &= ~GcFoundMask;
cptr = &(cl->NextCl); cptr = &(cl->NextCl);
cl = cl->NextCl; cl = cl->NextCl;
} }
@ -3490,21 +3490,17 @@ compaction_phase(tr_fr_ptr old_TR, CELL *current_env, yamop *curp, CELL *max)
} }
} }
static Int static int
do_gc(Int predarity, CELL *current_env, yamop *nextop) do_gc(Int predarity, CELL *current_env, yamop *nextop)
{ {
Int heap_cells; Int heap_cells;
int gc_verbose; int gc_verbose;
tr_fr_ptr old_TR = NULL; volatile tr_fr_ptr old_TR = NULL;
UInt m_time, c_time, time_start, gc_time; UInt m_time, c_time, time_start, gc_time;
CELL *max; CELL *max;
Int effectiveness, tot; Int effectiveness, tot;
int gc_trace; int gc_trace;
if (setjmp(Yap_gc_restore) == 2) {
/* we cannot recover, fail system */
Yap_Error(OUT_OF_TRAIL_ERROR,TermNil,"could not expand trail during garbage collection");
}
heap_cells = H-H0; heap_cells = H-H0;
gc_verbose = is_gc_verbose(); gc_verbose = is_gc_verbose();
effectiveness = 0; effectiveness = 0;
@ -3609,6 +3605,32 @@ do_gc(Int predarity, CELL *current_env, yamop *nextop)
memset((void *)bp, 0, alloc_sz); memset((void *)bp, 0, alloc_sz);
} }
#endif /* GC_NO_TAGS */ #endif /* GC_NO_TAGS */
if (setjmp(Yap_gc_restore) == 2) {
/* we cannot recover, fail system */
*--ASP = (CELL)current_env;
TR = OldTR;
if (
#if GC_NO_TAGS
!Yap_growtrail(64 * 1024L, FALSE)
#else
TRUE
#endif
) {
#if GC_NO_TAGS
Yap_Error(OUT_OF_TRAIL_ERROR,TermNil,"out of %lB during gc", 64*1024L);
return -1;
#else
/* try stack expansion, who knows */
return 0;
#endif
} else {
current_env = (CELL *)*ASP;
ASP++;
#if COROUTINING
max = (CELL *)DelayTop();
#endif
}
}
#ifdef HYBRID_SCHEME #ifdef HYBRID_SCHEME
iptop = (CELL_PTR *)H; iptop = (CELL_PTR *)H;
#endif #endif
@ -3772,6 +3794,8 @@ call_gc(UInt gc_lim, Int predarity, CELL *current_env, yamop *nextop)
/* make sure there is a point in collecting the heap */ /* make sure there is a point in collecting the heap */
H-H0 > (LCL0-ASP)/2) { H-H0 > (LCL0-ASP)/2) {
effectiveness = do_gc(predarity, current_env, nextop); effectiveness = do_gc(predarity, current_env, nextop);
if (effectiveness < 0)
return FALSE;
if (effectiveness > 90) { if (effectiveness > 90) {
while (gc_margin < H-H0) while (gc_margin < H-H0)
gc_margin <<= 1; gc_margin <<= 1;
@ -3811,8 +3835,7 @@ Yap_gcl(UInt gc_lim, Int predarity, CELL *current_env, yamop *nextop)
static Int static Int
p_gc(void) p_gc(void)
{ {
do_gc(0, ENV, P); return do_gc(0, ENV, P);
return(TRUE);
} }
void void

View File

@ -16,6 +16,8 @@
<h2>Yap-5.1.0:</h2> <h2>Yap-5.1.0:</h2>
<ul> <ul>
<li> FIXED: heapgc wo tags can handle trail overflows right. </li>
<li> NEW: heapgc wo tags does not write on the collected areas during marking. </li>
<li> FIXED: dif/2 might get into trouble restoring assignments to <li> FIXED: dif/2 might get into trouble restoring assignments to
attributes. </li> attributes. </li>
<li> NEW: Yap_DebugPlWrite and Yap_DebugErrorPutc for those debugging <li> NEW: Yap_DebugPlWrite and Yap_DebugErrorPutc for those debugging