gc_copy.h

00001 /* File:      gc_copy.h
00002 ** Author(s): Luis Castro, Bart Demoen, Kostis Sagonas
00003 ** Contact:   xsb-contact@cs.sunysb.edu
00004 ** 
00005 ** Copyright (C) The Research Foundation of SUNY, 1986, 1993-1998
00006 ** Copyright (C) ECRC, Germany, 1990
00007 ** 
00008 ** XSB is free software; you can redistribute it and/or modify it under the
00009 ** terms of the GNU Library General Public License as published by the Free
00010 ** Software Foundation; either version 2 of the License, or (at your option)
00011 ** any later version.
00012 ** 
00013 ** XSB is distributed in the hope that it will be useful, but WITHOUT ANY
00014 ** WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00015 ** FOR A PARTICULAR PURPOSE.  See the GNU Library General Public License for
00016 ** more details.
00017 ** 
00018 ** You should have received a copy of the GNU Library General Public License
00019 ** along with XSB; if not, write to the Free Software Foundation,
00020 ** Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00021 **
00022 ** $Id: gc_copy.h,v 1.6 2005/01/14 18:31:16 ruim Exp $
00023 ** 
00024 */
00025 
00026 /*=======================================================================*/
00027 /*  Heap collection by copying                                           */
00028 /*  Marking is finished and new heap allocated                           */
00029 /*  Idea is to copy a la Cheney and copy immediatly back to original     */
00030 /*          heap - this allows release of the new heap                   */
00031 /*          Cheney is slightly adapted to make it possible to have       */
00032 /*          the copy back as a mem copy; so heap pointers during Cheney  */
00033 /*          will already point to the final destination                  */
00034 /*                                                                       */
00035 /*  It is very similar to the BinProlog garbage collector.               */
00036 /*=======================================================================*/
00037 
00038 #ifdef GC
00039 
00040 /* the following variables are set by copy_heap() and used as */
00041 /* globals in the two functions below.                        */
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 } /* CHECK */
00054 #define GCDBG(mes,val) /*if (num_gc == 61)*/ 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) /* make sure this macro does not modify HP ! */\
00072     i = HP-heap_bot; \
00073     while (h_marked(--i)) ; /* assumes that h_marked[-1] = 0 !!! */\
00074     /* while (--i >= 0 && h_marked(i)) ; otherwise */\
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); /* leave a forwarding pointer */\
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     /* copy the block into the new heap area */
00089     copy_block(hp,next);
00090 
00091     /* perform a Cheney scan: pointer "scan" chases the "next" pointer  */
00092     /* note that "next" is modified inside the for loop by copy_block() */
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)) { /* if structure not already copied */
00117           copy_block(addr,next); /* this modifies *addr */
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)) { /* if list head not already copied */
00130           copy_block(addr,next); /* this modifies *addr */
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 } /* find_and_copy_block */
00151 
00152 #endif /* GC */
00153 
00154 /*-------------------------------------------------------------------------*/
00155 #ifdef GC
00156 
00157 inline static void adapt_hreg_from_choicepoints(CTXTdeclc CPtr h)
00158 {
00159   CPtr b, bprev;
00160 
00161   /* only after copying collection */
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 } /* adapt_hreg_from_choicepoints */
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   /* the order in which stuff is copied might be important                 */
00210   /* but like the price of a ticket from Seattle to New York: nobody knows */
00211 
00212   /* trail */
00213   /* more precise traversal of trail possible */
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       /* re-tag pre image cells in trail */
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   /* choicepoints */
00241   /* a more precise traversal of choicepoints is possible */
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   /* local stack */
00255   /* a more precise traversal of local stack is possible */
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     /* now do the argument registers */
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     /* now do the delay register */
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 } /* copy_heap */
00310 
00311 #endif /* GC */
00312 

Generated on Wed Jul 26 13:30:41 2006 for XSB by  doxygen 1.4.5