18static char SccsId[] =
"%W% %G%";
28#define HYBRID_SCHEME 1
30#define DEBUG_printf0(A,B)
31#define DEBUG_printf1(A,B,C)
32#define DEBUG_printf20(A,B)
33#define DEBUG_printf21(A,B,C)
37static Int p_inform_gc( CACHE_TYPE1 );
38static Int garbage_collect( CACHE_TYPE1 );
39static void init_dbtable(tr_fr_ptr CACHE_TYPE);
40static void mark_external_reference(CELL * CACHE_TYPE);
41static void mark_db_fixed(CELL * CACHE_TYPE);
42static void mark_trail(tr_fr_ptr, tr_fr_ptr, CELL *,
choiceptr CACHE_TYPE);
43static void mark_environments(CELL *,
yamop *,
size_t, CELL * CACHE_TYPE);
44static void mark_choicepoints(
choiceptr, tr_fr_ptr,
bool CACHE_TYPE);
45static void into_relocation_chain(CELL *, CELL * CACHE_TYPE);
46static void sweep_environments(CELL *,
yamop*,
size_t, CELL * CACHE_TYPE);
47static void sweep_choicepoints(
choiceptr CACHE_TYPE);
48static void compact_heap( CACHE_TYPE1 );
49static void update_relocation_chain(CELL *, CELL * CACHE_TYPE);
50static bool is_gc_verbose(
void);
51static bool is_gc_very_verbose(
void);
52static void LeaveGCMode( CACHE_TYPE1 );
54static void set_conditionals(tr_fr_ptr CACHE_TYPE);
77 db_entry_type db_type;
87 db_entry_type db_type;
97#define LOCAL_cont_top0 (cont *)LOCAL_sTR
102yamop * Yap_gcP(
void) {
110gc_growtrail(
int committed, tr_fr_ptr begsTR,
cont *old_cont_top0 USES_REGS)
112 UInt sz = LOCAL_TrailTop-(ADDR)LOCAL_OldTR;
116 if (!Yap_locked_growtrail(sz, TRUE)) {
119 LOCAL_sTR = (tr_fr_ptr)old_cont_top0;
120 while (begsTR != NULL) {
121 tr_fr_ptr newsTR = (tr_fr_ptr)TrailTerm(begsTR);
122 TrailTerm(LOCAL_sTR) = TrailTerm(begsTR+1);
123 TrailTerm(LOCAL_sTR+1) = TrailTerm(begsTR+2);
128 set_conditionals(LOCAL_sTR PASS_REGS);
132 siglongjmp(LOCAL_gc_restore, 2);
137PUSH_CONTINUATION(CELL *v,
int nof USES_REGS) {
141 if ((ADDR)x > LOCAL_TrailTop-1024) {
142 gc_growtrail(TRUE, NULL, NULL PASS_REGS);
149#define POP_CONTINUATION() { \
150 if (LOCAL_cont_top == LOCAL_cont_top0) \
153 int nof = LOCAL_cont_top->nof; \
154 cont *x = LOCAL_cont_top; \
158 LOCAL_cont_top = --x; \
169PUSH_POINTER(CELL *v USES_REGS) {
170 if (LOCAL_iptop >= (CELL_PTR *)ASP)
return;
176POP_POINTER( USES_REGS1 ) {
177 if (LOCAL_iptop >= (CELL_PTR *)ASP)
return;
183POPSWAP_POINTER(CELL_PTR *vp, CELL_PTR v USES_REGS) {
184 if (LOCAL_iptop >= (CELL_PTR *)ASP || LOCAL_iptop == vp)
return;
188 if (vp != LOCAL_iptop)
197exchange(CELL_PTR * b, Int i, Int j)
206partition(CELL *a[], Int p, Int r)
215 while (a[j] > x && i < j) {
218 while (a[i] < x && i < j) {
225 while (a[j] > x && i < j) {
228 while (a[i] < x && i < j) {
239insort(CELL *a[], Int p, Int q)
243 for (j = p+1; j <= q; j ++) {
250 while (i > p && a[i-1] > key) {
260quicksort(CELL *a[], Int p, Int r)
268 exchange(a, p, (p+r)/2);
269 q = partition (a, p, r);
270 quicksort(a, p, q-1);
271 quicksort(a, q + 1, r);
277#define PUSH_POINTER(P PASS_REGS)
278#define POP_POINTER( PASS_REGS1 )
279#define POPSWAP_POINTER(P)
284#ifdef MULTI_ASSIGNMENT_VARIABLES
292static inline unsigned int
293GC_MAVAR_HASH(CELL *addr) {
295 return((((
unsigned int)((CELL)(addr)))>>3)%GC_MAVARS_HASH_SIZE);
297 return((((
unsigned int)((CELL)(addr)))>>2)%GC_MAVARS_HASH_SIZE);
302GC_ALLOC_NEW_MASPACE( USES_REGS1 )
305 if ((
char *)LOCAL_gc_ma_h_top > LOCAL_TrailTop-1024)
306 gc_growtrail(FALSE, NULL, NULL PASS_REGS);
308 LOCAL_cont_top = (
cont *)LOCAL_gc_ma_h_top;
310 LOCAL_sTR = LOCAL_sTR0 = (tr_fr_ptr)LOCAL_cont_top;
312 LOCAL_cont_top0 = LOCAL_cont_top;
318gc_lookup_ma_var(CELL *addr, tr_fr_ptr trp USES_REGS) {
319 unsigned int i = GC_MAVAR_HASH(addr);
322 if (LOCAL_gc_ma_hash_table[i].timestmp != LOCAL_gc_timestamp) {
323 LOCAL_gc_ma_hash_table[i].timestmp = LOCAL_gc_timestamp;
324 LOCAL_gc_ma_hash_table[i].addr = addr;
326 LOCAL_gc_ma_hash_table[i].loc = trp;
327 LOCAL_gc_ma_hash_table[i].more = LOCAL_gc_ma_h_list;
328 LOCAL_gc_ma_h_list = LOCAL_gc_ma_hash_table+i;
330 LOCAL_gc_ma_hash_table[i].next = NULL;
333 nptr = LOCAL_gc_ma_hash_table+i;
336 if (nptr->addr == addr) {
342 TrailVal(nptr->loc+1) = TrailVal(trp+1);
348 nptr = GC_ALLOC_NEW_MASPACE( PASS_REGS1 );
353 nptr->more = LOCAL_gc_ma_h_list;
356 LOCAL_gc_ma_h_list = nptr;
362 UInt time = ++LOCAL_gc_timestamp;
364 LOCAL_gc_ma_h_list = NULL;
369 for (i = 0; i < GC_MAVARS_HASH_SIZE; i++)
370 LOCAL_gc_ma_hash_table[i].timestmp = 0L;
371 time = ++LOCAL_gc_timestamp;
373 LOCAL_gc_ma_h_top = top;
374 LOCAL_cont_top = (
cont *)LOCAL_gc_ma_h_top;
376 LOCAL_sTR = (tr_fr_ptr)LOCAL_cont_top;
378 LOCAL_cont_top0 = LOCAL_cont_top;
386static void count(Term t, Term *p) {
388 if ((tr_fr_ptr)LOCAL_TrailTop-TR < 1024) {
390 siglongjmp( LOCAL_gc_restore, 2);
394static void mark(Term t, Term *p) {
395 mark_external_reference(&TrailTerm(TR) PASS_REGS);
399static void sweep(Term t, Term *o) {
400 Term *ptr =&(TrailTerm(TR)) ;
401 if (HEAP_PTR(*ptr)) {
402 into_relocation_chain(ptr, GET_NEXT(*ptr) PASS_REGS);
408static void pop(Term t, Term *o) {
409 Term *ptr = &(TrailTerm(TR));
419#define PUSH(X) PUSH__((X),&(X))
422push_registers(Int num_regs,
void PUSH__(Term, Term *),
yamop *nextop USES_REGS)
430 for (i = 1; i <= num_regs; i++) {
434 PUSH( LOCAL_GlobalArena );
437 PUSH( LOCAL_WokenGoals );
438 PUSH( LOCAL_AttsMutableList );
440 PUSH( al->ValueOfVE );
445 if (!IsUnboundVar(&gl->global) &&
455 if (sal->ArrayType == array_of_nb_terms) {
456 UInt arity = -sal->ArrayEArity, i;
457 for (i=0; i < arity; i++) {
458 Term tlive = sal->ValueOfVE.lterms[i].tlive;
459 if (!IsVarTerm(tlive) || !IsUnboundVar(&sal->ValueOfVE.lterms[i].tlive)) {
460 PUSH( sal->ValueOfVE.lterms[i].tlive );
467 CELL *curslot = LOCAL_SlotBase,
468 *topslot = LOCAL_SlotBase + LOCAL_CurSlot;
469 while (curslot < topslot) {
471 if (
false && !IsVarTerm(*curslot) &&
473 (*curslot < (CELL)LOCAL_GlobalBase &&
474 *curslot > (CELL)HR))) {
475 *curslot++ = TermFreeTerm;
482 if (nextop->opc == Yap_opcode(_move_back) ||
483 nextop->opc == Yap_opcode(_skip)) {
484 CELL *lab = (CELL *)(nextop->y_u.l.l);
490 for (i=0L; i <= max; i++) {
491 if (i == 8*CellSize) {
507mark_regs(
int num_regs, tr_fr_ptr old_TR,
yamop *nextop USES_REGS)
511 push_registers(num_regs, mark, nextop USES_REGS);
517sweep_regs(
int num_regs, tr_fr_ptr old_TR,
yamop *nextop USES_REGS)
521 push_registers(num_regs, sweep, nextop PASS_REGS);
530pop_registers(Int num_regs, tr_fr_ptr old_TR,
yamop *nextop USES_REGS)
533 while (LOCAL_extra_gc_cells > LOCAL_extra_gc_cells_base) {
534 YAP_Opaque_CallOnGCRelocate f;
535 CELL *ptr = LOCAL_extra_gc_cells-1;
536 size_t n = ptr[0], t = ptr[-1];
538 LOCAL_extra_gc_cells -= (n+1);
539 if ( (f = Yap_blob_gc_relocate_handler(t)) ) {
540 int out = (f)(Yap_BlobTag(t), Yap_BlobInfo(t), LOCAL_extra_gc_cells, n);
545 siglongjmp(LOCAL_gc_restore, 4);
550 tr_fr_ptr trnow = TR;
552 push_registers(num_regs, pop,nextop PASS_REGS);
555#if DEBUG && COUNT_CELLS_MARKED
557count_cells_marked(
void)
560 int found_marked = 0;
562 for (current = H - 1; current >= H0; current--) {
563 if (MARKED_PTR(current)) {
567 return(found_marked);
573RBMalloc(UInt size USES_REGS)
575 ADDR
new = LOCAL_db_vec;
577 LOCAL_db_vec += size;
578 if ((ADDR)LOCAL_db_vec > LOCAL_TrailTop-1024) {
579 gc_growtrail(FALSE, NULL, NULL PASS_REGS);
592 temp->parent=temp->left=temp->right=temp;
596 temp->parent=temp->left=temp->right=LOCAL_db_nil;
639 if (y->left != rb_nil) y->left->parent=x;
646 if( x == x->parent->left) {
655 Assert(!LOCAL_db_nil->red,
"nil not red in LeftRotate");
695 if (rb_nil != x->right) x->right->parent=y;
701 if( y == y->parent->left) {
710 Assert(!LOCAL_db_nil->red,
"nil not red in RightRotate");
736 z->left=z->right=rb_nil;
738 x=LOCAL_db_root->left;
739 while( x != rb_nil) {
741 if (x->key < z->key) {
748 if ( (y == LOCAL_db_root) ||
756 Assert(!LOCAL_db_nil->red,
"nil not red in TreeInsertHelp");
781RBTreeInsert(CODEADDR key, CODEADDR end, db_entry_type db_type USES_REGS) {
792 TreeInsertHelp(x PASS_REGS);
795 while(x->parent->red) {
796 if (x->parent == x->parent->parent->left) {
797 y=x->parent->parent->right;
801 x->parent->parent->red=1;
804 if (x == x->parent->right) {
806 LeftRotate(x PASS_REGS);
809 x->parent->parent->red=1;
810 RightRotate(x->parent->parent PASS_REGS);
813 y=x->parent->parent->left;
817 x->parent->parent->red=1;
820 if (x == x->parent->left) {
822 RightRotate(x PASS_REGS);
825 x->parent->parent->red=1;
826 LeftRotate(x->parent->parent PASS_REGS);
830 LOCAL_db_root->left->red=0;
834 Assert(!LOCAL_db_nil->red,
"nil not red in RBTreeInsert");
835 Assert(!LOCAL_db_root->red,
"root not red in RBTreeInsert");
842store_in_dbtable(CODEADDR entry, CODEADDR end, db_entry_type db_type USES_REGS)
844 RBTreeInsert(entry, end, db_type PASS_REGS);
849find_ref_in_dbtable(CODEADDR entry USES_REGS)
853 while (current != LOCAL_db_nil) {
854 if (current->key <= entry && current->lim > entry) {
857 if (entry < current->key)
858 current = current->right;
860 current = current->left;
867mark_ref_in_use(
DBRef ref USES_REGS)
874ref_in_use(
DBRef ref USES_REGS)
881mark_db_fixed(CELL *ptr USES_REGS) {
884 el = find_ref_in_dbtable((CODEADDR)ptr PASS_REGS);
885 if (el != LOCAL_db_nil) {
891init_dbtable(tr_fr_ptr trail_ptr USES_REGS) {
896 LOCAL_extra_gc_cells =
897 LOCAL_extra_gc_cells_base = (CELL *)TR;
898 LOCAL_extra_gc_cells_top = LOCAL_extra_gc_cells_base+
899 LOCAL_extra_gc_cells_size;
900 if ((
char *)LOCAL_extra_gc_cells_top > LOCAL_TrailTop-1024)
901 gc_growtrail(FALSE, NULL, NULL PASS_REGS);
902 LOCAL_db_vec0 = LOCAL_db_vec = (ADDR)LOCAL_extra_gc_cells_top;
903 LOCAL_db_root = RBTreeCreate();
904 while (trail_ptr > (tr_fr_ptr)LOCAL_TrailBase) {
905 register CELL trail_cell;
909 trail_cell = TrailTerm(trail_ptr);
911 if (!IsVarTerm(trail_cell) && IsPairTerm(trail_cell)) {
912 CELL *pt0 = RepPair(trail_cell);
920 (ADDR) pt0 >= HeapTop
922 (ADDR) pt0 >= LOCAL_TrailBase && (ADDR) pt0 < LOCAL_TrailTop
932 if (FlagOn(DBClMask, flags)) {
933 DBRef dbr = DBStructFlagsToDBStruct(pt0);
934 store_in_dbtable((CODEADDR)dbr,
935 (CODEADDR)dbr+
sizeof(
DBStruct)+
sizeof(CELL)*dbr->DBT.NOfCells,
937 }
else if (flags & LogUpdMask) {
938 if (flags & IndexMask) {
940 store_in_dbtable((CODEADDR)li, (CODEADDR)li+li->ClSize, li_entry PASS_REGS);
943 store_in_dbtable((CODEADDR)cli, (CODEADDR)cli+cli->ClSize, lcl_entry PASS_REGS);
947 store_in_dbtable((CODEADDR)dcl, (CODEADDR)dcl+dcl->ClSize, dcl_entry PASS_REGS);
952 store_in_dbtable((CODEADDR)sc, (CODEADDR)sc+sc->ClSize, dcl_entry PASS_REGS);
956 store_in_dbtable((CODEADDR)si, (CODEADDR)si+si->ClSize, dcl_entry PASS_REGS);
957 si = si->SiblingIndex;
960 store_in_dbtable((CODEADDR)mc, (CODEADDR)mc+mc->ClSize, dcl_entry PASS_REGS);
963 if (LOCAL_db_vec == LOCAL_db_vec0) {
965 LOCAL_db_vec0 = NULL;
985unsigned long chain[16];
986unsigned long env_vars;
987unsigned long vars[gc_susp+1];
990unsigned long old_vars, new_vars;
995inc_vars_of_type(CELL *curr,gc_types val) {
996 if (curr >= H0 && curr < TrueHB) {
998 }
else if (curr >= TrueHB && curr < HR) {
1007put_type_info(
unsigned long total)
1009 fprintf(stderr,
"%% type info for %lu cells\n", total);
1010 fprintf(stderr,
"%% %lu vars\n", vars[gc_var]);
1011 fprintf(stderr,
"%% %lu refs\n", vars[gc_ref]);
1012 fprintf(stderr,
"%% %lu references from env\n", env_vars);
1013 fprintf(stderr,
"%% %lu atoms\n", vars[gc_atom]);
1014 fprintf(stderr,
"%% %lu small ints\n", vars[gc_int]);
1015 fprintf(stderr,
"%% %lu other numbers\n", vars[gc_num]);
1016 fprintf(stderr,
"%% %lu lists\n", vars[gc_list]);
1017 fprintf(stderr,
"%% %lu compound terms\n", vars[gc_appl]);
1018 fprintf(stderr,
"%% %lu functors\n", vars[gc_func]);
1019 fprintf(stderr,
"%% %lu suspensions\n", vars[gc_susp]);
1023inc_var(CELL *current, CELL *next)
1028 if (ONHEAP(current)) {
1029 if (next == current) {
1030 inc_vars_of_type(current,gc_var);
1033 inc_vars_of_type(current,gc_ref);
1034 while(ONHEAP(mynext) && IsVarTerm(*mynext)) {
1035 CELL *prox = GET_NEXT(*mynext);
1036 if (prox == mynext) {
1077 for (current = H - 1; current >= H0; current--) {
1078 CELL ccurr = *current;
1080 if (MARKED_PTR(current)) {
1081 CELL ccell = UNMARK_CELL(ccurr);
1084 CELL *ptr = current-1;
1087 while (!MARKED_PTR(ptr)) ptr--;
1088 nofcells = current-ptr;
1095 if (IsVarTerm(ccurr)) {
1096 if (IsBlobFunctor((
Functor)ccurr)) vars[gc_num]++;
1097 else if (ccurr != 0 && (ccurr < (CELL)LOCAL_GlobalBase || ccurr > (CELL)LOCAL_TrailTop)) {
1103 else if (IsUnboundVar(current)) vars[gc_var]++;
1104 else vars[gc_ref]++;
1105 }
else if (IsApplTerm(ccurr)) {
1108 }
else if (IsPairTerm(ccurr)) {
1111 }
else if (IsAtomTerm(ccurr)) {
1114 }
else if (IsIntTerm(ccurr)) {
1121 put_type_info(H-H0);
1134#define check_global()
1140mark_variable(CELL_PTR current USES_REGS)
1145 char *local_bp = LOCAL_bp;
1148 if (current == 0 || UNMARKED_MARK(current,local_bp)) {
1151 if (current >= H0 && current < HR) {
1153 LOCAL_total_marked++;
1154 if (current < LOCAL_HGEN) {
1155 LOCAL_total_oldies++;
1157 DEBUG_printf0(
"%p 1\n", current);
1160 PUSH_POINTER(current PASS_REGS);
1162 next = GET_NEXT(ccur);
1164 if (IsVarTerm(ccur)) {
1165 if (IN_BETWEEN(LOCAL_GlobalBase,current,HR) && GlobalIsAttVar(current) && current==next) {
1166 if (next < H0) POP_CONTINUATION();
1167 if (!UNMARKED_MARK(next-1,local_bp)) {
1169 LOCAL_total_marked++;
1170 if (next-1 < LOCAL_HGEN) {
1171 LOCAL_total_oldies++;
1173 DEBUG_printf0(
"%p 1\n", next-1);
1175 PUSH_POINTER(next-1 PASS_REGS);
1177 PUSH_CONTINUATION(next+1,2 PASS_REGS);
1180 }
else if (ONHEAP(next)) {
1186 if (!MARKED_PTR(next)) {
1187 if (IsVarTerm(cnext) && (CELL)next == cnext) {
1189 if (next > current && current < LOCAL_prev_HB && current >= HB && next >= HB && next < LOCAL_prev_HB) {
1191 inc_var(current, current);
1193 *next = (CELL)current;
1196 *current = (CELL)current;
1201 inc_var(current, next);
1207 if (next >= HB && current < LCL0 && cnext != TermFoundVar) {
1210 if (current >= H0 && current < HR) {
1212 LOCAL_total_marked--;
1213 if (current < LOCAL_HGEN) {
1214 LOCAL_total_oldies--;
1216 DEBUG_printf0(
"%p-1\n", next-1);
1219 POP_POINTER( PASS_REGS1 );
1222 inc_var(current, next);
1228 }
else if (next > HB &&
1230 UNMARK_CELL(cnext) != (CELL)next &&
1233 *current = UNMARK_CELL(cnext);
1235 if (current >= H0 && current < HR ) {
1237 LOCAL_total_marked--;
1238 if (current < LOCAL_HGEN) {
1239 LOCAL_total_oldies--;
1241 DEBUG_printf0(
"%p-1\n", next-1);
1244 POP_POINTER( PASS_REGS1 );
1250 inc_var(current, next);
1256 }
else if (next < (CELL *)LOCAL_GlobalBase || next > (CELL *)LOCAL_TrailTop) {
1258 "OOPS in GC: marking, TR=%p, current=%p, *current=" UInt_FORMAT
" next=%p\n", TR, current, ccur, next);
1262 LOCAL_total_smarked++;
1265 inc_var(current, next);
1269 }
else if (IsAtomOrIntTerm(ccur)) {
1271 if (IsAtomTerm(ccur))
1272 inc_vars_of_type(current,gc_atom);
1274 inc_vars_of_type(current, gc_int);
1277 }
else if (IsPairTerm(ccur)) {
1279 inc_vars_of_type(current,gc_list);
1283 if (IsAtomOrIntTerm(*next)) {
1284 if (!UNMARKED_MARK(next,local_bp)) {
1286 LOCAL_total_marked++;
1287 if (next < LOCAL_HGEN) {
1288 LOCAL_total_oldies++;
1290 DEBUG_printf0(
"%p 1\n", next);
1292 PUSH_POINTER(next PASS_REGS);
1297 PUSH_CONTINUATION(next+1,1 PASS_REGS);
1301 }
else if (ONCODE(next)) {
1302 mark_db_fixed(RepPair(ccur) PASS_REGS);
1305 }
else if (IsApplTerm(ccur)) {
1306 register CELL cnext = *next;
1309 if (!IsExtensionFunctor((
Functor)cnext))
1310 inc_vars_of_type(current,gc_appl);
1312 inc_vars_of_type(current,gc_num);
1315 if ((
Functor)cnext == FunctorDBRef) {
1316 DBRef tref = DBRefOfTerm(ccur);
1319 if ((tref->Flags & (ErasedMask|LogUpdMask)) == (ErasedMask|LogUpdMask)) {
1320 *current = MkDBRefTerm((
DBRef)LogDBErasedMarker);
1323 mark_ref_in_use(tref PASS_REGS);
1326 mark_db_fixed(next PASS_REGS);
1330 if ( MARKED_PTR(next) || !ONHEAP(next) )
1333 if (next < H0) POP_CONTINUATION();
1334 if (IsExtensionFunctor((
Functor)cnext)) {
1335 size_t sz = SizeOfOpaqueTerm(next,cnext);
1343 if (next < LOCAL_HGEN) {
1344 LOCAL_total_oldies+=sz;
1348 LOCAL_total_marked += sz;
1349 PUSH_POINTER(next PASS_REGS);
1350 PUSH_POINTER(next+(sz-1) PASS_REGS);
1351 YAP_Opaque_CallOnGCMark f;
1352 Term t = AbsAppl(next);
1353 if ((
Functor)next[0] == FunctorBlob &&
1354 (f = Yap_blob_gc_mark_handler(t))) {
1355 Int n = f(Yap_BlobTag(t), Yap_BlobInfo(t), LOCAL_extra_gc_cells,
1356 LOCAL_extra_gc_cells_top - (LOCAL_extra_gc_cells + 2));
1360 save_machine_regs();
1361 siglongjmp(LOCAL_gc_restore, 3);
1363 CELL *ptr = LOCAL_extra_gc_cells;
1365 LOCAL_extra_gc_cells += n + 2;
1366 PUSH_CONTINUATION(ptr, n + 1 PASS_REGS);
1374 if (next[sz-1] != CloseExtension(next)) {
1375 fprintf(stderr,
"[ Error: could not find ES at blob %p type " UInt_FORMAT
" ]\n", next, next[1]);
1380 if (next < H0) POP_CONTINUATION();
1382 inc_vars_of_type(next,gc_func);
1384 arity = ArityOfFunctor((
Functor)(cnext));
1387 ++LOCAL_total_marked;
1388 if (next < LOCAL_HGEN) {
1389 ++LOCAL_total_oldies;
1391 DEBUG_printf0(
"%p 1\n", next);
1393 PUSH_POINTER(next PASS_REGS);
1396 while (arity && IsAtomOrIntTerm(*next)) {
1397 if (!UNMARKED_MARK(next,local_bp)) {
1399 LOCAL_total_marked++;
1400 if (next < LOCAL_HGEN) {
1401 LOCAL_total_oldies++;
1403 DEBUG_printf0(
"%p 1\n", next);
1405 PUSH_POINTER(next PASS_REGS);
1410 if (!arity) POP_CONTINUATION();
1412 if (arity == 1)
goto begin;
1413 PUSH_CONTINUATION(current+1,arity-1 PASS_REGS);
1419Yap_mark_variable(CELL_PTR current)
1422 mark_variable(current PASS_REGS);
1426mark_code(CELL_PTR ptr, CELL *next USES_REGS)
1430 if (IsApplTerm(reg) && (
Functor)(*next) == FunctorDBRef) {
1431 DBRef tref = DBRefOfTerm(reg);
1433 if ((tref->Flags & (LogUpdMask|ErasedMask)) == (LogUpdMask|ErasedMask)) {
1434 *ptr = MkDBRefTerm((
DBRef)LogDBErasedMarker);
1436 mark_ref_in_use(tref PASS_REGS);
1439 mark_db_fixed(next PASS_REGS);
1445mark_external_reference(CELL *ptr USES_REGS) {
1446 CELL *next = GET_NEXT(*ptr);
1450 CELL_PTR *old = LOCAL_iptop;
1452 mark_variable(ptr PASS_REGS);
1454 POPSWAP_POINTER(old, ptr PASS_REGS);
1455 }
else if (ptr < H0 || ptr > (CELL*)LOCAL_TrailTop) {
1456 mark_code(ptr, next PASS_REGS);
1466Yap_mark_external_reference(CELL *ptr) {
1468 mark_external_reference(ptr PASS_REGS);
1475mark_environments(CELL_PTR gc_ENV,
yamop *pc,
size_t size, CELL *pvbmap USES_REGS)
1478 bool very_verbose = is_gc_very_verbose();
1479 while (gc_ENV != NULL) {
1486 op_numbers op = Yap_op_from_opcode(ENV_ToOp((
yamop*)gc_ENV[E_CP]));
1487#if defined(ANALYST) || defined(DEBUG)
1488 fprintf(stderr,
"ENV %p-%p(%ld) %s\n", gc_ENV, pvbmap, size-EnvSizeInCells, Yap_op_names[op]);
1490 fprintf(stderr,
"ENV %p-%p(%ld) %d\n", gc_ENV, pvbmap, size-EnvSizeInCells, (
int)op);
1493 fprintf(stderr,
" %s/%ld\n", RepAtom(NameOfFunctor(pe->FunctorOfPred))->StrOfAE, pe->ArityOfPE);
1495 fprintf(stderr,
" %s\n", RepAtom((
Atom)(pe->FunctorOfPred))->StrOfAE);
1498 if (pc->opc== FAIL_OPCODE)
1504 fprintf(stderr,
"OOPS in GC: env size for %p is " UInt_FORMAT
"\n", gc_ENV, (CELL)size);
1506 mark_db_fixed((CELL *)gc_ENV[E_CP] PASS_REGS);
1508 if (size > EnvSizeInCells) {
1509 int tsize = size - EnvSizeInCells;
1511 currv =
sizeof(CELL)*8-tsize%(
sizeof(CELL)*8);
1512 if (pvbmap != NULL) {
1513 pvbmap += tsize/(
sizeof(CELL)*8);
1518 bmap = (Int)(((CELL)bmap) << currv);
1521 for (saved_var = gc_ENV - size; saved_var < gc_ENV - EnvSizeInCells; saved_var++) {
1522 if (currv ==
sizeof(CELL)*8) {
1532 if (bmap < 0 && !MARKED_PTR(saved_var)) {
1534 Term ccur = *saved_var;
1536 if (IsVarTerm(ccur)) {
1538 CELL *mynext= GET_NEXT(ccur);
1540 if (ONHEAP(mynext)) {
1542 while(ONHEAP(mynext) && IsVarTerm(*mynext)) {
1543 CELL *prox = GET_NEXT(*mynext);
1544 if (prox == mynext) {
1559 mark_external_reference(saved_var PASS_REGS);
1571 if (MARKED_PTR(gc_ENV+E_CB))
1574 pc = (
yamop *) (gc_ENV[E_CP]);
1575 size = EnvSize( pc );
1576 pvbmap = EnvBMap( pc );
1578 gc_ENV = (CELL_PTR) gc_ENV[E_E];
1600mark_trail(tr_fr_ptr trail_ptr, tr_fr_ptr trail_base, CELL *gc_H,
choiceptr gc_B USES_REGS)
1603 tr_fr_ptr begsTR = NULL, endsTR = NULL;
1604 tr_fr_ptr OldsTR0 = LOCAL_sTR0;
1607 CELL *detatt = NULL;
1609 cont *old_cont_top0 = LOCAL_cont_top0;
1611 if (trail_ptr == trail_base)
1615 while (trail_base < trail_ptr) {
1616 register CELL trail_cell;
1618 trail_cell = TrailTerm(trail_base);
1619 if (IsVarTerm(trail_cell)) {
1620 CELL *hp = (CELL *)trail_cell;
1625 if ((hp < gc_H && hp >= H0 ) && !MARKED_PTR(hp)) {
1629 LOCAL_discard_trail_entries++;
1630 RESET_VARIABLE(&TrailTerm(trail_base));
1632 RESET_VARIABLE(&TrailVal(trail_base));
1634 }
else if (hp < (CELL *)LOCAL_GlobalBase || hp > (CELL *)LOCAL_TrailTop) {
1637 }
else if ((hp < (CELL *)gc_B && hp >= gc_H) || hp > (CELL *)LOCAL_TrailBase) {
1639 RESET_VARIABLE(&TrailTerm(trail_base));
1641 RESET_VARIABLE(&TrailVal(trail_base));
1643 LOCAL_discard_trail_entries++;
1645 if (trail_cell == (CELL)trail_base)
1646 LOCAL_discard_trail_entries++;
1652 if (IN_BETWEEN(LOCAL_GlobalBase,hp,HR) && GlobalIsAttVar(hp) && !UNMARKED_MARK(hp-1,LOCAL_bp)) {
1654 LOCAL_total_marked++;
1655 PUSH_POINTER(hp-1 PASS_REGS);
1656 if (hp-1 < LOCAL_HGEN) {
1657 LOCAL_total_oldies++;
1659 DEBUG_printf0(
"%p 1\n", hp-1);
1661 mark_variable(hp+1 PASS_REGS);
1662 mark_variable(hp+2 PASS_REGS);
1665 mark_external_reference(&TrailVal(trail_base) PASS_REGS);
1669 if (hp < gc_H && hp >= H0 && !MARKED_PTR(hp)) {
1670 tr_fr_ptr nsTR = (tr_fr_ptr)LOCAL_cont_top0;
1671 CELL *cptr = (CELL *)trail_cell;
1673 if ((ADDR)nsTR > LOCAL_TrailTop-1024) {
1674 gc_growtrail(TRUE, begsTR, old_cont_top0 PASS_REGS);
1676 TrailTerm(nsTR) = (CELL)NULL;
1677 TrailTerm(nsTR+1) = *hp;
1678 TrailTerm(nsTR+2) = trail_cell;
1682 TrailTerm(endsTR) = (CELL)nsTR;
1684 LOCAL_cont_top = (
cont *)(nsTR+3);
1685 LOCAL_sTR = (tr_fr_ptr)LOCAL_cont_top;
1687 RESET_VARIABLE(cptr);
1692 }
else if (IsPairTerm(trail_cell)) {
1694 CELL *cptr = RepPair(trail_cell);
1695 if (IN_BETWEEN(LOCAL_GlobalBase,cptr,HR)) {
1696 if (GlobalIsAttVar(cptr)) {
1697 TrailTerm(trail_base) = (CELL)cptr;
1698 mark_external_reference(&TrailTerm(trail_base) PASS_REGS);
1699 TrailTerm(trail_base) = trail_cell;
1701 mark_external_reference(&TrailTerm(trail_base) PASS_REGS);
1705#if MULTI_ASSIGNMENT_VARIABLES
1707 CELL *cptr = RepAppl(trail_cell);
1715 if (cptr < (CELL *)gc_B && cptr >= gc_H) {
1716 goto remove_trash_entry;
1717 }
else if (IsAttVar(cptr)) {
1719 if (detatt && cptr < detatt) {
1720 goto remove_trash_entry;
1723 mark_variable(cptr PASS_REGS);
1726 if (!gc_lookup_ma_var(cptr, trail_base PASS_REGS)) {
1728 Term t0 = TrailTerm(trail_base+1);
1730 if (!IsAtomicTerm(t0)) {
1731 CELL *next = GET_NEXT(t0);
1734 if (next < (CELL *)gc_B && next >= gc_H) {
1735 goto remove_trash_entry;
1738 if (HEAP_PTR(trail_cell)) {
1740 TrailTerm(trail_base) = (CELL)cptr;
1741 mark_external_reference(&(TrailTerm(trail_base)) PASS_REGS);
1743 TrailTerm(trail_base) = AbsAppl((CELL *)TrailTerm(trail_base));
1746 mark_external_reference(&(TrailVal(trail_base)) PASS_REGS);
1748 if (HEAP_PTR(trail_cell)) {
1749 TrailTerm(trail_base) = (CELL)cptr;
1750 mark_external_reference(&(TrailTerm(trail_base)) PASS_REGS);
1752 TrailTerm(trail_base) = AbsAppl((CELL *)TrailTerm(trail_base));
1758 mark_external_reference(&(TrailTerm(trail_base)) PASS_REGS);
1760 if (HEAP_PTR(trail_cell)) {
1762 TrailTerm(trail_base) = (CELL)cptr;
1763 mark_external_reference(&(TrailTerm(trail_base)) PASS_REGS);
1765 TrailTerm(trail_base) = AbsAppl((CELL *)TrailTerm(trail_base));
1772 LOCAL_discard_trail_entries += 2;
1773 RESET_VARIABLE(&TrailTerm(trail_base));
1774 RESET_VARIABLE(&TrailVal(trail_base));
1776 LOCAL_discard_trail_entries += 3;
1777 RESET_VARIABLE(&TrailTerm(trail_base));
1779 RESET_VARIABLE(&TrailTerm(trail_base));
1782 RESET_VARIABLE(&TrailTerm(trail_base));
1784 RESET_VARIABLE(&TrailVal(trail_base));
1799 mark_external_reference(&(TrailVal(gl->loc+1)) PASS_REGS);
1806 LOCAL_sTR = (tr_fr_ptr)old_cont_top0;
1807 while (begsTR != NULL) {
1808 tr_fr_ptr newsTR = (tr_fr_ptr)TrailTerm(begsTR);
1809 TrailTerm(LOCAL_sTR) = TrailTerm(begsTR+1);
1810 TrailTerm(LOCAL_sTR+1) = TrailTerm(begsTR+2);
1814 LOCAL_sTR0 = OldsTR0;
1816 LOCAL_cont_top0 = old_cont_top0;
1818 LOCAL_cont_top = LOCAL_cont_top0;
1827#define init_substitution_pointer(GCB, SUBS_PTR, DEP_FR) \
1828 if (DepFr_leader_cp(DEP_FR) == GCB) { \
1831 SUBS_PTR = (CELL *) (GEN_CP(GCB) + 1); \
1832 SUBS_PTR += SgFr_arity(GEN_CP(GCB)->cp_sg_fr); \
1834 SUBS_PTR = (CELL *) (CONS_CP(GCB) + 1); \
1849 if (depfr && min > DepFr_cons_cp(depfr)) {
1850 min = DepFr_cons_cp(depfr);
1852 if (depfr && min == DepFr_cons_cp(depfr)) {
1853 *depfrp = DepFr_next(depfr);
1861mark_choicepoints(
register choiceptr gc_B, tr_fr_ptr saved_TR,
bool very_verbose USES_REGS)
1864 trust_lu = Yap_opcode(_trust_logical),
1865 count_trust_lu = Yap_opcode(_count_trust_logical),
1866 profiled_trust_lu = Yap_opcode(_profiled_trust_logical);
1868 yamop *lu_cl0 = NEXTOP(PredLogUpdClause0->CodeOfPred,Otapl),
1869 *lu_cl = NEXTOP(PredLogUpdClause->CodeOfPred,Otapl),
1870 *lu_cle = NEXTOP(PredLogUpdClauseErase->CodeOfPred,Otapl),
1871 *su_cl = NEXTOP(PredStaticClause->CodeOfPred,Otapl);
1876 gc_B = youngest_cp(gc_B, &depfr);
1878 while (gc_B != NULL) {
1881 yamop *rtp = gc_B->cp_ap;
1887 mark_db_fixed((CELL *)rtp PASS_REGS);
1888#ifdef DETERMINISTIC_TABLING
1889 if (!IS_DET_GEN_CP(gc_B))
1891 mark_db_fixed((CELL *)(gc_B->cp_cp) PASS_REGS);
1893 LOCAL_current_B = gc_B;
1902 if (aux_sg_fr && gc_B == SgFr_gen_cp(aux_sg_fr)) {
1904 opnum = _table_completion;
1907 opnum = _trust_fail;
1912 opnum = Yap_op_from_opcode(op);
1917 if (aux_sg_fr && gc_B == SgFr_gen_cp(aux_sg_fr)) {
1918 aux_sg_fr = SgFr_next(aux_sg_fr);
1925 fprintf(stderr,
"%% marked " UInt_FORMAT
" (%s)\n", LOCAL_total_marked, Yap_op_names[opnum]);
1926 }
else if (pe->ArityOfPE) {
1927 fprintf(stderr,
"%% %s/" UInt_FORMAT
" marked " UInt_FORMAT
" (%s)\n", RepAtom(NameOfFunctor(pe->FunctorOfPred))->StrOfAE, pe->ArityOfPE, LOCAL_total_marked, Yap_op_names[opnum]);
1929 fprintf(stderr,
"%% %s marked " UInt_FORMAT
" (%s)\n", RepAtom((
Atom)(pe->FunctorOfPred))->StrOfAE, LOCAL_total_marked, Yap_op_names[opnum]);
1933 fprintf(stderr,
"%% marked " Int_FORMAT
" (%u)\n", LOCAL_total_marked, (
unsigned int)opnum);
1934 }
else if (pe->ArityOfPE) {
1935 fprintf(stderr,
"%% %s/%lu marked " Int_FORMAT
" (%u)\n", RepAtom(NameOfFunctor(pe->FunctorOfPred))->StrOfAE, (
unsigned long int)pe->ArityOfPE, LOCAL_total_marked, (
unsigned int)opnum);
1937 fprintf(stderr,
"%% %s marked " Int_FORMAT
" (%u)\n", RepAtom((
Atom)(pe->FunctorOfPred))->StrOfAE, LOCAL_total_marked, (
unsigned int)opnum);
1943 mark_trail(saved_TR, gc_B->cp_tr, gc_B->cp_h, gc_B PASS_REGS);
1944 saved_TR = gc_B->cp_tr;
1946 if (opnum == _or_else || opnum == _or_last) {
1948 mark_environments((CELL_PTR) (gc_B->cp_a1),gc_B->cp_cp,
1949 -gc_B->cp_cp->y_u.Osblp.s / ((OPREG)
sizeof(CELL)),
1950 gc_B->cp_cp->y_u.Osblp.bmap
1954 register CELL_PTR saved_reg;
1958 if (opnum == _Nstop)
1959 mark_environments((CELL_PTR) gc_B->cp_env,NOCODE,
1962 else if (opnum != _trust_fail) {
1964#ifdef DETERMINISTIC_TABLING
1965 mark &= !IS_DET_GEN_CP(gc_B);
1968 mark_environments((CELL_PTR) gc_B->cp_env,gc_B->cp_cp,
1969 EnvSize((
yamop *) (gc_B->cp_cp)),
1970 EnvBMap((
yamop *) (gc_B->cp_cp)) PASS_REGS);
1976 if (gc_B->cp_env == LCL0) {
1985 if (gc_B->cp_ap == RETRY_C_RECORDED_K_CODE
1986 || gc_B->cp_ap == RETRY_C_RECORDEDP_CODE) {
1991 ref = (
DBRef)EXTRA_CBACK_ARG(3,1);
1992 if (IsVarTerm((CELL)ref)) {
1993 mark_ref_in_use(ref PASS_REGS);
1995 if (ONCODE((CELL *)ref)) {
1996 mark_db_fixed(RepAppl((CELL)ref) PASS_REGS);
2001 nargs = rtp->y_u.OtapFs.s+rtp->y_u.OtapFs.extra;
2006 opnum = Yap_op_from_opcode(op);
2008 case _retry_profiled:
2010 rtp = NEXTOP(rtp,l);
2012 opnum = Yap_op_from_opcode(op);
2018 case _table_load_answer:
2020 CELL *vars_ptr, vars;
2021 vars_ptr = (CELL *) (LOAD_CP(gc_B) + 1);
2024 mark_external_reference(vars_ptr PASS_REGS);
2030 case _table_try_answer:
2031 case _table_retry_me:
2032 case _table_trust_me:
2036 CELL *vars_ptr, vars;
2037 vars_ptr = (CELL *)(GEN_CP(gc_B) + 1);
2038 nargs = rtp->y_u.Otapl.s;
2040 mark_external_reference(vars_ptr PASS_REGS);
2045 mark_external_reference(vars_ptr PASS_REGS);
2051 case _table_completion:
2052#ifdef THREADS_CONSUMER_SHARING
2053 case _table_answer_resolution_completion:
2056 CELL *vars_ptr, vars;
2057#ifdef DETERMINISTIC_TABLING
2058 if (IS_DET_GEN_CP(gc_B))
2059 vars_ptr = (CELL *)(DET_GEN_CP(gc_B) + 1);
2063 vars_ptr = (CELL *)(GEN_CP(gc_B) + 1);
2064 nargs = SgFr_arity(GEN_CP(gc_B)->cp_sg_fr);
2066 mark_external_reference(vars_ptr PASS_REGS);
2072 mark_external_reference(vars_ptr PASS_REGS);
2078 case _table_answer_resolution:
2080 CELL *vars_ptr, vars;
2081 dep_fr_ptr dep_fr = CONS_CP(gc_B)->cp_dep_fr;
2083 if (TRUE || TrNode_child(ans_node)) {
2085#ifdef MODE_DIRECTED_TABLING
2086 if (TrNode_child(ans_node) && IS_ANSWER_INVALID_NODE(TrNode_child(ans_node))) {
2088 old_ans_node = ans_node;
2089 ans_node = TrNode_child(ans_node);
2091 ans_node = TrNode_child(ans_node);
2092 }
while (IS_ANSWER_INVALID_NODE(ans_node));
2093 TrNode_child(old_ans_node) = ans_node;
2096 ans_node = TrNode_child(ans_node);
2097 if (gc_B == DepFr_leader_cp(dep_fr)) {
2100 TABLING_ERROR_CHECKING(generator_consumer, IS_BATCHED_GEN_CP(gc_B));
2101 vars_ptr = (CELL *) (GEN_CP(gc_B) + 1);
2102 vars_ptr += SgFr_arity(GEN_CP(gc_B)->cp_sg_fr);
2104 vars_ptr = (CELL *) (CONS_CP(gc_B) + 1);
2109 mark_external_reference(vars_ptr PASS_REGS);
2116 case _trie_trust_var:
2117 case _trie_retry_var:
2118 case _trie_trust_var_in_pair:
2119 case _trie_retry_var_in_pair:
2120 case _trie_trust_val:
2121 case _trie_retry_val:
2122 case _trie_trust_val_in_pair:
2123 case _trie_retry_val_in_pair:
2124 case _trie_trust_atom:
2125 case _trie_retry_atom:
2126 case _trie_trust_atom_in_pair:
2127 case _trie_retry_atom_in_pair:
2128 case _trie_trust_null:
2129 case _trie_retry_null:
2130 case _trie_trust_null_in_pair:
2131 case _trie_retry_null_in_pair:
2132 case _trie_trust_pair:
2133 case _trie_retry_pair:
2134 case _trie_trust_appl:
2135 case _trie_retry_appl:
2136 case _trie_trust_appl_in_pair:
2137 case _trie_retry_appl_in_pair:
2138 case _trie_trust_extension:
2139 case _trie_retry_extension:
2140 case _trie_trust_double:
2141 case _trie_retry_double:
2142 case _trie_trust_longint:
2143 case _trie_retry_longint:
2144 case _trie_trust_gterm:
2145 case _trie_retry_gterm:
2148 int heap_arity, vars_arity, subs_arity;
2149 vars_ptr = (CELL *)(gc_B + 1);
2150 heap_arity = vars_ptr[0];
2151 vars_arity = vars_ptr[1 + heap_arity];
2152 subs_arity = vars_ptr[2 + heap_arity + vars_arity];
2153 vars_ptr += 2 + heap_arity + subs_arity + vars_arity;
2155 while (subs_arity--) {
2156 mark_external_reference(vars_ptr PASS_REGS);
2162 while (vars_arity--) {
2163 mark_external_reference(vars_ptr PASS_REGS);
2169 while (heap_arity--) {
2172 mark_external_reference(vars_ptr PASS_REGS);
2180 case _profiled_retry_and_mark:
2181 case _count_retry_and_mark:
2182 case _retry_and_mark:
2183 mark_ref_in_use((
DBRef)ClauseCodeToDynamicClause(gc_B->cp_ap) PASS_REGS);
2194 case _retry_logical:
2201 yamop *end = rtp->y_u.OtaLl.n;
2202 while (end->opc != trust_lu &&
2203 end->opc != count_trust_lu &&
2204 end->opc != profiled_trust_lu )
2205 end = end->y_u.OtaLl.n;
2206 mark_ref_in_use((
DBRef)end->y_u.OtILl.block PASS_REGS);
2209 nargs = rtp->y_u.OtaLl.s+1;
2211 case _count_retry_logical:
2218 yamop *end = rtp->y_u.OtaLl.n;
2219 while (Yap_op_from_opcode(end->opc) != _count_trust_logical)
2220 end = end->y_u.OtaLl.n;
2221 mark_ref_in_use((
DBRef)end->y_u.OtILl.block PASS_REGS);
2224 nargs = rtp->y_u.OtaLl.s+1;
2226 case _profiled_retry_logical:
2233 yamop *end = rtp->y_u.OtaLl.n;
2234 while (Yap_op_from_opcode(end->opc) != _profiled_trust_logical)
2235 end = end->y_u.OtaLl.n;
2236 mark_ref_in_use((
DBRef)end->y_u.OtILl.block PASS_REGS);
2239 nargs = rtp->y_u.OtaLl.s+1;
2241 case _trust_logical:
2242 case _count_trust_logical:
2243 case _profiled_trust_logical:
2245 mark_ref_in_use((
DBRef)rtp->y_u.OtILl.block PASS_REGS);
2246 nargs = rtp->y_u.OtILl.d->ClPred->ArityOfPE+1;
2249 case _retry_exo_udi:
2250 case _retry_all_exo:
2251 nargs = rtp->y_u.lp.p->ArityOfPE;
2254 nargs = rtp->y_u.p.p->ArityOfPE;
2259 case _profiled_retry_me:
2260 case _profiled_trust_me:
2261 case _count_retry_me:
2262 case _count_trust_me:
2265 if (IN_BETWEEN(H0,(CELL *)(gc_B->cp_ap),HR)) {
2266 fprintf(stderr,
"OOPS in GC: gc not supported in this case!!!\n");
2269 nargs = rtp->y_u.Otapl.s;
2272 fprintf(stderr,
"OOPS in GC: Unexpected opcode: %d\n", opnum);
2276 nargs = rtp->y_u.Otapl.s;
2281 if (gc_B->cp_ap == lu_cl0 ||
2282 gc_B->cp_ap == lu_cl ||
2283 gc_B->cp_ap == lu_cle ||
2284 gc_B->cp_ap == su_cl) {
2285 yamop *pt = (
yamop *)IntegerOfTerm(gc_B->cp_args[1]);
2286 if (gc_B->cp_ap == su_cl) {
2287 mark_db_fixed((CELL *)pt PASS_REGS);
2289 while (pt->opc != trust_lu &&
2290 pt->opc != count_trust_lu &&
2291 pt->opc != profiled_trust_lu
2293 pt = pt->y_u.OtaLl.n;
2294 mark_ref_in_use((
DBRef)pt->y_u.OtILl.block PASS_REGS);
2298 for (saved_reg = &gc_B->cp_a1;
2301 saved_reg < &gc_B->cp_a1 + nargs;
2303 mark_external_reference(saved_reg PASS_REGS);
2307 gc_B = youngest_cp(gc_B->cp_b, &depfr);
2323into_relocation_chain(CELL_PTR current, CELL_PTR next USES_REGS)
2327 current_tag = TAG(*current);
2335 *next = (CELL) current | current_tag;
2340CleanDeadClauses( USES_REGS1 )
2346 cptr = &(DeadStaticClauses);
2347 cl = DeadStaticClauses;
2349 if (!ref_in_use((
DBRef)cl PASS_REGS)) {
2350 char *ocl = (
char *)cl;
2351 Yap_ClauseSpace -= cl->ClSize;
2354 Yap_FreeCodeSpace(ocl);
2356 cptr = &(cl->ClNext);
2365 cptr = &(DeadStaticIndices);
2366 cl = DeadStaticIndices;
2368 if (!ref_in_use((
DBRef)cl PASS_REGS)) {
2369 char *ocl = (
char *)cl;
2370 if (cl->ClFlags & SwitchTableMask)
2371 Yap_IndexSpace_SW -= cl->ClSize;
2373 Yap_IndexSpace_Tree -= cl->ClSize;
2374 cl = cl->SiblingIndex;
2376 Yap_FreeCodeSpace(ocl);
2378 cptr = &(cl->SiblingIndex);
2379 cl = cl->SiblingIndex;
2387 cptr = &(DeadMegaClauses);
2388 cl = DeadMegaClauses;
2390 if (!ref_in_use((
DBRef)cl PASS_REGS)) {
2391 char *ocl = (
char *)cl;
2392 Yap_ClauseSpace -= cl->ClSize;
2395 Yap_FreeCodeSpace(ocl);
2397 cptr = &(cl->ClNext);
2409 tr_fr_ptr trail_ptr, dest;
2410 Int OldHeapUsed = HeapUsed;
2412 sweep_regs(info->a, old_TR, info->p_env PASS_REGS);
2414#ifndef FROZEN_STACKS
2421 current->cp_b = NULL;
2432 source = dest = (tr_fr_ptr)LOCAL_TrailBase;
2433 while (
source < old_TR) {
2436 while (next &&
source == next->cp_tr) {
2443 trail_cell = TrailTerm(
source);
2444 if (trail_cell != (CELL)
source) {
2460 trail_ptr = (tr_fr_ptr)LOCAL_TrailBase;
2462 while (trail_ptr < old_TR) {
2463 register CELL trail_cell;
2465 trail_cell = TrailTerm(trail_ptr);
2467#ifndef FROZEN_STACKS
2469 if (trail_cell == (CELL)trail_ptr) {
2470 TrailTerm(dest) = trail_cell;
2476 TrailTerm(dest) = trail_cell;
2477 if (IsVarTerm(trail_cell)) {
2480 if ((CELL *)trail_cell < HR && (CELL *)trail_cell >= H0 && MARKED_PTR((CELL *)trail_cell)) {
2481 if (HEAP_PTR(trail_cell)) {
2482 into_relocation_chain(&TrailTerm(dest), GET_NEXT(trail_cell) PASS_REGS);
2487 TrailVal(dest) = TrailVal(trail_ptr);
2488 if (MARKED_PTR(&TrailVal(dest))) {
2489 if (HEAP_PTR(TrailVal(dest))) {
2490 into_relocation_chain(&TrailVal(dest), GET_NEXT(TrailVal(dest)) PASS_REGS);
2494 }
else if (IsPairTerm(trail_cell)) {
2495 CELL *pt0 = RepPair(trail_cell);
2498 if (IN_BETWEEN(LOCAL_GlobalBase, pt0, HR)) {
2499 if (GlobalIsAttVar(pt0)) {
2500 TrailTerm(dest) = trail_cell;
2502 if (HEAP_PTR(TrailTerm(dest))) {
2503 into_relocation_chain(&TrailTerm(dest), GET_NEXT(trail_cell) PASS_REGS);
2506 TrailTerm(dest) = trail_cell;
2508 if (HEAP_PTR(TrailTerm(dest))) {
2509 into_relocation_chain(&TrailTerm(dest), GET_NEXT(trail_cell) PASS_REGS);
2520 (ADDR) pt0 >= LOCAL_GlobalBase
2522 (ADDR) pt0 >= LOCAL_TrailBase
2533 if (!ref_in_use((
DBRef)pt0 PASS_REGS)) {
2535 if (!FlagOn(DBClMask, flags)) {
2538 if (FlagOn(ErasedMask, flags)) {
2542 if (FlagOn(ErasedMask, flags)) {
2547 if (!ref_in_use((
DBRef)pt0 PASS_REGS)) {
2548 if (FlagOn(DBClMask, flags)) {
2550 dbr->Flags &= ~InUseMask;
2551 DEC_DBREF_COUNT(dbr);
2552 if (dbr->Flags & ErasedMask) {
2556 if (flags & LogUpdMask) {
2557 if (flags & IndexMask) {
2558 LogUpdIndex *indx = ClauseFlagsToLogUpdIndex(pt0);
2560#if defined(YAPOR) || defined(THREADS)
2569 DEC_CLREF_COUNT(indx);
2570 indx->ClFlags &= ~InUseMask;
2571 erase = (indx->ClFlags & ErasedMask
2572 && !indx->ClRefCount);
2576 Yap_ErLogUpdIndex(indx);
2578#if defined(YAPOR) || defined(THREADS)
2584#if defined(YAPOR) || defined(THREADS)
2589#if defined(YAPOR) || defined(THREADS)
2593 DEC_CLREF_COUNT(cl);
2594 cl->ClFlags &= ~InUseMask;
2595 erase = ((cl->ClFlags & ErasedMask) && !cl->ClRefCount);
2601#if defined(YAPOR) || defined(THREADS)
2609 DEC_CLREF_COUNT(cl);
2610 cl->ClFlags &= ~InUseMask;
2611 erase = (cl->ClFlags & ErasedMask)
2612#
if defined(YAPOR) || defined(THREADS)
2613 && (cl->ClRefCount == 0)
2623 RESET_VARIABLE(&TrailTerm(dest));
2625 RESET_VARIABLE(&TrailVal(dest));
2627 LOCAL_discard_trail_entries++;
2629#if MULTI_ASSIGNMENT_VARIABLES
2632 CELL trail_cell = TrailTerm(trail_ptr+1);
2633 CELL old = TrailVal(trail_ptr);
2634 CELL old1 = TrailVal(trail_ptr+1);
2635 Int marked_ptr = MARKED_PTR(&TrailTerm(trail_ptr+1));
2636 Int marked_val_old = MARKED_PTR(&TrailVal(trail_ptr));
2637 Int marked_val_ptr = MARKED_PTR(&TrailVal(trail_ptr+1));
2639 TrailTerm(dest+1) = TrailTerm(dest) = trail_cell;
2640 TrailVal(dest) = old;
2641 TrailVal(dest+1) = old1;
2643 UNMARK(&TrailTerm(dest));
2644 UNMARK(&TrailTerm(dest+1));
2645 if (HEAP_PTR(trail_cell)) {
2646 into_relocation_chain(&TrailTerm(dest), GET_NEXT(trail_cell) PASS_REGS);
2647 into_relocation_chain(&TrailTerm(dest+1), GET_NEXT(trail_cell) PASS_REGS);
2650 if (marked_val_old) {
2651 UNMARK(&TrailVal(dest));
2652 if (HEAP_PTR(old)) {
2653 into_relocation_chain(&TrailVal(dest), GET_NEXT(old) PASS_REGS);
2656 if (marked_val_ptr) {
2657 UNMARK(&TrailVal(dest+1));
2658 if (HEAP_PTR(old1)) {
2659 into_relocation_chain(&TrailVal(dest+1), GET_NEXT(old1) PASS_REGS);
2665 CELL trail_cell = TrailTerm(trail_ptr+2);
2666 CELL old = TrailTerm(trail_ptr+1);
2667 Int marked_ptr = MARKED_PTR(&TrailTerm(trail_ptr+2));
2668 Int marked_old = MARKED_PTR(&TrailTerm(trail_ptr+1));
2673 ptr = RepAppl(UNMARK_CELL(trail_cell));
2675 ptr = RepAppl(trail_cell);
2677 TrailTerm(dest+1) = old;
2679 UNMARK(&TrailTerm(dest+1));
2680 if (HEAP_PTR(old)) {
2681 into_relocation_chain(&TrailTerm(dest+1), GET_NEXT(old) PASS_REGS);
2684 TrailTerm(dest+2) = TrailTerm(dest) = trail_cell;
2686 UNMARK(&TrailTerm(dest));
2687 UNMARK(&TrailTerm(dest+2));
2688 if (HEAP_PTR(trail_cell)) {
2689 into_relocation_chain(&TrailTerm(dest), GET_NEXT(trail_cell) PASS_REGS);
2690 into_relocation_chain(&TrailTerm(dest+2), GET_NEXT(trail_cell) PASS_REGS);
2702 LOCAL_new_TR = dest;
2703 if (is_gc_verbose()) {
2704 if (old_TR != (tr_fr_ptr)LOCAL_TrailBase)
2706 "%% Trail: discarded %d (%ld%%) cells out of %ld\n",
2707 LOCAL_discard_trail_entries,
2708 (
unsigned long int)(LOCAL_discard_trail_entries*100/(old_TR-(tr_fr_ptr)LOCAL_TrailBase)),
2709 (
unsigned long int)(old_TR-(tr_fr_ptr)LOCAL_TrailBase));
2713 "%% Trail: unmarked %ld dbentries (%ld%%) out of %ld\n",
2714 (
long int)hp_not_in_use,
2715 (
long int)(hp_not_in_use*100/hp_entrs),
2716 (
long int)hp_entrs);
2717 if (hp_in_use_erased > 0 && hp_erased > 0)
2719 "%% Trail: deleted %ld dbentries (%ld%%) out of %ld\n",
2720 (
long int)hp_erased,
2721 (
long int)(hp_erased*100/(hp_erased+hp_in_use_erased)),
2722 (
long int)(hp_erased+hp_in_use_erased));
2726 "%% Heap: recovered %ld bytes (%ld%%) out of %ld\n",
2727 (
unsigned long int)(OldHeapUsed-HeapUsed),
2728 (
unsigned long int)((OldHeapUsed-HeapUsed)/(OldHeapUsed/100)),
2729 (
unsigned long int)OldHeapUsed);
2732 CleanDeadClauses( PASS_REGS1 );
2742sweep_environments(CELL_PTR gc_ENV,
yamop *pc,
size_t size, CELL *pvbmap USES_REGS)
2745 bool very_verbose = is_gc_very_verbose();
2747 while (gc_ENV != NULL) {
2753 op_numbers op = Yap_op_from_opcode(ENV_ToOp((
yamop*)gc_ENV[E_CP]));
2754#if defined(ANALYST) || defined(DEBUG)
2755 fprintf(stderr,
"sweep env %p-%p(%ld) %s\n", gc_ENV
2756 , pvbmap, size-EnvSizeInCells, Yap_op_names[op]);
2758 fprintf(stderr,
"sweep env %p-%p(%ld) %ld\n", gc_ENV, pvbmap, size-EnvSizeInCells, (
int)op);
2761 fprintf(stderr,
" %s/%ld\n", RepAtom(NameOfFunctor(pe->FunctorOfPred))->StrOfAE, pe->ArityOfPE);
2763 fprintf(stderr,
" %s\n", RepAtom((
Atom)(pe->FunctorOfPred))->StrOfAE);
2766 if (pc->opc == Yap_opcode(_op_fail))
2772 if (size > EnvSizeInCells) {
2773 int tsize = size - EnvSizeInCells;
2776 currv =
sizeof(CELL)*8-tsize%(
sizeof(CELL)*8);
2777 if (pvbmap != NULL) {
2778 pvbmap += tsize/(
sizeof(CELL)*8);
2783 bmap = (Int)(((CELL)bmap) << currv);
2785 for (saved_var = gc_ENV - size; saved_var < gc_ENV - EnvSizeInCells; saved_var++) {
2786 if (currv ==
sizeof(CELL)*8) {
2787 if (pvbmap != NULL) {
2795 if (bmap < 0&& MARKED_PTR(saved_var)) {
2796 CELL env_cell = *saved_var;
2797 if (MARKED_PTR(saved_var)) {
2799 if (HEAP_PTR(env_cell)) {
2800 into_relocation_chain(saved_var, GET_NEXT(env_cell) PASS_REGS);
2811 if (!MARKED_PTR(gc_ENV+E_CB))
2813 UNMARK(gc_ENV+E_CB);
2814 pc= (
yamop *) (gc_ENV[E_CP]);
2817 pvbmap = EnvBMap(pc);
2818 gc_ENV = (CELL_PTR) gc_ENV[E_E];
2824sweep_b(
choiceptr gc_B, UInt arity USES_REGS)
2826 register CELL_PTR saved_reg;
2828 sweep_environments(gc_B->cp_env,gc_B->cp_cp,
2829 EnvSize((
yamop *) (gc_B->cp_cp)),
2830 EnvBMap((
yamop *) (gc_B->cp_cp)) PASS_REGS);
2833 for (saved_reg = &gc_B->cp_a1;
2834 saved_reg < &gc_B->cp_a1 + arity;
2836 CELL cp_cell = *saved_reg;
2837 if (MARKED_PTR(saved_reg)) {
2839 if (HEAP_PTR(cp_cell)) {
2840 into_relocation_chain(saved_reg, GET_NEXT(cp_cell) PASS_REGS);
2852sweep_choicepoints(
choiceptr gc_B USES_REGS)
2860 gc_B = youngest_cp(gc_B, &depfr);
2862 while (gc_B != NULL) {
2863 yamop *rtp = gc_B->cp_ap;
2869 if (aux_sg_fr && gc_B == SgFr_gen_cp(aux_sg_fr)) {
2871 opnum = _table_completion;
2874 opnum = _trust_fail;
2879 opnum = Yap_op_from_opcode(op);
2882 if (aux_sg_fr && gc_B == SgFr_gen_cp(aux_sg_fr)) {
2883 aux_sg_fr = SgFr_next(aux_sg_fr);
2896 if (gc_B->cp_env == LCL0) {
2908 sweep_environments((CELL_PTR)(gc_B->cp_a1),gc_B->cp_cp,
2909 -gc_B->cp_cp->y_u.Osblp.s / ((OPREG)
sizeof(CELL)),
2910 gc_B->cp_cp->y_u.Osblp.bmap
2913 case _retry_profiled:
2915 rtp = NEXTOP(rtp,l);
2917 opnum = Yap_op_from_opcode(op);
2922 opnum = Yap_op_from_opcode(op);
2925 case _table_load_answer:
2927 CELL *vars_ptr, vars;
2928 sweep_environments(gc_B->cp_env, gc_B->cp_cp, EnvSize(gc_B->cp_cp), EnvBMap(gc_B->cp_cp) PASS_REGS);
2929 vars_ptr = (CELL *) (LOAD_CP(gc_B) + 1);
2932 CELL cp_cell = *vars_ptr;
2933 if (MARKED_PTR(vars_ptr)) {
2935 if (HEAP_PTR(cp_cell)) {
2936 into_relocation_chain(vars_ptr, GET_NEXT(cp_cell) PASS_REGS);
2943 case _table_try_answer:
2944 case _table_retry_me:
2945 case _table_trust_me:
2950 CELL *vars_ptr, vars;
2951 sweep_environments(gc_B->cp_env,gc_B->cp_cp, EnvSize(gc_B->cp_cp), EnvBMap(gc_B->cp_cp) PASS_REGS);
2952 vars_ptr = (CELL *)(GEN_CP(gc_B) + 1);
2953 nargs = rtp->y_u.Otapl.s;
2955 CELL cp_cell = *vars_ptr;
2956 if (MARKED_PTR(vars_ptr)) {
2958 if (HEAP_PTR(cp_cell)) {
2959 into_relocation_chain(vars_ptr, GET_NEXT(cp_cell) PASS_REGS);
2966 CELL cp_cell = *vars_ptr;
2967 if (MARKED_PTR(vars_ptr)) {
2969 if (HEAP_PTR(cp_cell)) {
2970 into_relocation_chain(vars_ptr, GET_NEXT(cp_cell) PASS_REGS);
2977 case _table_completion:
2978#ifdef THREADS_CONSUMER_SHARING
2979 case _table_answer_resolution_completion:
2983 CELL *vars_ptr, vars;
2984#ifdef DETERMINISTIC_TABLING
2985 if (IS_DET_GEN_CP(gc_B))
2986 vars_ptr = (CELL *)(DET_GEN_CP(gc_B) + 1);
2990 sweep_environments(gc_B->cp_env,gc_B->cp_cp, EnvSize(gc_B->cp_cp), EnvBMap(gc_B->cp_cp) PASS_REGS);
2991 vars_ptr = (CELL *)(GEN_CP(gc_B) + 1);
2992 nargs = SgFr_arity(GEN_CP(gc_B)->cp_sg_fr);
2994 CELL cp_cell = *vars_ptr;
2995 if (MARKED_PTR(vars_ptr)) {
2997 if (HEAP_PTR(cp_cell)) {
2998 into_relocation_chain(vars_ptr, GET_NEXT(cp_cell) PASS_REGS);
3006 CELL cp_cell = *vars_ptr;
3007 if (MARKED_PTR(vars_ptr)) {
3009 if (HEAP_PTR(cp_cell)) {
3010 into_relocation_chain(vars_ptr, GET_NEXT(cp_cell) PASS_REGS);
3017 case _table_answer_resolution:
3019 CELL *vars_ptr, vars;
3020 dep_fr_ptr dep_fr = CONS_CP(gc_B)->cp_dep_fr;
3022 if (TRUE || TrNode_child(ans_node)) {
3024#ifdef MODE_DIRECTED_TABLING
3025 if (TrNode_child(ans_node) && IS_ANSWER_INVALID_NODE(TrNode_child(ans_node))) {
3027 old_ans_node = ans_node;
3028 ans_node = TrNode_child(ans_node);
3030 ans_node = TrNode_child(ans_node);
3031 }
while (IS_ANSWER_INVALID_NODE(ans_node));
3032 TrNode_child(old_ans_node) = ans_node;
3035 ans_node = TrNode_child(ans_node);
3036 if (gc_B == DepFr_leader_cp(dep_fr)) { \
3039 TABLING_ERROR_CHECKING(generator_consumer, IS_BATCHED_GEN_CP(gc_B));
3040 vars_ptr = (CELL *) (GEN_CP(gc_B) + 1);
3041 vars_ptr += SgFr_arity(GEN_CP(gc_B)->cp_sg_fr);
3043 vars_ptr = (CELL *) (CONS_CP(gc_B) + 1); \
3045 sweep_environments(gc_B->cp_env, gc_B->cp_cp,EnvSize(gc_B->cp_cp), EnvBMap(gc_B->cp_cp) PASS_REGS);
3048 CELL cp_cell = *vars_ptr;
3049 if (MARKED_PTR(vars_ptr)) {
3051 if (HEAP_PTR(cp_cell)) {
3052 into_relocation_chain(vars_ptr, GET_NEXT(cp_cell) PASS_REGS);
3060 case _trie_trust_var:
3061 case _trie_retry_var:
3062 case _trie_trust_var_in_pair:
3063 case _trie_retry_var_in_pair:
3064 case _trie_trust_val:
3065 case _trie_retry_val:
3066 case _trie_trust_val_in_pair:
3067 case _trie_retry_val_in_pair:
3068 case _trie_trust_atom:
3069 case _trie_retry_atom:
3070 case _trie_trust_atom_in_pair:
3071 case _trie_retry_atom_in_pair:
3072 case _trie_trust_null:
3073 case _trie_retry_null:
3074 case _trie_trust_null_in_pair:
3075 case _trie_retry_null_in_pair:
3076 case _trie_trust_pair:
3077 case _trie_retry_pair:
3078 case _trie_trust_appl:
3079 case _trie_retry_appl:
3080 case _trie_trust_appl_in_pair:
3081 case _trie_retry_appl_in_pair:
3082 case _trie_trust_extension:
3083 case _trie_retry_extension:
3084 case _trie_trust_double:
3085 case _trie_retry_double:
3086 case _trie_trust_longint:
3087 case _trie_retry_longint:
3088 case _trie_trust_gterm:
3089 case _trie_retry_gterm:
3092 int heap_arity, vars_arity, subs_arity;
3093 sweep_environments(gc_B->cp_env,gc_B->cp_cp, EnvSize(gc_B->cp_cp), EnvBMap(gc_B->cp_cp) PASS_REGS);
3094 vars_ptr = (CELL *)(gc_B + 1);
3095 heap_arity = vars_ptr[0];
3096 vars_arity = vars_ptr[1 + heap_arity];
3097 subs_arity = vars_ptr[2 + heap_arity + vars_arity];
3098 vars_ptr += 2 + heap_arity + subs_arity + vars_arity;
3100 while (subs_arity--) {
3101 CELL cp_cell = *vars_ptr;
3102 if (MARKED_PTR(vars_ptr)) {
3104 if (HEAP_PTR(cp_cell)) {
3105 into_relocation_chain(vars_ptr, GET_NEXT(cp_cell) PASS_REGS);
3113 while (vars_arity--) {
3114 CELL cp_cell = *vars_ptr;
3115 if (MARKED_PTR(vars_ptr)) {
3117 if (HEAP_PTR(cp_cell)) {
3118 into_relocation_chain(vars_ptr, GET_NEXT(cp_cell) PASS_REGS);
3126 while (heap_arity--) {
3127 CELL cp_cell = *vars_ptr;
3130 if (MARKED_PTR(vars_ptr)) {
3132 if (HEAP_PTR(cp_cell)) {
3133 into_relocation_chain(vars_ptr, GET_NEXT(cp_cell) PASS_REGS);
3143 case _retry_logical:
3144 case _count_retry_logical:
3145 case _profiled_retry_logical:
3147 sweep_b(gc_B, rtp->y_u.OtaLl.s+1 PASS_REGS);
3149 case _trust_logical:
3150 case _count_trust_logical:
3151 case _profiled_trust_logical:
3152 sweep_b(gc_B, rtp->y_u.OtILl.d->ClPred->ArityOfPE+1 PASS_REGS);
3155 sweep_b(gc_B, 2 PASS_REGS);
3158 sweep_b(gc_B, 3 PASS_REGS);
3161 sweep_b(gc_B, 4 PASS_REGS);
3164 sweep_b(gc_B, rtp->y_u.p.p->ArityOfPE PASS_REGS);
3167 case _retry_exo_udi:
3168 case _retry_all_exo:
3169 sweep_b(gc_B, rtp->y_u.lp.p->ArityOfPE PASS_REGS);
3174 register CELL_PTR saved_reg;
3177 for (saved_reg = &(gc_B->cp_a1)+rtp->y_u.OtapFs.s;
3178 saved_reg < &(gc_B->cp_a1)+rtp->y_u.OtapFs.s+rtp->y_u.OtapFs.extra;
3180 CELL cp_cell = *saved_reg;
3181 if (MARKED_PTR(saved_reg)) {
3183 if (HEAP_PTR(cp_cell)) {
3184 into_relocation_chain(saved_reg, GET_NEXT(cp_cell) PASS_REGS);
3191 sweep_b(gc_B,rtp->y_u.Otapl.s PASS_REGS);
3196 gc_B = youngest_cp(gc_B->cp_b, &depfr);
3208update_relocation_chain(CELL_PTR current, CELL_PTR dest USES_REGS)
3211 CELL ccur = *current;
3213 int rmarked = RMARKED(current);
3218 next = GET_NEXT(ccur);
3219 current_tag = TAG(ccur);
3221 rmarked = RMARKED(next);
3223 *next = (CELL) dest | current_tag;
3229update_B_H(
choiceptr gc_B, CELL *current, CELL *dest, CELL *odest
3241 while (gc_B && current <= gc_B->cp_h) {
3242 if (gc_B->cp_h == current) {
3250 if (depfr && gc_B >= DepFr_cons_cp(depfr)) {
3251 gc_B = DepFr_cons_cp(depfr);
3252 *depfrp = depfr = DepFr_next(depfr);
3274compact_heap( USES_REGS1 )
3276 CELL_PTR dest, current, next;
3278 Int found_marked = 0;
3282 CELL *start_from = H0;
3296 if (depfr && gc_B >= DepFr_cons_cp(depfr)) {
3297 gc_B = DepFr_cons_cp(depfr);
3298 depfr = DepFr_next(depfr);
3301 next_hb = set_next_hb(gc_B PASS_REGS);
3302 dest = H0 + LOCAL_total_marked-1 ;
3304 gc_B = update_B_H(gc_B, HR, dest+1, dest+2
3309 for (current = HR - 1, previous=HR-1; current >= start_from; current--) {
3310 if (MARKED_PTR(current)) {
3311 if (current <= next_hb) {
3312 gc_B = update_B_H(gc_B, current, dest, dest + 1
3317 next_hb = set_next_hb(gc_B PASS_REGS);
3320 if (XMARKED(current)) {
3323 current = (CELL *)AtomOfTerm(*current);
3324 UInt nofcells = (previous - current);
3329 found_marked+=nofcells;
3334 update_relocation_chain(current, dest PASS_REGS);
3335 if (HEAP_PTR(*current)) {
3336 next = GET_NEXT(*current);
3339 into_relocation_chain(current, next PASS_REGS);
3340 else if (current == next) {
3343 *current = (CELL) dest;
3356 if (dest != start_from-1)
3357 fprintf(stderr,
"%% Bad Dest (%lu): %p should be %p\n",
3358 (
unsigned long int)LOCAL_GcCalls,
3361 if (LOCAL_total_marked != found_marked)
3362 fprintf(stderr,
"%% Upward (%lu): %lu total against %lu found\n",
3363 (
unsigned long int)LOCAL_GcCalls,
3364 (
unsigned long int)LOCAL_total_marked,
3365 (
unsigned long int)found_marked);
3366 found_marked = start_from-H0;
3377 found_marked= LOCAL_total_marked;
3381 for (current = H0; current < HR; current++) {
3382 if (MARKED_PTR(current)) {
3383 bool xmark = XMARKED(current);
3384 update_relocation_chain(current, dest PASS_REGS);
3385 CELL ccur = *current;
3386 next = GET_NEXT(ccur);
3387 if (HEAP_PTR(ccur) &&
3388 (next = GET_NEXT(ccur)) < HR &&
3392 into_relocation_chain(dest, next PASS_REGS);
3396 *dest = ccur = UNMARK_CELL(ccur);
3400 CELL *dest0 = dest++;
3401 CELL *previous = current++;
3404 while (!XMARKED(current))
3405 *dest++ = *current++;
3406 if (LOCAL_OpenArray) {
3407 if (LOCAL_OpenArray < current &&
3408 LOCAL_OpenArray > previous) {
3409 UInt off = LOCAL_OpenArray - previous;
3410 LOCAL_OpenArray = dest + off;
3421 *dest = CloseExtension(dest0);
3431 if (0 != found_marked)
3432 fprintf(stderr,
"%% Downward (%lu): %lu total against %lu found\n",
3433 (
unsigned long int)LOCAL_GcCalls,
3434 (
unsigned long int)LOCAL_total_marked,
3435 (
unsigned long int)(LOCAL_total_marked-found_marked));
3455icompact_heap( USES_REGS1 )
3457 CELL_PTR *iptr, *ibase = (CELL_PTR *)HR;
3461 Int found_marked = 0;
3475 if (depfr && gc_B >= DepFr_cons_cp(depfr)) {
3476 gc_B = DepFr_cons_cp(depfr);
3477 depfr = DepFr_next(depfr);
3480 next_hb = set_next_hb(gc_B PASS_REGS);
3481 dest = (CELL_PTR) H0 + LOCAL_total_marked - 1;
3482 gc_B = update_B_H(gc_B, HR, dest+1, dest+2
3487 for (iptr = LOCAL_iptop - 1; iptr >= ibase; iptr--) {
3493 if (current <= next_hb) {
3494 gc_B = update_B_H(gc_B, current, dest, dest+1
3499 next_hb = set_next_hb(gc_B PASS_REGS);
3501 if (IsEndExtension(current)) {
3508 nofcells = current-ptr;
3510 found_marked+=(nofcells+1);
3515 current[0] = ptr[0];
3516 ptr[0] = CloseExtension(current);
3523 update_relocation_chain(current, dest PASS_REGS);
3524 if (HEAP_PTR(*current)) {
3526 next = GET_NEXT(*current);
3529 into_relocation_chain(current, next PASS_REGS);
3530 else if (current == next) {
3533 *current = (CELL) dest;
3541 fprintf(stderr,
"%% Bad Dest (%lu): %p should be %p\n",
3542 (
unsigned long int)LOCAL_GcCalls,
3545 if (LOCAL_total_marked != found_marked)
3546 fprintf(stderr,
"%% Upward (%lu): %lu total against %lu found\n",
3547 (
unsigned long int)LOCAL_GcCalls,
3548 (
unsigned long int)LOCAL_total_marked,
3549 (
unsigned long int)found_marked);
3561 for (iptr = ibase; iptr < LOCAL_iptop; iptr++) {
3563 CELL *current = *iptr;
3564 CELL ccur = *current;
3566 if (IsEndExtension(current)) {
3567 CELL *old_dest = dest;
3572 while (!MARKED_PTR(current)) {
3573 *dest++ = *current++;
3576 *old_dest = *current;
3577 *dest++ = CloseExtension(old_dest);
3579 found_marked += dest-old_dest;
3586 update_relocation_chain(current, dest PASS_REGS);
3588 next = GET_NEXT(ccur);
3589 if (HEAP_PTR(ccur) &&
3593 into_relocation_chain(dest, next PASS_REGS);
3598 *dest++ = ccur = UNMARK_CELL(ccur);
3602 if (H0+LOCAL_total_marked != dest)
3603 fprintf(stderr,
"%% Downward (%lu): %p total against %p found\n",
3604 (
unsigned long int)LOCAL_GcCalls,
3605 H0+LOCAL_total_marked,
3607 if (LOCAL_total_marked != found_marked)
3608 fprintf(stderr,
"%% Downward (%lu): %lu total against %lu found\n",
3609 (
unsigned long int)LOCAL_GcCalls,
3610 (
unsigned long int)LOCAL_total_marked,
3611 (
unsigned long int)found_marked);
3629set_conditionals(tr_fr_ptr str USES_REGS) {
3630 while (str != LOCAL_sTR0) {
3633 cptr = (CELL *)TrailTerm(str+1);
3634 *cptr = TrailTerm(str);
3636 LOCAL_sTR = LOCAL_sTR0 = NULL;
3651 LOCAL_current_B = B;
3654 init_dbtable(old_TR PASS_REGS);
3656 LOCAL_sTR0 = (tr_fr_ptr)LOCAL_db_vec;
3657 LOCAL_sTR = (tr_fr_ptr)LOCAL_db_vec;
3660 LOCAL_cont_top0 = (
cont *)LOCAL_db_vec;
3662 LOCAL_cont_top = (
cont *)LOCAL_db_vec;
3665 mark_regs(info->a, old_TR, info->p_env PASS_REGS);
3667 mark_environments(info->env, info->p_env, info->env_size, EnvBMap(info->p_env) PASS_REGS);
3668 mark_choicepoints(B, old_TR, is_gc_very_verbose() PASS_REGS);
3670 set_conditionals(LOCAL_sTR PASS_REGS);
3675sweep_oldgen(CELL *max, CELL *base USES_REGS)
3678 char *bpb = LOCAL_bp+(base-(CELL*)LOCAL_GlobalBase);
3682 if (HEAP_PTR(*ptr)) {
3683 into_relocation_chain(ptr, GET_NEXT(*ptr) PASS_REGS);
3700 CELL *CurrentH0 = H0;
3702 int icompact =
false && (LOCAL_iptop < (CELL_PTR *)ASP && 10*LOCAL_total_marked < HR-H0);
3706 if (LOCAL_HGEN != H0) {
3708 LOCAL_total_marked += LOCAL_total_oldies;
3712 if (LOCAL_HGEN != H0) {
3715 sweep_oldgen(LOCAL_HGEN, CurrentH0 PASS_REGS);
3718 sweep_environments(info->env, info->p_env, info->env_size, EnvBMap(info->p_env) PASS_REGS);
3719 sweep_choicepoints(B PASS_REGS);
3720 sweep_trail(B, old_TR, info PASS_REGS);
3722 if (
false && icompact) {
3734 int effectiveness = (((H-H0)-LOCAL_total_marked)*100)/(H-H0);
3735 fprintf(stderr,
"%% using pointers (%d)\n", effectiveness);
3740 LOCAL_total_marked += LOCAL_total_oldies;
3743 quicksort((CELL_PTR *)HR, 0, (LOCAL_iptop-(CELL_PTR *)HR)-1);
3744 icompact_heap( PASS_REGS1 );
3757 compact_heap( PASS_REGS1 );
3774 volatile tr_fr_ptr old_TR = NULL;
3775 UInt m_time, c_time, time_start, gc_time;
3776 Int effectiveness, tot;
3782Int predarity = info->a;
3783CELL *current_env = info->env;
3784yamop *nextop = info->p_env;
3787 gc_verbose = is_gc_verbose();
3791 #ifdef INSTRUMENT_GC
3794 for (i=0; i<16; i++)
3806 old_vars = new_vars = 0;
3814 if (gcTrace() != TermOff)
3817 fprintf(stderr,
"%% gc\n");
3818 }
else if (gc_verbose) {
3819#if defined(YAPOR) || defined(THREADS)
3820 fprintf(stderr,
"%% Worker Id %d:\n", worker_id);
3822 fprintf(stderr,
"%% Start of garbage collection %lu:\n", (
unsigned long int)LOCAL_GcCalls);
3823 fprintf(stderr,
"%% Global: %8ld cells (%p-%p)\n", (
long int)heap_cells,H0,HR);
3824 fprintf(stderr,
"%% Local:%8ld cells (%p-%p)\n", (
unsigned long int)(LCL0-ASP),LCL0,ASP);
3825 fprintf(stderr,
"%% Trail:%8ld cells (%p-%p)\n",
3826 (
unsigned long int)(TR-(tr_fr_ptr)LOCAL_TrailBase),LOCAL_TrailBase,TR);
3828#if !USE_SYSTEM_MALLOC
3829 if (HeapTop >= LOCAL_GlobalBase - MinHeapGap) {
3830 *H++ = (CELL)current_env;
3831 if (!Yap_locked_growheap(FALSE, MinHeapGap, NULL)) {
3832 Yap_Error(RESOURCE_ERROR_HEAP, TermNil, LOCAL_ErrorMessage);
3835 current_env = (CELL *)*--HR;
3838 time_start = Yap_cputime();
3839 jmp_res = sigsetjmp(jmp, 0);
3844 restore_machine_regs();
3845 sz = LOCAL_TrailTop-(ADDR)LOCAL_OldTR;
3850 *HR++ = (CELL)current_env;
3852 !Yap_locked_growtrail(sz, FALSE)
3854 Yap_Error(RESOURCE_ERROR_TRAIL,TermNil,
"out of %lB during gc", sz);
3857 LOCAL_total_marked = 0;
3858 LOCAL_total_oldies = 0;
3860 LOCAL_total_smarked = 0;
3862 LOCAL_discard_trail_entries = 0;
3863 current_env = (CELL *)*--HR;
3865 }
else if (jmp_res == 3) {
3867 restore_machine_regs();
3870 LOCAL_total_marked = 0;
3871 LOCAL_total_oldies = 0;
3873 LOCAL_total_smarked = 0;
3875 LOCAL_discard_trail_entries = 0;
3876 if (LOCAL_extra_gc_cells_size < 1024 *104) {
3877 LOCAL_extra_gc_cells_size <<= 1;
3879 LOCAL_extra_gc_cells_size += 1024*1024;
3881 }
else if (jmp_res == 4) {
3886 LOCAL_sTR0 = LOCAL_sTR = NULL;
3888 LOCAL_total_marked = 0;
3889 LOCAL_total_oldies = 0;
3891 LOCAL_total_smarked = 0;
3893 LOCAL_discard_trail_entries = 0;
3894 alloc_sz = (CELL *)LOCAL_TrailTop-(CELL*)LOCAL_GlobalBase;
3895 LOCAL_bp = Yap_PreAllocCodeSpace();
3896 while (IN_BETWEEN(LOCAL_bp, AuxSp, LOCAL_bp+alloc_sz)) {
3898 *HR++ = (CELL)current_env;
3899 LOCAL_bp = (
char *)Yap_ExpandPreAllocCodeSpace(alloc_sz, NULL, TRUE);
3902 current_env = (CELL *)*--HR;
3904 memset((
void *)LOCAL_bp, 0, alloc_sz);
3906 LOCAL_iptop = (CELL_PTR *)HR;
3913 if (gc_phase != LOCAL_GcCurrentPhase) {
3917 LOCAL_OldTR = old_TR = push_registers(predarity, count,nextop PASS_REGS);
3919 marking_phase(old_TR, info PASS_REGS);
3925 if (LOCAL_total_oldies > ((LOCAL_HGEN-H0)*8)/10) {
3926 LOCAL_total_marked -= LOCAL_total_oldies;
3927 tot = LOCAL_total_marked+(LOCAL_HGEN-H0);
3929 if (LOCAL_HGEN != H0) {
3931 LOCAL_GcCurrentPhase++;
3933 tot = LOCAL_total_marked;
3935 m_time = Yap_cputime();
3936 gc_time = m_time-time_start;
3938 if (heap_cells > 1000000)
3939 effectiveness = (heap_cells-tot)/(heap_cells/100);
3941 effectiveness = 100*(heap_cells-tot)/heap_cells;
3945 fprintf(stderr,
"%% Mark: Marked %ld cells of %ld (efficiency: %ld%%) in %g sec\n",
3946 (
long int)tot, (
long int)heap_cells, (
long int)effectiveness, (
double)(m_time-time_start)/1000);
3948 fprintf(stderr,
"%% previous generation has size " UInt_FORMAT
", with " UInt_FORMAT
" (" UInt_FORMAT
"%%) unmarked\n", (UInt)(LOCAL_HGEN-H0), (UInt)((LOCAL_HGEN-H0)-LOCAL_total_oldies), (UInt)(100*((LOCAL_HGEN-H0)-LOCAL_total_oldies)/(LOCAL_HGEN-H0)));
3952 for (i=0; i<16; i++) {
3954 fprintf(stderr,
"%% chain[%d]=%lu\n", i, chain[i]);
3957 put_type_info((
unsigned long int)tot);
3958 fprintf(stderr,
"%% %lu/%ld before and %lu/%ld after\n", old_vars, (
unsigned long int)(B->cp_h-H0), new_vars, (
unsigned long int)(H-B->cp_h));
3959 fprintf(stderr,
"%% %ld choicepoints\n", num_bs);
3963 time_start = m_time;
3964 compaction_phase(old_TR, info PASS_REGS);
3965 pop_registers(predarity, old_TR, nextop PASS_REGS);
3974c_time = Yap_cputime();
3976 fprintf(stderr,
"%% Compress: took %g sec\n", (
double)(c_time-time_start)/1000);
3978 gc_time += (c_time-time_start);
3979 LOCAL_TotGcTime += gc_time;
3980 LOCAL_TotGcRecovered += heap_cells-tot;
3982 fprintf(stderr,
"%% GC %lu took %g sec, total of %g sec doing GC so far.\n", (
unsigned long int)LOCAL_GcCalls, (
double)gc_time/1000, (
double)LOCAL_TotGcTime/1000);
3983 fprintf(stderr,
"%% Left %ld cells free in stacks.\n",
3984 (
unsigned long int)(ASP-HR));
3991 return effectiveness;
3998 if (LOCAL_PrologMode == BootMode)
4005 return t == TermVerbose || t == TermVeryVerbose;
4010Yap_is_gc_verbose(
void)
4012 return is_gc_verbose();
4016is_gc_very_verbose(
void)
4019 if (LOCAL_PrologMode == BootMode)
4021 return gcTrace() == TermVeryVerbose;
4025Yap_total_gc_time(
void)
4028 return(LOCAL_TotGcTime);
4032p_inform_gc( USES_REGS1 )
4034 Term tn = MkIntegerTerm(LOCAL_TotGcTime);
4035 Term tt = MkIntegerTerm(LOCAL_GcCalls);
4036 Term ts = Yap_Mk64IntegerTerm((LOCAL_TotGcRecovered*
sizeof(CELL)));
4038 return(Yap_unify(tn, ARG2) && Yap_unify(tt, ARG1) && Yap_unify(ts, ARG3));
4048 Int effectiveness = 0;
4049 int gc_on = FALSE, gc_t = FALSE;
4051 if (trueGlobalPrologFlag(GC_FLAG) && IsIntTerm(getAtomicGlobalPrologFlag(GC_MARGIN_FLAG)))
4054 CalculateStackGap( PASS_REGS1 );
4059 if (IsIntegerTerm(Tgc_margin = getAtomicGlobalPrologFlag(GC_MARGIN_FLAG)) &&
4061 gc_margin = (UInt)IntegerOfTerm(Tgc_margin);
4065 if (LOCAL_GcCalls < 8)
4075 if (gc_margin < info->gc_min)
4078 if (gc_on && !(LOCAL_PrologMode & InErrorMode) &&
4080 (ASP-H0)*
sizeof(CELL) > info->gc_min &&
4081 HR-H0 > (LCL0-ASP)/2) {
4082 effectiveness = do_gc(info PASS_REGS);
4083 if (effectiveness < 0)
4085 if (effectiveness > 90 && !gc_t) {
4086 while (
gc_margin < (HR-H0)/
sizeof(CELL))
4093 if (ASP - HR <
gc_margin/
sizeof(CELL) ||
4094 effectiveness < 20) {
4095 LeaveGCMode( PASS_REGS1 );
4099 CalculateStackGap( PASS_REGS1 );
4111LeaveGCMode( USES_REGS1 )
4113 if (LOCAL_PrologMode & GCMode)
4114 LOCAL_PrologMode &= ~GCMode;
4115 if (LOCAL_PrologMode & AbortMode) {
4116 LOCAL_PrologMode &= ~AbortMode;
4118 Yap_Error(ABORT_EVENT, TermNil,
"abort from console");
4119 Yap_RestartYap( 1 );
4123bool Yap_dogc( USES_REGS1 ) {
4126 Yap_track_cpred(0, P, 0, p);
4127 LOCAL_PrologMode |= GCMode;
4129 LeaveGCMode( PASS_REGS1 );
4130 if (LOCAL_PrologMode & GCMode)
4131 LOCAL_PrologMode &= ~GCMode;
4135bool Yap_dogcl(
size_t minsz USES_REGS ) {
4138 Yap_track_cpred(0, P, 0, p);
4140 LOCAL_PrologMode |= GCMode;
4142 LeaveGCMode( PASS_REGS1 );
4143 if (LOCAL_PrologMode & GCMode)
4144 LOCAL_PrologMode &= ~GCMode;
4148bool Yap_gc(
void *p0 ) {
4151 LOCAL_PrologMode |= GCMode;
4153 LeaveGCMode( PASS_REGS1 );
4154 if (LOCAL_PrologMode & GCMode)
4155 LOCAL_PrologMode &= ~GCMode;
4162Yap_gcl(
size_t gc_lim,
void *p)
4169 CalculateStackGap( PASS_REGS1 );
4170 min = EventFlag*
sizeof(CELL);
4173 info->gc_min = gc_lim;
4174 LOCAL_PrologMode |= GCMode;
4176 res = call_gc(info PASS_REGS);
4177 LeaveGCMode( PASS_REGS1 );
4181garbage_collect( USES_REGS1 )
4184 LOCAL_PrologMode |= GCMode;
4186 Yap_track_cpred(0, P, 0, p);
4187 CalculateStackGap( PASS_REGS1 );
4188 i.gc_min = EventFlag*
sizeof(CELL);
4189 res = call_gc(p PASS_REGS) >= 0;
4190 LeaveGCMode( PASS_REGS1 );
4197 Yap_InitCPred(
"garbage_collect", 0, garbage_collect, 0);
4198 Yap_InitCPred(
"$inform_gc", 3, p_inform_gc, 0);
4202Yap_inc_mark_variable()
4205 LOCAL_total_marked++;
@ source
If true maintain the source for all clauses.
@ gc_margin
controls when to do garbage collection
@ gc_trace
show activity in garbag collector
PredEntry * Yap_PredForChoicePt(choiceptr cp, op_numbers *op)
Yap_v<<ChoicePt(): find out the predicate who generated a CP.