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:
parent
5c2e06ad50
commit
147c2cee15
97
C/heapgc.c
97
C/heapgc.c
@ -103,6 +103,7 @@ static void
|
||||
gc_growtrail(int committed)
|
||||
{
|
||||
#if THREADS
|
||||
YAPLeaveCriticalSection();
|
||||
longjmp(Yap_gc_restore, 2);
|
||||
#endif
|
||||
#if USE_SYSTEM_MALLOC
|
||||
@ -524,6 +525,7 @@ typedef enum {
|
||||
typedef struct db_entry {
|
||||
CODEADDR val;
|
||||
db_entry_type db_type;
|
||||
int in_use;
|
||||
struct db_entry *left;
|
||||
CODEADDR lim;
|
||||
struct db_entry *right;
|
||||
@ -535,6 +537,7 @@ typedef struct RB_red_blk_node {
|
||||
CODEADDR key;
|
||||
CODEADDR lim;
|
||||
db_entry_type db_type;
|
||||
int in_use;
|
||||
int red; /* if red=0 then the node is black */
|
||||
struct RB_red_blk_node* left;
|
||||
struct RB_red_blk_node* right;
|
||||
@ -758,6 +761,7 @@ RBTreeInsert(CODEADDR key, CODEADDR end, db_entry_type db_type) {
|
||||
x->key=key;
|
||||
x->lim=end;
|
||||
x->db_type=db_type;
|
||||
x->in_use = FALSE;
|
||||
|
||||
TreeInsertHelp(x);
|
||||
newNode=x;
|
||||
@ -832,29 +836,28 @@ find_ref_in_dbtable(CODEADDR entry)
|
||||
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
|
||||
mark_db_fixed(CELL *ptr) {
|
||||
rb_red_blk_node *el;
|
||||
|
||||
el = find_ref_in_dbtable((CODEADDR)ptr);
|
||||
if (el != db_nil) {
|
||||
switch (el->db_type) {
|
||||
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;
|
||||
}
|
||||
el->in_use = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1236,7 +1239,7 @@ mark_variable(CELL_PTR current)
|
||||
*current = MkDBRefTerm(DBErasedMarker);
|
||||
MARK(current);
|
||||
} else {
|
||||
tref->Flags |= GcFoundMask;
|
||||
mark_ref_in_use(tref);
|
||||
}
|
||||
} else {
|
||||
mark_db_fixed(next);
|
||||
@ -1354,7 +1357,7 @@ mark_code(CELL_PTR ptr, CELL *next)
|
||||
tref->Parent->KindOfPE & LogUpdDBBit) {
|
||||
*ptr = MkDBRefTerm(DBErasedMarker);
|
||||
} else {
|
||||
tref->Flags |= GcFoundMask;
|
||||
mark_ref_in_use(tref);
|
||||
}
|
||||
} else {
|
||||
mark_db_fixed(next);
|
||||
@ -1863,9 +1866,9 @@ mark_choicepoints(register choiceptr gc_B, tr_fr_ptr saved_TR, int very_verbose)
|
||||
DBRef ref;
|
||||
B = gc_B;
|
||||
ref = (DBRef)EXTRA_CBACK_ARG(3,1);
|
||||
if (IsVarTerm((CELL)ref))
|
||||
ref->Flags |= GcFoundMask;
|
||||
else {
|
||||
if (IsVarTerm((CELL)ref)) {
|
||||
mark_ref_in_use(ref);
|
||||
} else {
|
||||
if (ONCODE((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 _count_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:
|
||||
nargs = 2;
|
||||
break;
|
||||
@ -2215,7 +2218,7 @@ sweep_trail(choiceptr gc_B, tr_fr_ptr old_TR)
|
||||
flags = *pt0;
|
||||
#ifdef DEBUG
|
||||
hp_entrs++;
|
||||
if (!FlagOn(GcFoundMask, flags)) {
|
||||
if (!ref_in_use((DBRef)pt0)) {
|
||||
hp_not_in_use++;
|
||||
if (!FlagOn(DBClMask, flags)) {
|
||||
code_entries++;
|
||||
@ -2229,7 +2232,7 @@ sweep_trail(choiceptr gc_B, tr_fr_ptr old_TR)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (!FlagOn(GcFoundMask, flags)) {
|
||||
if (!ref_in_use((DBRef)pt0)) {
|
||||
if (FlagOn(DBClMask, flags)) {
|
||||
DBRef dbr = (DBRef) ((CELL)pt0 - (CELL) &(((DBRef) NIL)->Flags));
|
||||
dbr->Flags &= ~InUseMask;
|
||||
@ -2283,8 +2286,6 @@ sweep_trail(choiceptr gc_B, tr_fr_ptr old_TR)
|
||||
}
|
||||
RESET_VARIABLE(&TrailTerm(dest));
|
||||
discard_trail_entries++;
|
||||
} else {
|
||||
*pt0 = ResetFlag(GcFoundMask, flags);
|
||||
}
|
||||
#if MULTI_ASSIGNMENT_VARIABLES
|
||||
} else {
|
||||
@ -2394,13 +2395,12 @@ sweep_trail(choiceptr gc_B, tr_fr_ptr old_TR)
|
||||
cptr = &(DeadClauses);
|
||||
cl = DeadClauses;
|
||||
while (cl != NULL) {
|
||||
if (!(cl->ClFlags & GcFoundMask)) {
|
||||
if (!ref_in_use((DBRef)cl)) {
|
||||
char *ocl = (char *)cl;
|
||||
cl = cl->NextCl;
|
||||
*cptr = cl;
|
||||
Yap_FreeCodeSpace(ocl);
|
||||
} else {
|
||||
cl->ClFlags &= ~GcFoundMask;
|
||||
cptr = &(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)
|
||||
{
|
||||
Int heap_cells;
|
||||
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;
|
||||
CELL *max;
|
||||
Int effectiveness, tot;
|
||||
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;
|
||||
gc_verbose = is_gc_verbose();
|
||||
effectiveness = 0;
|
||||
@ -3609,6 +3605,32 @@ do_gc(Int predarity, CELL *current_env, yamop *nextop)
|
||||
memset((void *)bp, 0, alloc_sz);
|
||||
}
|
||||
#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
|
||||
iptop = (CELL_PTR *)H;
|
||||
#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 */
|
||||
H-H0 > (LCL0-ASP)/2) {
|
||||
effectiveness = do_gc(predarity, current_env, nextop);
|
||||
if (effectiveness < 0)
|
||||
return FALSE;
|
||||
if (effectiveness > 90) {
|
||||
while (gc_margin < H-H0)
|
||||
gc_margin <<= 1;
|
||||
@ -3811,8 +3835,7 @@ Yap_gcl(UInt gc_lim, Int predarity, CELL *current_env, yamop *nextop)
|
||||
static Int
|
||||
p_gc(void)
|
||||
{
|
||||
do_gc(0, ENV, P);
|
||||
return(TRUE);
|
||||
return do_gc(0, ENV, P);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
<h2>Yap-5.1.0:</h2>
|
||||
<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
|
||||
attributes. </li>
|
||||
<li> NEW: Yap_DebugPlWrite and Yap_DebugErrorPutc for those debugging
|
||||
|
Reference in New Issue
Block a user