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)
|
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
|
||||||
|
@ -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
|
||||||
|
Reference in New Issue
Block a user