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
00035
00036
00037
00038 #ifdef GC
00039
00040
00041
00042
00043 static int offset;
00044 static CPtr scan, next;
00045
00046
00047 #ifdef DEBUG_ASSERTIONS
00048 static void CHECK(CPtr p)
00049 { CPtr q;
00050 q = (CPtr)(*p);
00051 if (((heap_bot - offset) <= q) && (q < next)) return;
00052 xsb_dbgmsg((LOG_GC, "really bad thing discovered"));
00053 }
00054 #define GCDBG(mes,val) xsb_dbgmsg((LOG_GC,mes,val))
00055 #else
00056 #define CHECK(p)
00057 #define GCDBG(mes,val)
00058 #endif
00059
00060 #define adapt_external_heap_pointer(P,Q,TAG) \
00061 CHECK(Q);\
00062 GCDBG("Adapting %p ", P); GCDBG("with %p ", Q);\
00063 Q = (CPtr)((CPtr)(cell(Q))+offset); \
00064 if (TAG == XSB_REF || TAG == XSB_REF1) {\
00065 bld_ref(P, Q); \
00066 } else {\
00067 cell(P) = (Cell)(enc_addr(Q) | TAG); \
00068 } \
00069 GCDBG("to %lx\n", cell(P))
00070
00071 #define copy_block(HP,NEXT) \
00072 i = HP-heap_bot; \
00073 while (h_marked(--i)) ; \
00074 \
00075 p = heap_bot+i+1;\
00076 for (i = p-heap_bot; h_marked(i); p++, i++) { \
00077 h_clear_mark(i); \
00078 cell(NEXT) = cell(p); \
00079 cell(p) = (Cell)(NEXT); \
00080 NEXT++; \
00081 }
00082
00083 static void find_and_copy_block(CPtr hp)
00084 {
00085 int i, tag;
00086 CPtr p, q, addr;
00087
00088
00089 copy_block(hp,next);
00090
00091
00092
00093 for ( ; scan < next; scan++) {
00094 q = (CPtr)cell(scan);
00095 tag = cell_tag(q);
00096 switch (tag) {
00097 case XSB_REF:
00098 case XSB_REF1:
00099 if (points_into_heap(q)) {
00100 GCDBG("Reference to heap with tag %d\n", tag);
00101
00102 xsb_dbgmsg((LOG_GC, "In adapting case for %p with %p (%lx)...",
00103 scan, q, cell(q)));
00104
00105 if (h_marked(q-heap_bot)) {
00106 copy_block(q,next);
00107 }
00108 q = (CPtr)((CPtr)(cell(q))+offset);
00109 GCDBG(" to be adapted to %p\n", q);
00110 bld_ref(scan, q);
00111 }
00112 break;
00113 case XSB_STRUCT :
00114 addr = (CPtr)cs_val(q);
00115 GCDBG("Structure pointing to %p found...\n", addr);
00116 if (h_marked(addr-heap_bot)) {
00117 copy_block(addr,next);
00118 }
00119 CHECK(addr);
00120 GCDBG("*p = %lx ", cell(addr));
00121 addr = (CPtr)((CPtr)(cell(addr))+offset);
00122 GCDBG("q = %p ", addr);
00123 bld_cs(scan, addr);
00124 GCDBG("made to point to %lx\n", cell(scan));
00125 break;
00126 case XSB_LIST :
00127 addr = clref_val(q);
00128 GCDBG("List %p found... \n", addr);
00129 if (h_marked(addr-heap_bot)) {
00130 copy_block(addr,next);
00131 }
00132 CHECK(addr);
00133 addr = (CPtr)((CPtr)(cell(addr))+offset);
00134 bld_list(scan, addr);
00135 break;
00136 case XSB_ATTV:
00137 addr = clref_val(q);
00138 GCDBG("Attv %p found... \n", addr);
00139 if (h_marked(addr-heap_bot)) {
00140 copy_block(addr,next);
00141 }
00142 CHECK(addr);
00143 addr = (CPtr)((CPtr)(cell(addr))+offset);
00144 bld_attv(scan, addr);
00145 break;
00146 default :
00147 break;
00148 }
00149 }
00150 }
00151
00152 #endif
00153
00154
00155 #ifdef GC
00156
00157 inline static void adapt_hreg_from_choicepoints(CTXTdeclc CPtr h)
00158 {
00159 CPtr b, bprev;
00160
00161
00162 b = breg;
00163 b = top_of_cpstack;
00164 bprev = 0;
00165 while (b != bprev) {
00166 cp_hreg(b) = h;
00167 bprev = b;
00168 b = cp_prevbreg(b);
00169 }
00170 }
00171
00172 #endif
00173
00174 #ifdef SLG_GC
00175
00176 inline static void adapt_hfreg_from_choicepoints(CTXTdeclc CPtr h)
00177 {
00178 CPtr b, bprev;
00179 b = (bfreg < breg ? bfreg : breg);
00180 bprev = 0;
00181 while (1) {
00182 if (is_generator_choicepoint(b))
00183 tcp_hfreg(b) = h;
00184 cp_hreg(b) = h;
00185 b = cp_prevtop(b);
00186 if (b >= (cp_bot - CP_SIZE))
00187 break;
00188 }
00189 }
00190
00191 #endif
00192
00193
00194
00195 #ifdef GC
00196
00197 static CPtr copy_heap(CTXTdeclc int marked, CPtr begin_new_h, CPtr end_new_h, int arity)
00198 {
00199 CPtr p, q;
00200 int tag;
00201 Cell contents;
00202
00203 offset = heap_bot-begin_new_h;
00204 scan = next = begin_new_h;
00205
00206 xsb_dbgmsg((LOG_GC,
00207 "New heap space between %p and %p", begin_new_h,end_new_h));
00208
00209
00210
00211
00212
00213
00214
00215 { CPtr endtr ;
00216 endtr = tr_top ;
00217 for (p = tr_bot; p <= endtr; p++) {
00218 contents = cell(p);
00219
00220 #ifdef SLG_GC
00221 if (!tr_marked(p-tr_bot))
00222 continue;
00223 tr_clear_mark(p-tr_bot);
00224 #endif
00225 q = hp_pointer_from_cell(contents,&tag) ;
00226 if (!q) continue ;
00227 if (h_marked(q-heap_bot))
00228 find_and_copy_block(q);
00229 adapt_external_heap_pointer(p,q,tag);
00230 }
00231 #ifdef PRE_IMAGE_TRAIL
00232
00233 if (tr_pre_marked(p-tr_bot)) {
00234 *p = *p | PRE_IMAGE_MARK;
00235 tr_clear_pre_mark(p-tr_bot);
00236 }
00237 #endif
00238 }
00239
00240
00241
00242
00243 { CPtr endcp ;
00244 endcp = cp_top ;
00245 for (p = cp_bot; p >= endcp ; p--)
00246 { contents = cell(p) ;
00247 q = hp_pointer_from_cell(contents,&tag) ;
00248 if (!q) continue ;
00249 if (h_marked(q-heap_bot)) { find_and_copy_block(q); }
00250 adapt_external_heap_pointer(p,q,tag);
00251 }
00252 }
00253
00254
00255
00256
00257 { CPtr endls;
00258 endls = ls_top ;
00259 for (p = ls_bot; p >= endls ; p-- )
00260 { if (! ls_marked(p-ls_top)) continue ;
00261 ls_clear_mark((p-ls_top)) ;
00262 contents = cell(p) ;
00263 q = hp_pointer_from_cell(contents,&tag) ;
00264 if (!q) continue ;
00265 if (h_marked(q-heap_bot)) { find_and_copy_block(q); }
00266 adapt_external_heap_pointer(p,q,tag);
00267 }
00268 }
00269
00270
00271
00272 { CPtr p;
00273 for (p = reg+1; arity-- > 0; p++)
00274 { contents = cell(p) ;
00275 q = hp_pointer_from_cell(contents,&tag) ;
00276 if (!q) continue ;
00277 if (h_marked(q-heap_bot)) { find_and_copy_block(q); }
00278 adapt_external_heap_pointer(p,q,tag);
00279 }
00280 }
00281
00282
00283
00284 { CPtr p;
00285
00286 if (delayreg != NULL)
00287 {
00288 p = (CPtr)(&delayreg);
00289 contents = cell(p) ;
00290 q = hp_pointer_from_cell(contents,&tag) ;
00291 if (!q)
00292 xsb_dbgmsg((LOG_GC, "non null delayreg points not in heap"));
00293 else
00294 {
00295 if (h_marked(q-heap_bot)) { find_and_copy_block(q); }
00296 adapt_external_heap_pointer(p,q,tag);
00297 }
00298 }
00299 }
00300
00301 if (next != end_new_h) {
00302 xsb_dbgmsg((LOG_GC, "heap copy gc - inconsistent hreg: %d cells not copied. (num_gc=%d)\n",
00303 (end_new_h-next),num_gc));
00304 }
00305
00306 memcpy((void *)heap_bot, (void *)begin_new_h, marked*sizeof(Cell));
00307
00308 return(heap_bot+marked);
00309 }
00310
00311 #endif
00312