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
00027
00028
00029
00030
00031
00032
00033
00034 #ifdef GC
00035
00036 #define h_set_chained(p) heap_marks[(p-heap_bot)] |= CHAIN_BIT
00037 #define h_set_unchained(p) heap_marks[(p-heap_bot)] &= ~CHAIN_BIT
00038 #define h_is_chained(p) (heap_marks[(p-heap_bot)] & CHAIN_BIT)
00039
00040 #define ls_set_chained(p) ls_marks[(p-ls_top)] |= CHAIN_BIT
00041 #define ls_set_unchained(p) ls_marks[(p-ls_top)] &= ~CHAIN_BIT
00042 #define ls_is_chained(p) (ls_marks[(p-ls_top)] & CHAIN_BIT)
00043
00044 #define cp_set_chained(p) cp_marks[(p-cp_top)] |= CHAIN_BIT
00045 #define cp_set_unchained(p) cp_marks[(p-cp_top)] &= ~CHAIN_BIT
00046 #define cp_is_chained(p) (cp_marks[(p-cp_top)] & CHAIN_BIT)
00047
00048 #define tr_set_chained(p) tr_marks[(p-tr_bot)] |= CHAIN_BIT
00049 #define tr_set_unchained(p) tr_marks[(p-tr_bot)] &= ~CHAIN_BIT
00050 #define tr_is_chained(p) (tr_marks[(p-tr_bot)] & CHAIN_BIT)
00051
00052 static void unchain(CPtr hptr, CPtr destination)
00053 {
00054 CPtr start, pointsto ;
00055 int whereto, tag ;
00056 int continue_after_this = 0 ;
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 h_set_unchained(hptr) ;
00071
00072 do
00073 {
00074 start = (CPtr)(*hptr) ;
00075
00076 pointsto = pointer_from_cell((Cell)start,&tag,&whereto) ;
00077 if (pointsto == NULL) xsb_exit("pointsto error during unchaining") ;
00078 switch (whereto)
00079 {
00080 case TO_HEAP :
00081 continue_after_this = h_is_chained(pointsto) ;
00082 h_set_unchained(pointsto) ;
00083 break ;
00084 case TO_LS :
00085 continue_after_this = ls_is_chained(pointsto) ;
00086 ls_set_unchained(pointsto) ;
00087 break ;
00088 case TO_TR :
00089 continue_after_this = tr_is_chained(pointsto) ;
00090 tr_set_unchained(pointsto) ;
00091 break ;
00092 case TO_CP :
00093 continue_after_this = cp_is_chained(pointsto) ;
00094 cp_set_unchained(pointsto) ;
00095 break ;
00096 default :
00097 xsb_exit("pointsto wrong space error during unchaining");
00098 break;
00099 }
00100 *hptr = *pointsto ;
00101 switch (tag) {
00102 case XSB_REF:
00103 case XSB_REF1:
00104 *pointsto = (Cell)destination ;
00105 break ;
00106 case XSB_STRUCT :
00107 *pointsto = makecs((Cell)destination) ;
00108 break ;
00109 case XSB_LIST :
00110 *pointsto = makelist((Cell)destination) ;
00111 break ;
00112 case XSB_ATTV :
00113 *pointsto = makeattv((Cell)destination);
00114 break;
00115 default :
00116 xsb_exit("tag error during unchaining") ;
00117 }
00118 }
00119 while (continue_after_this) ;
00120
00121 }
00122
00123
00124
00125 inline static void swap_with_tag(CPtr p, CPtr q, int tag)
00126 {
00127
00128
00129 *p = *q ;
00130 switch (tag) {
00131 case XSB_REF:
00132 case XSB_REF1:
00133 *q = (Cell)p ;
00134 break ;
00135 case XSB_STRUCT :
00136 *q = makecs((Cell)p) ;
00137 break ;
00138 case XSB_LIST :
00139 *q = makelist((Cell)p) ;
00140 break ;
00141 case XSB_ATTV :
00142 *q = makeattv((Cell)p);
00143 break;
00144 default : xsb_exit("error during swap_with_tag") ;
00145 }
00146 }
00147
00148 #endif
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159 #ifdef INDIRECTION_SLIDE
00160
00161 #define mem_swap(a,b) \
00162 { unsigned long temp; \
00163 temp = *a; \
00164 *a = *b; \
00165 *b = temp; \
00166 }
00167 #define push_sort_stack(X,Y) \
00168 addr_stack[stack_index] = X;\
00169 size_stack[stack_index] = Y;\
00170 stack_index++
00171 #define pop_sort_stack(X,Y)\
00172 stack_index--; \
00173 X = addr_stack[stack_index]; \
00174 Y = size_stack[stack_index]
00175 #define sort_stack_empty \
00176 (stack_index == 0)
00177
00178 static void randomize_data(unsigned long *data, unsigned long size)
00179 {
00180 unsigned long i,j;
00181
00182 for (i=0; i<size; i++) {
00183 j = (unsigned long) rand()*(size-1)/RAND_MAX;
00184 mem_swap((data+i), (data+j));
00185 }
00186 }
00187
00188 static void sort_buffer(unsigned long *indata, unsigned long insize)
00189 {
00190 unsigned long *left, *right, *pivot;
00191 unsigned long *data, size;
00192 unsigned long *addr_stack[4000];
00193 unsigned long size_stack[4000];
00194 int stack_index=0;
00195 Integer leftsize;
00196 #ifdef GC_PROFILE
00197 unsigned long begin_sorting, end_sorting;
00198 #endif
00199
00200 randomize_data(indata,insize);
00201
00202 #ifdef GC_PROFILE
00203 if (verbose_gc)
00204 begin_sorting = cpu_time();
00205 #endif
00206 push_sort_stack(indata,insize);
00207
00208 while (!sort_stack_empty) {
00209
00210 pop_sort_stack(data,size);
00211
00212 if (size < 1)
00213 continue;
00214
00215 if (size == 1) {
00216 if (data[0] > data[1])
00217 mem_swap(data, (data+1));
00218 continue;
00219 }
00220
00221 left = data;
00222 right = &data[size];
00223
00224 pivot = &data[size/2];
00225 mem_swap(pivot, right);
00226
00227 pivot = right;
00228
00229 while (left < right) {
00230 while ((*left < *pivot) && (left < right))
00231 left++;
00232 while ((*right >= *pivot) && (left < right))
00233 right--;
00234 if (left < right) {
00235 mem_swap(left,right);
00236 left++;
00237 }
00238 }
00239 if (right == data) {
00240 mem_swap(right, pivot);
00241 right++;
00242 }
00243 leftsize = right - data;
00244 if (leftsize >= 1)
00245 push_sort_stack(data,leftsize);
00246 if ((size-leftsize) >= 1)
00247 push_sort_stack(right,(size-leftsize));
00248
00249 }
00250 #ifdef GC_PROFILE
00251 if (verbose_gc) {
00252 end_sorting = cpu_time();
00253 fprintf(stddbg,"{GC} Sorting took %f ms.\n", (double)
00254 (end_sorting - begin_sorting)*1000/CLOCKS_PER_SEC);
00255 }
00256 #endif
00257 }
00258
00259 #endif
00260
00261 #ifdef GC
00262
00263 static CPtr slide_heap(int num_marked)
00264 {
00265 int tag ;
00266 Cell contents;
00267 CPtr p, q ;
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280 { CPtr endtr ;
00281 endtr = tr_top ;
00282 for (p = tr_bot; p <= endtr ; p++ )
00283 { contents = cell(p) ;
00284
00285 #ifdef SLG_GC
00286 if (!tr_marked(p-tr_bot))
00287 continue;
00288 tr_clear_mark(p-tr_bot);
00289 #endif
00290 q = hp_pointer_from_cell(contents,&tag) ;
00291 if (!q) continue ;
00292 if (! h_marked(q-heap_bot)) {
00293 continue ;
00294 }
00295 if (h_is_chained(q)) tr_set_chained(p) ;
00296 h_set_chained(q) ;
00297 swap_with_tag(p,q,tag) ;
00298 }
00299 }
00300
00301
00302
00303
00304 { CPtr endcp ;
00305 endcp = cp_top ;
00306 for (p = cp_bot; p >= endcp ; p--)
00307 { contents = cell(p) ;
00308 q = hp_pointer_from_cell(contents,&tag) ;
00309 if (!q) continue ;
00310 if (! h_marked(q-heap_bot))
00311 { xsb_dbgmsg((LOG_DEBUG, "not marked from cp(%p)",p)); continue ; }
00312 if (h_is_chained(q)) cp_set_chained(p) ;
00313 h_set_chained(q) ;
00314 swap_with_tag(p,q,tag) ;
00315 }
00316 }
00317
00318
00319
00320
00321
00322 { CPtr endls ;
00323 endls = ls_top ;
00324 for (p = ls_bot; p >= endls ; p-- )
00325 {
00326 if (! ls_marked(p-ls_top)) continue ;
00327 ls_clear_mark((p-ls_top)) ;
00328 contents = cell(p) ;
00329 q = hp_pointer_from_cell(contents,&tag) ;
00330 if (!q) continue ;
00331 if (! h_marked(q-heap_bot)) continue ;
00332 if (h_is_chained(q)) ls_set_chained(p) ;
00333 h_set_chained(q) ;
00334 swap_with_tag(p,q,tag) ;
00335 }
00336 }
00337
00338
00339
00340 { CPtr destination, hptr ;
00341 long garbage = 0 ;
00342 Integer index ;
00343
00344
00345
00346 index = heap_top - heap_bot ;
00347 destination = heap_bot + num_marked - 1 ;
00348 #ifdef INDIRECTION_SLIDE
00349 if (slide_buffering) {
00350 unsigned long i;
00351 #ifdef GC_PROFILE
00352 if (verbose_gc) {
00353 fprintf(stddbg,"{GC} Using Fast-Slide scheme.\n");
00354 }
00355 #endif
00356
00357 sort_buffer((unsigned long *)slide_buf, slide_top-1);
00358
00359
00360 for (i=slide_top; i > 0; i--) {
00361 hptr = slide_buf[i-1];
00362
00363 if (h_is_chained(hptr)) {
00364 unchain(hptr,destination);
00365 }
00366 p = hp_pointer_from_cell(*hptr,&tag);
00367 if (p &&(p<hptr)) {
00368 swap_with_tag(hptr,p,tag);
00369 if (h_is_chained(p))
00370 h_set_chained(hptr);
00371 else
00372 h_set_chained(p);
00373 }
00374 destination--;
00375 }
00376 } else {
00377 #ifdef GC_PROFILE
00378 if (verbose_gc && pflags[GARBAGE_COLLECT]==INDIRECTION_SLIDE_GC)
00379 fprintf(stddbg,"{GC} Giving up Fast-Slide scheme.\n");
00380 #endif
00381 #endif
00382 for (hptr = heap_top - 1 ; hptr >= heap_bot ; hptr--) {
00383 if (h_marked(hptr - heap_bot)) {
00384
00385
00386
00387
00388
00389 if (garbage) {
00390 *(hptr+1) = makeint(garbage) ;
00391 garbage = 0 ;
00392 }
00393 if (h_is_chained(hptr)) {
00394 unchain(hptr,destination) ;
00395 }
00396 p = hp_pointer_from_cell(*hptr,&tag) ;
00397 if (p && (p < hptr)) {
00398 swap_with_tag(hptr,p,tag) ;
00399 if (h_is_chained(p))
00400 h_set_chained(hptr) ;
00401 else
00402 h_set_chained(p) ;
00403 }
00404 destination-- ;
00405 }
00406 else
00407 garbage++ ;
00408 index-- ;
00409 }
00410 #ifdef INDIRECTION_SLIDE
00411 }
00412 if (!slide_buffering)
00413 #endif
00414 if (garbage)
00415
00416 *heap_bot = makeint(garbage) ;
00417
00418
00419 index = 0 ;
00420 destination = heap_bot ;
00421
00422 #ifdef INDIRECTION_SLIDE
00423 if (slide_buffering) {
00424 unsigned long i;
00425 for (i=0; i<slide_top; i++) {
00426 hptr = slide_buf[i];
00427
00428 if (h_is_chained(hptr)) {
00429 unchain(hptr,destination);
00430 }
00431 if ((Cell)(hptr) == *hptr)
00432 bld_free(destination);
00433 else {
00434 p = hp_pointer_from_cell(*hptr,&tag);
00435 *destination = *hptr;
00436 if (p && (p > hptr)) {
00437 swap_with_tag(destination,p,tag);
00438 if (h_is_chained(p))
00439 h_set_chained(destination);
00440 else
00441 h_set_chained(p);
00442 }
00443 h_clear_mark((hptr-heap_bot));
00444 }
00445 destination++;
00446 }
00447 } else {
00448 #endif
00449 hptr = heap_bot;
00450 while (hptr < heap_top) {
00451 if (h_marked(hptr - heap_bot)) {
00452 if (h_is_chained(hptr))
00453 { unchain(hptr,destination) ; }
00454 if ((Cell)(hptr) == *hptr)
00455 bld_free(destination) ;
00456 else {
00457 p = hp_pointer_from_cell(*hptr,&tag) ;
00458 *destination = *hptr ;
00459 if (p && (p > hptr)) {
00460 swap_with_tag(destination,p,tag) ;
00461 if (h_is_chained(p))
00462 h_set_chained(destination) ;
00463 else
00464 h_set_chained(p) ;
00465 }
00466 }
00467 h_clear_mark((hptr-heap_bot)) ;
00468 hptr++ ; destination++ ;
00469 index++ ;
00470 } else {
00471 garbage = int_val(cell(hptr)) ;
00472 index += garbage ;
00473 hptr += garbage ;
00474 }
00475 }
00476 if (destination != (heap_bot+num_marked))
00477 xsb_dbgmsg((LOG_DEBUG, "bad size %p %p",
00478 destination,heap_bot+num_marked));
00479 #ifdef INDIRECTION_SLIDE
00480 }
00481 #endif
00482 }
00483
00484 #ifdef PRE_IMAGE_TRAIL
00485
00486
00487 for (p = tr_bot; p <= tr_top ; p++ ) {
00488 if (tr_pre_marked(p-tr_bot)) {
00489 *p = *p | PRE_IMAGE_MARK;
00490 tr_clear_pre_mark(p-tr_bot);
00491 }
00492 }
00493 #endif
00494
00495 return(heap_bot + num_marked) ;
00496
00497 }
00498
00499 static void check_zero(char *b, Integer l, char *s)
00500 {
00501 #ifdef SAFE_GC
00502 Integer i = 0 ;
00503 while (l--)
00504 {
00505 if (*b++)
00506 xsb_dbgmsg((LOG_DEBUG, "%s - left marker - %d - %d - %d", s,*(b-1),i,l));
00507 i++ ;
00508 }
00509 #endif
00510 }
00511
00512 #endif
00513
00514