fix garbage collection for delayed variables

git-svn-id: https://yap.svn.sf.net/svnroot/yap/trunk@1038 b08c6af1-5177-4d33-ba66-4b1c6b8b522a
This commit is contained in:
vsc 2004-04-16 20:38:54 +00:00
parent f7a68f97cd
commit d2a4490676

View File

@ -48,8 +48,6 @@ static unsigned long int total_marked; /* number of heap objects marked */
static unsigned long int total_smarked; static unsigned long int total_smarked;
#endif #endif
struct gc_ma_h_entry *live_list;
STATIC_PROTO(Int p_inform_gc, (void)); STATIC_PROTO(Int p_inform_gc, (void));
STATIC_PROTO(Int p_gc, (void)); STATIC_PROTO(Int p_gc, (void));
@ -258,18 +256,10 @@ quicksort(CELL *a[], Int p, Int r)
#define GC_MAVARS_HASH_SIZE 512 #define GC_MAVARS_HASH_SIZE 512
typedef struct gc_ma_h_entry { typedef struct gc_ma_hash_entry_struct {
CELL* addr;
tr_fr_ptr trptr;
struct gc_ma_h_entry* ma_list;
struct gc_ma_h_entry *next;
} gc_ma_h_inner_struct;
extern struct gc_ma_h_entry *live_list;
typedef struct {
UInt timestmp; UInt timestmp;
struct gc_ma_h_entry val; CELL* addr;
struct gc_ma_hash_entry_struct *next;
} gc_ma_hash_entry; } gc_ma_hash_entry;
static gc_ma_hash_entry gc_ma_hash_table[GC_MAVARS_HASH_SIZE]; static gc_ma_hash_entry gc_ma_hash_table[GC_MAVARS_HASH_SIZE];
@ -285,12 +275,12 @@ GC_MAVAR_HASH(CELL *addr) {
#endif #endif
} }
gc_ma_h_inner_struct *gc_ma_h_top; gc_ma_hash_entry *gc_ma_h_top;
static inline struct gc_ma_h_entry * static inline gc_ma_hash_entry *
GC_ALLOC_NEW_MASPACE(void) GC_ALLOC_NEW_MASPACE(void)
{ {
gc_ma_h_inner_struct *new = gc_ma_h_top; gc_ma_hash_entry *new = gc_ma_h_top;
if ((char *)gc_ma_h_top > Yap_TrailTop-1024) if ((char *)gc_ma_h_top > Yap_TrailTop-1024)
Yap_growtrail(64 * 1024L); Yap_growtrail(64 * 1024L);
gc_ma_h_top++; gc_ma_h_top++;
@ -300,47 +290,37 @@ GC_ALLOC_NEW_MASPACE(void)
#else #else
cont_top0 = cont_top; cont_top0 = cont_top;
#endif #endif
return(new); return new;
} }
static inline tr_fr_ptr* static inline gc_ma_hash_entry*
gc_lookup_ma_var(CELL *addr, tr_fr_ptr trp) { gc_lookup_ma_var(CELL *addr, tr_fr_ptr trp) {
unsigned int i = GC_MAVAR_HASH(addr); unsigned int i = GC_MAVAR_HASH(addr);
struct gc_ma_h_entry *nptr, *optr; gc_ma_hash_entry *nptr, *optr = NULL;
if (gc_ma_hash_table[i].timestmp != timestamp) { if (gc_ma_hash_table[i].timestmp != timestamp) {
gc_ma_hash_table[i].timestmp = timestamp; gc_ma_hash_table[i].timestmp = timestamp;
gc_ma_hash_table[i].val.addr = addr; gc_ma_hash_table[i].addr = addr;
gc_ma_hash_table[i].val.next = NULL; gc_ma_hash_table[i].next = NULL;
gc_ma_hash_table[i].val.trptr = trp; return NULL;
gc_ma_hash_table[i].val.ma_list = live_list;
live_list = &(gc_ma_hash_table[i].val);
return(NULL);
} }
if (gc_ma_hash_table[i].val.addr == addr) { nptr = gc_ma_hash_table+i;
return(&(gc_ma_hash_table[i].val.trptr)); while (nptr) {
}
optr = &(gc_ma_hash_table[i].val);
nptr = gc_ma_hash_table[i].val.next;
while (nptr != NULL) {
if (nptr->addr == addr) {
return(&(nptr->trptr));
}
optr = nptr; optr = nptr;
if (nptr->addr == addr) {
return nptr;
}
nptr = nptr->next; nptr = nptr->next;
} }
nptr = GC_ALLOC_NEW_MASPACE(); nptr = GC_ALLOC_NEW_MASPACE();
optr->next = nptr; optr->next = nptr;
nptr->addr = addr; nptr->addr = addr;
nptr->trptr = trp;
nptr->ma_list = live_list;
nptr->next = NULL; nptr->next = NULL;
live_list = nptr; return NULL;
return(NULL);
} }
static inline void static inline void
GC_NEW_MAHASH(gc_ma_h_inner_struct *top) { GC_NEW_MAHASH(gc_ma_hash_entry *top) {
UInt time = ++timestamp; UInt time = ++timestamp;
if (time == 0) { if (time == 0) {
unsigned int i; unsigned int i;
@ -356,7 +336,6 @@ GC_NEW_MAHASH(gc_ma_h_inner_struct *top) {
#else #else
cont_top0 = cont_top; cont_top0 = cont_top;
#endif #endif
live_list = NULL;
} }
#endif #endif
@ -1241,13 +1220,12 @@ mark_trail(tr_fr_ptr trail_ptr, tr_fr_ptr trail_base, CELL *gc_H, choiceptr gc_B
tr_fr_ptr begsTR = NULL, endsTR = NULL; tr_fr_ptr begsTR = NULL, endsTR = NULL;
#endif #endif
cont *old_cont_top0 = cont_top0; cont *old_cont_top0 = cont_top0;
GC_NEW_MAHASH((gc_ma_h_inner_struct *)cont_top0);
while (trail_ptr > trail_base) { GC_NEW_MAHASH((gc_ma_hash_entry *)cont_top0);
while (trail_base < trail_ptr) {
register CELL trail_cell; register CELL trail_cell;
trail_ptr--; trail_cell = TrailTerm(trail_base);
trail_cell = TrailTerm(trail_ptr);
if (IsVarTerm(trail_cell)) { if (IsVarTerm(trail_cell)) {
CELL *hp = (CELL *)trail_cell; CELL *hp = (CELL *)trail_cell;
@ -1260,32 +1238,32 @@ mark_trail(tr_fr_ptr trail_ptr, tr_fr_ptr trail_base, CELL *gc_H, choiceptr gc_B
/* reset to be a variable */ /* reset to be a variable */
RESET_VARIABLE(hp); RESET_VARIABLE(hp);
discard_trail_entries++; discard_trail_entries++;
RESET_VARIABLE(&TrailTerm(trail_ptr)); RESET_VARIABLE(&TrailTerm(trail_base));
#ifdef FROZEN_STACKS #ifdef FROZEN_STACKS
RESET_VARIABLE(&TrailVal(trail_ptr)); RESET_VARIABLE(&TrailVal(trail_base));
#endif #endif
#else #else
/* if I have no early reset I have to follow the trail chain */ /* if I have no early reset I have to follow the trail chain */
mark_external_reference(&TrailTerm(trail_ptr)); mark_external_reference(&TrailTerm(trail_base));
UNMARK(&TrailTerm(trail_ptr)); UNMARK(&TrailTerm(trail_base));
#endif /* EARLY_RESET */ #endif /* EARLY_RESET */
} else if (hp < (CELL *)HeapTop) { } else if (hp < (CELL *)Yap_GlobalBase || hp > (CELL *)Yap_TrailTop) {
/* I decided to allow pointers from the Heap back into the trail. /* I decided to allow pointers from the Heap back into the trail.
The point of doing so is to have dynamic arrays */ The point of doing so is to have dynamic arrays */
mark_external_reference(hp); mark_external_reference(hp);
} else if ((hp < (CELL *)gc_B && hp >= gc_H) || hp > (CELL *)Yap_TrailBase) { } else if ((hp < (CELL *)gc_B && hp >= gc_H) || hp > (CELL *)Yap_TrailBase) {
/* clean the trail, avoid dangling pointers! */ /* clean the trail, avoid dangling pointers! */
RESET_VARIABLE(&TrailTerm(trail_ptr)); RESET_VARIABLE(&TrailTerm(trail_base));
#ifdef FROZEN_STACKS #ifdef FROZEN_STACKS
RESET_VARIABLE(&TrailVal(trail_ptr)); RESET_VARIABLE(&TrailVal(trail_base));
#endif #endif
discard_trail_entries++; discard_trail_entries++;
} else { } else {
if (trail_cell == (CELL)trail_ptr) if (trail_cell == (CELL)trail_base)
discard_trail_entries++; discard_trail_entries++;
#ifdef FROZEN_STACKS #ifdef FROZEN_STACKS
else else
mark_external_reference(&TrailVal(trail_ptr)); mark_external_reference(&TrailVal(trail_base));
#endif #endif
#ifdef EASY_SHUNTING #ifdef EASY_SHUNTING
if (hp < gc_H && hp >= H0) { if (hp < gc_H && hp >= H0) {
@ -1304,7 +1282,7 @@ mark_trail(tr_fr_ptr trail_ptr, tr_fr_ptr trail_base, CELL *gc_H, choiceptr gc_B
endsTR = nsTR; endsTR = nsTR;
cont_top = (cont *)(nsTR+3); cont_top = (cont *)(nsTR+3);
sTR = (tr_fr_ptr)cont_top; sTR = (tr_fr_ptr)cont_top;
gc_ma_h_top = (gc_ma_h_inner_struct *)(nsTR+3); gc_ma_h_top = (gc_ma_hash_entry *)(nsTR+3);
RESET_VARIABLE(cptr); RESET_VARIABLE(cptr);
MARK(cptr); MARK(cptr);
} }
@ -1315,7 +1293,6 @@ mark_trail(tr_fr_ptr trail_ptr, tr_fr_ptr trail_base, CELL *gc_H, choiceptr gc_B
} }
#if MULTI_ASSIGNMENT_VARIABLES #if MULTI_ASSIGNMENT_VARIABLES
else { else {
tr_fr_ptr *lkp;
CELL *cptr = RepAppl(trail_cell); CELL *cptr = RepAppl(trail_cell);
/* This is a bit complex. The idea is that we may have several /* This is a bit complex. The idea is that we may have several
trailings for the same mavar in the same trail segment. Essentially, trailings for the same mavar in the same trail segment. Essentially,
@ -1323,57 +1300,48 @@ mark_trail(tr_fr_ptr trail_ptr, tr_fr_ptr trail_base, CELL *gc_H, choiceptr gc_B
the last entry, or in this case, all but the first entry with the last the last entry, or in this case, all but the first entry with the last
value. value.
Problem: we can only mark when we know it is the *last*.
Solution: we keep a list of all found entries and search in the end
*/ */
if (!(lkp = gc_lookup_ma_var(cptr, trail_ptr))) { if (!gc_lookup_ma_var(cptr, trail_base)) {
/* first time we see it*/
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_ptr) = (CELL)cptr; TrailTerm(trail_base) = (CELL)cptr;
mark_external_reference(&(TrailTerm(trail_ptr))); mark_external_reference(&(TrailTerm(trail_base)));
/* reset the gc to believe the original tag */ /* reset the gc to believe the original tag */
TrailTerm(trail_ptr) = AbsAppl((CELL *)TrailTerm(trail_ptr)); TrailTerm(trail_base) = AbsAppl((CELL *)TrailTerm(trail_base));
}
trail_base++;
mark_external_reference(&(TrailTerm(trail_base)));
trail_base ++;
if (HEAP_PTR(trail_cell)) {
/* fool the gc into thinking this is a variable */
TrailTerm(trail_base) = (CELL)cptr;
mark_external_reference(&(TrailTerm(trail_base)));
/* reset the gc to believe the original tag */
TrailTerm(trail_base) = AbsAppl((CELL *)TrailTerm(trail_base));
} }
trail_ptr -= 2;
} else { } else {
tr_fr_ptr trp = (*lkp)-1;
TrailTerm(trp) = TrailTerm(trail_ptr-1);
/* we can safely ignore this little monster */ /* we can safely ignore this little monster */
discard_trail_entries += 2; discard_trail_entries += 3;
RESET_VARIABLE(&TrailTerm(trail_ptr)); RESET_VARIABLE(&TrailTerm(trail_base));
#ifdef FROZEN_STACKS #ifdef FROZEN_STACKS
RESET_VARIABLE(&TrailVal(trail_ptr)); RESET_VARIABLE(&TrailVal(trail_base));
#endif #endif
trail_ptr--; trail_base++;
RESET_VARIABLE(&TrailTerm(trail_ptr)); RESET_VARIABLE(&TrailTerm(trail_base));
#ifdef FROZEN_STACKS #ifdef FROZEN_STACKS
RESET_VARIABLE(&TrailVal(trail_ptr)); RESET_VARIABLE(&TrailVal(trail_base));
#endif
trail_base++;
RESET_VARIABLE(&TrailTerm(trail_base));
#ifdef FROZEN_STACKS
RESET_VARIABLE(&TrailVal(trail_base));
#endif #endif
trail_ptr--;
RESET_VARIABLE(&TrailTerm(trail_ptr));
} }
} }
#endif #endif
trail_base++;
} }
#if MULTI_ASSIGNMENT_VARIABLES
while (live_list != NULL) {
CELL trail_cell = TrailTerm(live_list->trptr-1);
CELL trail_cell2 = TrailTerm(live_list->trptr);
if (HEAP_PTR(trail_cell)) {
mark_external_reference(&TrailTerm(live_list->trptr-1));
}
#ifdef FROZEN_STACKS
if (HEAP_PTR(TrailVal(trail_ptr))) {
mark_external_reference(&TrailVal(trail_ptr));
}
if (HEAP_PTR(TrailVal(trail_ptr-1))) {
mark_external_reference(&TrailVal(trail_ptr-1));
}
#endif
live_list = live_list->ma_list;
}
#endif
#ifdef EASY_SHUNTING #ifdef EASY_SHUNTING
sTR = (tr_fr_ptr)old_cont_top0; sTR = (tr_fr_ptr)old_cont_top0;
while (begsTR != NULL) { while (begsTR != NULL) {