00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef MULTI_THREAD
00027 extern Structure_Manager smTSTN;
00028 #endif
00029
00030 extern Structure_Manager smTableBTN;
00031 extern Structure_Manager smAssertBTN;
00032 extern PrRef dynpredep_to_prref(CTXTdeclc void *pred_ep);
00033 extern ClRef db_get_clause_code_space(PrRef, ClRef, CPtr *, CPtr *);
00034 extern void mark_findall_strings(CTXTdecl);
00035 extern void mark_open_filenames();
00036 extern void mark_hash_table_strings(CTXTdecl);
00037
00038 #ifdef INDIRECTION_SLIDE
00039 #define TO_BUFFER(ptr) \
00040 { \
00041 if (slide_buffering) { \
00042 slide_buf[slide_top] = ptr; \
00043 slide_top++; \
00044 slide_buffering = slide_top <= slide_buf_size; \
00045 } \
00046 }
00047 #else
00048 #define TO_BUFFER(ptr)
00049 #endif
00050
00051 #ifdef GC_PROFILE
00052 #define h_mark(i) \
00053 do { \
00054 CPtr cell_ptr; int place;\
00055 place = i;\
00056 cell_ptr = (CPtr) heap_bot + place;\
00057 inspect_ptr(cell_ptr); \
00058 heap_marks[place] |= MARKED;\
00059 } while (0)
00060 #else
00061 #define h_mark(i) heap_marks[i] |= MARKED
00062 #endif
00063
00064 #define h_marked(i) (heap_marks[i])
00065 #define h_clear_mark(i) heap_marks[i] &= ~MARKED
00066
00067 #define ls_marked(i) (ls_marks[i])
00068 #ifdef GC_PROFILE
00069 #define ls_mark(i) \
00070 do { \
00071 int tag, place; \
00072 CPtr ptr; \
00073 place = i; \
00074 ptr = (CPtr) ls_top + place; \
00075 tag = cell_tag(*ptr); \
00076 inspect_chain(ptr); \
00077 ls_marks[place] |= MARKED; \
00078 } while (0)
00079 #else
00080 #define ls_mark(i) ls_marks[i] |= MARKED
00081 #endif
00082 #define ls_clear_mark(i) ls_marks[i] = 0
00083
00084 #define tr_marked(i) (tr_marks[i])
00085 #define tr_mark(i) tr_marks[i] |= MARKED
00086 #define tr_clear_mark(i) tr_marks[i] &= ~MARKED
00087 #define tr_mark_pre(i) tr_marks[i] |= TRAIL_PRE
00088 #define tr_clear_pre_mark(i) tr_marks[i] &= ~TRAIL_PRE
00089 #define tr_pre_marked(i) (tr_marks[i] & TRAIL_PRE)
00090
00091 #define cp_marked(i) (cp_marks[i])
00092 #define cp_mark(i) cp_marks[i] |= MARKED
00093 #define cp_clear_mark(i) cp_marks[i] &= ~MARKED
00094
00095
00096
00097 #ifdef GC
00098 inline static CPtr hp_pointer_from_cell(Cell cell, int *tag)
00099 {
00100 int t;
00101 CPtr retp;
00102
00103 t = cell_tag(cell) ;
00104
00105
00106
00107 if (t == XSB_LIST)
00108 {
00109 *tag = XSB_LIST;
00110 retp = clref_val(cell);
00111 testreturnit(retp);
00112 }
00113 if (t == XSB_STRUCT)
00114 {
00115 *tag = XSB_STRUCT;
00116 retp = (CPtr)(cs_val(cell));
00117 testreturnit(retp);
00118 }
00119 if ((t == XSB_REF) || (t == XSB_REF1))
00120 {
00121 *tag = t;
00122 retp = (CPtr)cell ;
00123 if (points_into_heap(retp)) return(retp);
00124 }
00125 if (t == XSB_ATTV)
00126 {
00127 *tag = XSB_ATTV;
00128 retp = clref_val(cell);
00129 testreturnit(retp);
00130 }
00131
00132 return NULL;
00133 }
00134 #endif
00135
00136 static CPtr pointer_from_cell(Cell cell, int *tag, int *whereto)
00137 { int t ;
00138 CPtr retp ;
00139
00140 *tag = t = cell_tag(cell) ;
00141 switch (t)
00142 {
00143 case XSB_REF:
00144 case XSB_REF1:
00145 retp = (CPtr)cell ;
00146 break ;
00147 case XSB_LIST:
00148 case XSB_ATTV:
00149 retp = clref_val(cell) ;
00150 break ;
00151 case XSB_STRUCT:
00152 retp = ((CPtr)(cs_val(cell))) ;
00153 break ;
00154 default:
00155 *whereto = TO_NOWHERE ;
00156 return((CPtr)cell) ;
00157 }
00158
00159 if (points_into_heap(retp)) *whereto = TO_HEAP ;
00160 else
00161 if (points_into_tr(retp)) *whereto = TO_TR ;
00162 else
00163 if (points_into_ls(retp)) *whereto = TO_LS ;
00164 else
00165 if (points_into_cp(retp)) *whereto = TO_CP ;
00166 else
00167 if (points_into_compl(retp)) *whereto = TO_COMPL ;
00168 else *whereto = TO_NOWHERE ;
00169 return(retp) ;
00170
00171 }
00172
00173
00174
00175 inline static char * pr_h_marked(CPtr cell_ptr)
00176 { int i ;
00177 i = cell_ptr - heap_bot ;
00178 if (heap_marks == NULL) return("not_m") ;
00179 if (h_marked(i) == MARKED) return("marked") ;
00180 if (h_marked(i) == CHAIN_BIT) return("chained") ;
00181 if (h_marked(i) == (CHAIN_BIT | MARKED)) return("chained+marked") ;
00182 return("not_m") ;
00183 }
00184
00185 inline static char * pr_ls_marked(CPtr cell_ptr)
00186 { int i ;
00187 i = cell_ptr - ls_top ;
00188 if (ls_marks == NULL) return("not_m") ;
00189 if (ls_marked(i) == MARKED) return("marked") ;
00190 if (ls_marked(i) == CHAIN_BIT) return("chained") ;
00191 if (ls_marked(i) == (CHAIN_BIT | MARKED)) return("chained+marked") ;
00192 return("not_m") ;
00193 }
00194
00195 inline static char * pr_cp_marked(CPtr cell_ptr)
00196 { int i ;
00197 i = cell_ptr - cp_top ;
00198 if (cp_marks == NULL) return("not_m") ;
00199 if (cp_marked(i) == MARKED) return("marked") ;
00200 if (cp_marked(i) == CHAIN_BIT) return("chained") ;
00201 if (cp_marked(i) == (CHAIN_BIT | MARKED)) return("chained+marked") ;
00202 return("not_m") ;
00203 }
00204
00205 inline static char * pr_tr_marked(CPtr cell_ptr)
00206 { int i ;
00207 i = cell_ptr - tr_bot ;
00208 if (tr_marks == NULL) return("not_m") ;
00209 if (tr_marked(i) == MARKED) return("marked") ;
00210 if (tr_marked(i) == CHAIN_BIT) return("chained") ;
00211 if (tr_marked(i) == (CHAIN_BIT | MARKED)) return("chained+marked") ;
00212 if (tr_marked(i) == (CHAIN_BIT | MARKED | TRAIL_PRE))
00213 return("chained+marked+pre");
00214 return("not_m") ;
00215 }
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226 #define MAXS 3700
00227 #define push_to_mark(p) mark_stack[mark_top++] = p
00228 #define mark_overflow (mark_top >= MAXS)
00229 static int mark_cell(CPtr cell_ptr)
00230 {
00231 CPtr p ;
00232 Cell cell_val ;
00233 Integer i;
00234 int m, arity, tag ;
00235 int mark_top = 0 ;
00236 CPtr mark_stack[MAXS+MAX_ARITY+1] ;
00237
00238 m = 0 ;
00239 mark_more:
00240 if (!points_into_heap(cell_ptr))
00241 goto pop_more ;
00242 safe_mark_more:
00243 i = cell_ptr - heap_bot ;
00244 if (h_marked(i)) goto pop_more ;
00245 TO_BUFFER(cell_ptr);
00246 h_mark(i) ;
00247 m++ ;
00248
00249 cell_val = *cell_ptr;
00250 tag = cell_tag(cell_val);
00251
00252
00253 if (tag == XSB_LIST || tag == XSB_ATTV)
00254 { cell_ptr = clref_val(cell_val) ;
00255 if (mark_overflow)
00256 { m += mark_cell(cell_ptr+1) ; }
00257 else push_to_mark(cell_ptr+1) ;
00258 goto safe_mark_more ;
00259 }
00260
00261 if (tag == XSB_STRUCT)
00262 { p = (CPtr)cell_val ;
00263 cell_ptr = ((CPtr)(cs_val(cell_val))) ;
00264 i = cell_ptr - heap_bot ;
00265 if (h_marked(i)) goto pop_more ;
00266 TO_BUFFER(cell_ptr);
00267 h_mark(i) ; m++ ;
00268 cell_val = *cell_ptr;
00269 arity = get_arity((Psc)(cell_val)) ;
00270 p = ++cell_ptr ;
00271 if (mark_overflow)
00272 { while (--arity)
00273 { m += mark_cell(++p) ; }
00274 }
00275 else while (--arity) push_to_mark(++p) ;
00276 goto mark_more ;
00277 }
00278
00279 if ((tag == XSB_REF) || (tag == XSB_REF1))
00280 { p = (CPtr)cell_val ;
00281 if (p == cell_ptr) goto pop_more ;
00282 cell_ptr = p ;
00283 goto mark_more ;
00284 }
00285
00286 #ifndef NO_STRING_GC
00287 #ifdef MULTI_THREAD
00288 if (flags[NUM_THREADS] == 1)
00289 #endif
00290 if (gc_strings) {
00291 if (tag == XSB_STRING) {
00292 char *astr = string_val(cell_val);
00293 if (astr && (string_find_safe(astr) == astr))
00294 mark_string_safe(astr,"mark_cell");
00295 }
00296 }
00297 #endif
00298
00299 pop_more:
00300 if (mark_top--)
00301 { cell_ptr = mark_stack[mark_top] ; goto mark_more ; }
00302 return(m) ;
00303
00304 }
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318 static int mark_root(Cell cell_val)
00319 {
00320 Integer i;
00321 int m, arity ;
00322 CPtr cell_ptr;
00323 int tag, whereto ;
00324 Cell v ;
00325
00326
00327
00328
00329
00330
00331
00332 if (cell_val == 0) return(0) ;
00333 switch (cell_tag(cell_val))
00334 {
00335 case XSB_REF:
00336 case XSB_REF1:
00337 v = *(CPtr)cell_val ;
00338 pointer_from_cell(v,&tag,&whereto) ;
00339 switch (tag)
00340 { case XSB_REF: case XSB_REF1:
00341 if (whereto != TO_HEAP) return(0) ;
00342 break ;
00343 }
00344 return(mark_cell((CPtr)cell_val)) ;
00345
00346 case XSB_STRUCT :
00347 cell_ptr = ((CPtr)(cs_val(cell_val))) ;
00348 if (!points_into_heap(cell_ptr)) return(0) ;
00349 i = cell_ptr - heap_bot ;
00350 if (h_marked(i)) return(0) ;
00351
00352 v = *cell_ptr ;
00353 pointer_from_cell(v,&tag,&whereto) ;
00354
00355 switch (tag) {
00356 case XSB_REF:
00357 case XSB_REF1 :
00358 if (whereto != TO_NOWHERE) return(0) ;
00359 break ;
00360
00361 }
00362 TO_BUFFER(cell_ptr);
00363 h_mark(i) ; m = 1 ;
00364 cell_val = *cell_ptr;
00365 arity = get_arity((Psc)(cell_val)) ;
00366 while (arity--) m += mark_cell(++cell_ptr) ;
00367 return(m) ;
00368
00369 case XSB_LIST:
00370 case XSB_ATTV:
00371
00372 cell_ptr = clref_val(cell_val) ;
00373 if (!points_into_heap(cell_ptr)) return(0) ;
00374 v = *cell_ptr ;
00375 #ifndef NO_STRING_GC
00376 if (gc_strings) mark_if_string(v,"attv 1");
00377 #endif
00378 pointer_from_cell(v,&tag,&whereto) ;
00379 switch (tag) {
00380 case XSB_REF:
00381 case XSB_REF1:
00382 if (whereto != TO_HEAP) return(0) ;
00383 break ;
00384 }
00385 v = *(++cell_ptr) ;
00386 #ifndef NO_STRING_GC
00387 if (gc_strings) mark_if_string(v,"attv 2");
00388 #endif
00389 pointer_from_cell(v,&tag,&whereto) ;
00390 switch (tag) {
00391 case XSB_REF:
00392 case XSB_REF1:
00393 if (whereto != TO_HEAP) return(0) ;
00394 break ;
00395 }
00396 m = mark_cell(cell_ptr) ;
00397 cell_ptr-- ;
00398 m += mark_cell(cell_ptr) ;
00399 return(m) ;
00400
00401 #ifndef NO_STRING_GC
00402 case XSB_STRING:
00403 #ifdef MULTI_THREAD
00404 if (flags[NUM_THREADS] == 1)
00405 #endif
00406 if (gc_strings) {
00407 char *sstr = string_val(cell_val);
00408 if (sstr && (string_find_safe(sstr) == sstr))
00409 mark_string_safe(sstr,"mark_root");
00410 return(0);
00411 }
00412 #endif
00413
00414 default : return(0) ;
00415 }
00416
00417 }
00418
00419
00420
00421 inline static int mark_region(CPtr beginp, CPtr endp)
00422 {
00423 int marked = 0 ;
00424
00425 while (beginp <= endp) {
00426 marked += mark_root(*(beginp++)) ;
00427 }
00428
00429 return(marked) ;
00430 }
00431
00432
00433 inline static unsigned long mark_trail_section(CPtr begintr, CPtr endtr)
00434 {
00435 CPtr a = begintr;
00436 CPtr trailed_cell;
00437 unsigned long i=0, marked=0;
00438 #ifdef PRE_IMAGE_TRAIL
00439 CPtr pre_value = NULL;
00440 #endif
00441
00442 while (a > (CPtr)endtr)
00443 {
00444 tr_mark(a - tr_bot);
00445
00446 tr_mark((a-tr_bot)-1);
00447 tr_mark((a-tr_bot)-2);
00448
00449 trailed_cell = (CPtr) *(a-2);
00450 #ifdef PRE_IMAGE_TRAIL
00451 if ((long) trailed_cell & PRE_IMAGE_MARK) {
00452 trailed_cell = (CPtr) ((Cell) trailed_cell & ~PRE_IMAGE_MARK);
00453 pre_value = (CPtr) *(a-3);
00454 tr_mark_pre((a-tr_bot)-2);
00455 *(a-2) = ((Cell)trailed_cell & ~PRE_IMAGE_MARK);
00456
00457 tr_mark((a-tr_bot)-3);
00458 }
00459 #endif
00460
00461 if (points_into_heap(trailed_cell))
00462 { i = trailed_cell - heap_bot ;
00463 if (! h_marked(i))
00464 {
00465 #if (EARLY_RESET == 1)
00466 {
00467
00468
00469 TO_BUFFER(trailed_cell);
00470 h_mark(i) ;
00471 marked++ ;
00472
00473 #ifdef PRE_IMAGE_TRAIL
00474 if (pre_value)
00475 *trailed_cell = (Cell) pre_value;
00476 else
00477 #endif
00478 bld_free(trailed_cell);
00479
00480
00481 heap_early_reset++;
00482 }
00483 #else
00484 {
00485 marked += mark_root((Cell)trailed_cell);
00486 }
00487 #endif
00488
00489 }
00490 }
00491 else
00492
00493
00494 if (points_into_ls(trailed_cell))
00495 { i = trailed_cell - ls_top ;
00496 if (! ls_marked(i))
00497 {
00498 #if (EARLY_RESET == 1)
00499 {
00500
00501
00502
00503 #ifdef PRE_IMAGE_TRAIL
00504 if (pre_value)
00505 *trailed_cell = (Cell) pre_value;
00506 else
00507 #endif
00508 bld_free(trailed_cell) ;
00509
00510
00511 ls_early_reset++;
00512 }
00513 #else
00514 { ls_mark(i) ;
00515 marked += mark_region(trailed_cell, trailed_cell);
00516 }
00517 #endif
00518 }
00519 }
00520
00521
00522 marked += mark_root((Cell) *(a-1));
00523
00524 #ifdef PRE_IMAGE_TRAIL
00525 if (pre_value) {
00526 marked += mark_root((Cell) pre_value);
00527 pre_value = NULL;
00528 }
00529 #endif
00530
00531
00532 if ((unsigned long) a == (unsigned long) *a)
00533 break;
00534
00535
00536 a = (CPtr) *a;
00537 }
00538 return marked;
00539 }
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550 static int mark_query(CTXTdecl)
00551 {
00552 Integer i;
00553 int yvar, total_marked = 0 ;
00554 CPtr b,e,*tr,a,d;
00555 byte *cp;
00556 int first_time;
00557
00558 b = breg ;
00559 e = ereg ;
00560 tr = trreg ;
00561 cp = cpreg ;
00562 first_time = 1;
00563
00564 restart:
00565 while (1)
00566 {
00567 while ((e < ls_bot) && (cp != NULL))
00568 {
00569 if (ls_marked(e - ls_top)) break ;
00570 ls_mark(e - ls_top) ;
00571
00572 yvar = *(cp-2*sizeof(Cell)+3) - 1 ;
00573 total_marked += mark_region(e-yvar,e-2) ;
00574 i = (e-2) - ls_top ;
00575 while (yvar-- > 1) { ls_mark(i--); }
00576 cp = (byte *)e[-1] ;
00577 e = (CPtr)e[0] ;
00578 }
00579 if (b >= (cp_bot-CP_SIZE)) {
00580 return(total_marked) ;
00581 }
00582 a = (CPtr)tr ;
00583 tr = cp_trreg(b) ;
00584
00585
00586
00587
00588
00589 if (is_generator_choicepoint(b)) {
00590 CPtr region;
00591 int at_size;
00592 region = (CPtr) tcp_template(b);
00593 at_size = (int_val(cell(region)) & 0xffff) + 1;
00594 while (at_size--)
00595 total_marked += mark_cell(region--);
00596 } else if (is_consumer_choicepoint(b)) {
00597 CPtr region;
00598 int at_size;
00599 region = (CPtr) nlcp_template(b);
00600 at_size = (int_val(cell(region))&0xffff)+1;
00601 while (at_size--)
00602 total_marked += mark_cell(region--);
00603 }
00604
00605
00606 if ((d = cp_pdreg(b)) != NULL) {
00607 total_marked += mark_root((Cell)d);
00608 }
00609
00610 total_marked += mark_trail_section(a,(CPtr) tr);
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621 if (is_generator_choicepoint(b))
00622 {
00623 total_marked += mark_region(b+TCP_SIZE, tcp_prevtop(b)-1);
00624 }
00625 else if (is_consumer_choicepoint(b))
00626 {
00627
00628 #ifdef SLG_GC
00629 if (nlcp_prevtop(b) != b+NLCP_SIZE) {
00630
00631
00632 CPtr ptr;
00633 for (ptr = b+NLCP_SIZE; ptr < nlcp_prevtop(b); ptr++)
00634 *ptr = makeint(6660666);
00635
00636 }
00637
00638 #endif
00639 }
00640 else if (is_compl_susp_frame(b))
00641 ;
00642 else {
00643 CPtr endregion, beginregion;
00644 endregion = cp_prevtop(b)-1;
00645 beginregion = b+CP_SIZE;
00646 total_marked += mark_region(beginregion,endregion) ;
00647
00648 }
00649
00650 e = cp_ereg(b) ;
00651 cp = cp_cpreg(b) ;
00652 #if defined(GC_PROFILE) && defined(CP_DEBUG)
00653 if (examine_data) {
00654 print_cpf_pred(b);
00655 active_cps++;
00656 }
00657 #endif
00658 if (first_time) {
00659 first_time = 0;
00660 if (bfreg < breg) {
00661 b = bfreg;
00662 e = cp_ereg(b);
00663 cp = cp_cpreg(b);
00664 tr = cp_trreg(b);
00665 goto restart;
00666 }
00667 }
00668
00669 b = cp_prevtop(b);
00670 }
00671
00672 }
00673
00674
00675
00676 static int mark_hreg_from_choicepoints(CTXTdecl)
00677 {
00678 CPtr b, bprev, h;
00679 Integer i;
00680 int m;
00681
00682
00683
00684
00685 b = (bfreg < breg ? bfreg : breg);
00686 bprev = 0;
00687 m = 0;
00688 while(1)
00689 {
00690 h = cp_hreg(b) ;
00691 i = h - heap_bot ;
00692 if (! h_marked(i))
00693
00694
00695
00696
00697 {
00698 cell(h) = makeint(666) ;
00699 TO_BUFFER(h);
00700 h_mark(i) ;
00701 m++ ;
00702 }
00703 #ifdef SLG_GC
00704
00705 if (is_generator_choicepoint(b)) {
00706 h = tcp_hfreg(b);
00707 i = h - heap_bot;
00708 if (! h_marked(i)) {
00709 cell(h) = makeint(6660);
00710 TO_BUFFER(h);
00711 h_mark(i);
00712 m++;
00713 }
00714 }
00715 #endif
00716 bprev = b;
00717 b = cp_prevtop(b);
00718 if (b >= (cp_bot-CP_SIZE))
00719 break;
00720 }
00721 return m;
00722 }
00723
00724
00725
00733 static int mark_from_attv_array(CTXTdecl)
00734 {
00735 int i,max;
00736 int m=0;
00737
00738 max = int_val(cell(interrupt_reg));
00739
00740 for (i=0; i<max; i++) {
00741 m += mark_cell((CPtr) attv_interrupts[i][0]);
00742 m += mark_cell((CPtr) attv_interrupts[i][1]);
00743 }
00744 return m;
00745 }
00746
00747
00748
00749
00750 int mark_heap(CTXTdeclc int arity, int *marked_dregs)
00751 {
00752 int avail_dreg_marks = 0, marked = 0;
00753
00754
00755
00756 slide = (pflags[GARBAGE_COLLECT] == SLIDING_GC) |
00757 (pflags[GARBAGE_COLLECT] == INDIRECTION_SLIDE_GC);
00758
00759 stack_boundaries ;
00760
00761 if (print_on_gc) print_all_stacks(CTXTc arity);
00762
00763 if (slide) {
00764 #ifdef INDIRECTION_SLIDE
00765
00766 slide_buf_size = (unsigned long) ((hreg+1-(CPtr)glstack.low)*0.2);
00767 slide_buf = (CPtr *) mem_calloc(slide_buf_size+1, sizeof(CPtr),GC_SPACE);
00768 if (!slide_buf)
00769 xsb_exit("Not enough space to allocate slide_buf");
00770 slide_top=0;
00771 if (pflags[GARBAGE_COLLECT] == INDIRECTION_SLIDE_GC)
00772 slide_buffering=1;
00773 else
00774 slide_buffering=0;
00775 #endif
00776 }
00777
00778 #ifdef INDIRECTION_SLIDE
00779 else
00780 slide_buffering=0;
00781 #endif
00782
00783 #ifdef SLG_GC
00784 cp_marks = (char *)mem_calloc(cp_bot - cp_top + 1,1,GC_SPACE);
00785 tr_marks = (char *)mem_calloc(tr_top - tr_bot + 1,1,GC_SPACE);
00786 if ((! cp_marks) || (! tr_marks))
00787 xsb_exit("Not enough core to perform garbage collection chaining phase");
00788 #endif
00789 heap_marks_size = heap_top - heap_bot + 2 + avail_dreg_marks;
00790 heap_marks = (char * )mem_calloc(heap_marks_size,1,GC_SPACE);
00791 ls_marks = (char * )mem_calloc(ls_bot - ls_top + 1,1,GC_SPACE);
00792 if ((! heap_marks) || (! ls_marks))
00793 xsb_exit("Not enough core to perform garbage collection marking phase");
00794
00795 heap_marks += 1;
00796
00797
00798
00799 marked = mark_region(reg+1,reg+arity);
00800 if (delayreg != NULL) {
00801 marked += mark_root((Cell)delayreg);
00802 }
00803
00804 marked += mark_root((Cell)glstack.low);
00805
00806 if (slide)
00807 {
00808 int put_on_heap;
00809 put_on_heap = arity;
00810 marked += put_on_heap;
00811 while (put_on_heap > 0) {
00812 #ifdef SLG_GC
00813 TO_BUFFER((heap_top-put_on_heap-1));
00814 h_mark((heap_top - 1 - put_on_heap--)-heap_bot);
00815 #else
00816 TO_BUFFER((heap_top-put_on_heap));
00817 h_mark((heap_top - put_on_heap--)-heap_bot);
00818 #endif
00819 }
00820 }
00821
00822 #ifdef SLG_GC
00823
00824
00825 if (slide) {
00826 CPtr hfreg_in_heap;
00827
00828 marked += mark_root((Cell)hfreg);
00829
00830 hfreg_in_heap = heap_top - 1;
00831 TO_BUFFER(hfreg_in_heap);
00832 if (!h_marked(hfreg_in_heap - heap_bot)) {
00833 h_mark(hfreg_in_heap - heap_bot);
00834 marked++;
00835 }
00836 }
00837 #endif
00838
00839 marked += mark_query(CTXT);
00840
00841 marked += mark_from_attv_array(CTXT);
00842
00843 if (slide)
00844 marked += mark_hreg_from_choicepoints(CTXT);
00845
00846 if (print_on_gc) print_all_stacks(CTXTc arity);
00847
00848 return marked ;
00849 }
00850
00851 #ifndef NO_STRING_GC
00852 #define mark_trie_strings_for(SM,BType,pStruct,apStruct) \
00853 pBlock = SM_CurBlock(SM); \
00854 if (pBlock != NULL) { \
00855 int isusedblock, anyunusedblock = FALSE; \
00856 for (pStruct = (BType)SMBlk_FirstStruct(pBlock); \
00857 pStruct < (BType)SM_NextStruct(SM); \
00858 pStruct = (BType)SMBlk_NextStruct(pStruct,SM_StructSize(SM))) { \
00859 if (isstring(BTN_Symbol(pStruct)) && (*(((Integer *)pStruct)+1) != FREE_TRIE_NODE_MARK)) {\
00860 mark_string(string_val(BTN_Symbol(pStruct)),"trie 1"); \
00861 } \
00862 } \
00863 pBlock = SMBlk_NextBlock(pBlock); \
00864 while (pBlock != NULL) { \
00865 isusedblock = FALSE; \
00866 for (pStruct = (BType)SMBlk_FirstStruct(pBlock); \
00867 pStruct <= (BType)SMBlk_LastStruct(pBlock,SM_StructSize(SM),SM_StructsPerBlock(SM)); \
00868 pStruct = (BType)SMBlk_NextStruct(pStruct,SM_StructSize(SM))) { \
00869 if (*(((Integer *)pStruct)+1) != FREE_TRIE_NODE_MARK) { \
00870 isusedblock = TRUE; \
00871 if (isstring(BTN_Symbol(pStruct))) \
00872 mark_string(string_val(BTN_Symbol(pStruct)),"trie 2");\
00873 } \
00874 } \
00875 anyunusedblock |= !isusedblock; \
00876 if (!isusedblock) { \
00877 \
00878 for (pStruct = (BType)SMBlk_FirstStruct(pBlock); \
00879 pStruct <= (BType)SMBlk_LastStruct(pBlock,SM_StructSize(SM),SM_StructsPerBlock(SM)); \
00880 pStruct = (BType)SMBlk_NextStruct(pStruct,SM_StructSize(SM))) { \
00881 *(((Integer *)pStruct)+1) = FREE_TRIE_BLOCK_MARK; \
00882 } \
00883 } \
00884 pBlock = SMBlk_NextBlock(pBlock); \
00885 } \
00886 if (anyunusedblock) { \
00887 apStruct = (BType *)&SM_FreeList(SM); \
00888 while (*apStruct != NULL) { \
00889 if (*((Integer *)(*apStruct)+1) == FREE_TRIE_BLOCK_MARK)\
00890 *apStruct = *((void **)(*apStruct)); \
00891 else apStruct = *(void **)apStruct; \
00892 } \
00893 apBlock = &(SM_CurBlock(SM)); \
00894 while (*apBlock != NULL) { \
00895 if (*((Integer *)(*apBlock)+2) == FREE_TRIE_BLOCK_MARK) {\
00896 pBlock = *apBlock; \
00897 *apBlock = *((void **)(*apBlock)); \
00898 mem_dealloc(pBlock,SM_NewBlockSize(SM),TABLE_SPACE); \
00899 } else apBlock = *((void **)(apBlock)); \
00900 } \
00901 } \
00902 }
00903
00904
00905 void mark_trie_strings(CTXTdecl) {
00906
00907 BTNptr pBTNStruct, *apBTNStruct;
00908 TSTNptr pTSTNStruct, *apTSTNStruct;
00909 void *pBlock, **apBlock;
00910
00911 #ifdef MULTI_THREAD
00912
00913 mark_trie_strings_for(*private_smTableBTN,BTNptr,pBTNStruct,apBTNStruct);
00914
00915 #endif
00916 SYS_MUTEX_LOCK(MUTEX_SM);
00917 mark_trie_strings_for(smTableBTN,BTNptr,pBTNStruct,apBTNStruct);
00918 mark_trie_strings_for(smAssertBTN,BTNptr,pBTNStruct,apBTNStruct);
00919 SYS_MUTEX_UNLOCK(MUTEX_SM);
00920 mark_trie_strings_for(smTSTN,TSTNptr,pTSTNStruct,apTSTNStruct);
00921 }
00922
00923 void mark_code_strings(int pflag, CPtr inst_addr, CPtr end_addr) {
00924 int current_opcode, oprand;
00925
00926
00927 while (inst_addr<end_addr) {
00928 current_opcode = cell_opcode(inst_addr);
00929
00930 inst_addr ++;
00931 for (oprand=1; oprand<=4; oprand++) {
00932 switch (inst_table[current_opcode][oprand]) {
00933 case A: case V: case R: case P: case PP: case PPP:
00934 case PPR: case PRR: case RRR: case X:
00935 break;
00936 case S: case L: case N: case B: case F:
00937 case I: case T:
00938 inst_addr ++;
00939 break;
00940 case C:
00941 case G:
00942 if (pflag) printf(" %s\n",*(char **)inst_addr);
00943 mark_string(*(char **)inst_addr,"code");
00944 inst_addr ++;
00945 break;
00946 default:
00947 break;
00948 }
00949 }
00950 }
00951 }
00952
00953 void mark_atom_and_code_strings(CTXTdecl) {
00954 unsigned long i;
00955 Pair pair_ptr, mod_pair_ptr;
00956 PrRef prref;
00957 ClRef clref;
00958 CPtr code_beg, code_end;
00959
00960
00961
00962 for (i = 0; i < symbol_table.size; i++) {
00963 if (symbol_table.table[i] != NULL) {
00964 for (pair_ptr = (Pair)symbol_table.table[i]; pair_ptr != NULL;
00965 pair_ptr = pair_next(pair_ptr)) {
00966 char *string = get_name(pair_psc(pair_ptr));
00967 mark_string(string,"usermod atom");
00968 if (get_type(pair_psc(pair_ptr)) == T_DYNA) {
00969
00970 prref = dynpredep_to_prref(CTXTc get_ep(pair_psc(pair_ptr)));
00971 if (prref) {
00972 clref = db_get_clause_code_space(prref,(ClRef)NULL,&code_beg,&code_end);
00973 while (clref) {
00974 mark_code_strings(0,code_beg,code_end);
00975 clref = db_get_clause_code_space(prref,clref,&code_beg,&code_end);
00976 }
00977 }
00978 }
00979 }
00980 }
00981 }
00982 for (mod_pair_ptr = (Pair)flags[MOD_LIST];
00983 mod_pair_ptr != NULL;
00984 mod_pair_ptr = pair_next(mod_pair_ptr)) {
00985 mark_string(get_name(pair_psc(mod_pair_ptr)),"mod");
00986 pair_ptr = (Pair) get_data(pair_psc(mod_pair_ptr));
00987 if ((Integer)pair_ptr != 1) {
00988 while (pair_ptr != NULL) {
00989 char *string = get_name(pair_psc(pair_ptr));
00990 mark_string(string,"mod atom");
00991 if (get_type(pair_psc(pair_ptr)) == T_DYNA) {
00992
00993 prref = dynpredep_to_prref(CTXTc get_ep(pair_psc(pair_ptr)));
00994 clref = db_get_clause_code_space(prref,(ClRef)NULL,&code_beg,&code_end);
00995 while (clref) {
00996
00997 mark_code_strings(0,code_beg,code_end);
00998 clref = db_get_clause_code_space(prref,clref,&code_beg,&code_end);
00999 }
01000 }
01001 pair_ptr = pair_next(pair_ptr);
01002 }
01003 }
01004 }
01005
01006 }
01007
01008 void mark_nonheap_strings(CTXTdecl) {
01009 char *empty;
01010
01011 mark_string((char *)(ret_psc[0]),"ret");
01012 mark_string(nil_string,"[]");
01013 empty = string_find_safe("");
01014 if (!empty) mark_string(empty,"empty");
01015
01016 mark_trie_strings(CTXT);
01017 mark_atom_and_code_strings(CTXT);
01018 mark_findall_strings(CTXT);
01019 mark_open_filenames();
01020 mark_hash_table_strings(CTXT);
01021
01022 }
01023 #endif
01024