C:/Users/Dennis/src/lang/russell.orig/src/gc/headers.c

Go to the documentation of this file.
00001 /* 
00002  * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
00003  * Copyright (c) 1991, 1992 by Xerox Corporation.  All rights reserved.
00004  *
00005  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
00006  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
00007  *
00008  * Permission is hereby granted to copy this garbage collector for any purpose,
00009  * provided the above notices are retained on all copies.
00010  */
00011  
00012 /*
00013  * This implements:
00014  * 1. allocation of heap block headers
00015  * 2. A map from addresses to heap block addresses to heap block headers
00016  *
00017  * Access speed is crucial.  We implement an index structure based on a 2
00018  * level tree.
00019  * For 64 bit machines this will have to be rewritten.  We expect that the
00020  * winning strategy there is to use a hash table as a cache, with
00021  * collisions resolved through a 4 or 5 level tree.
00022  */
00023  
00024 # include "gc_private.h"
00025 
00026 # if CPP_WORDSZ != 32
00027 #   if CPP_WORDSZ > 32
00028         --> This needs to be reimplemented.  See above.
00029 #   else
00030         --> Get a real machine.
00031 #   endif
00032 # endif
00033  
00034 hdr ** GC_top_index [TOP_SZ];
00035  
00036 typedef hdr * bottom_index[BOTTOM_SZ];
00037  
00038 /*
00039  * The bottom level index contains one of three kinds of values:
00040  * 0 means we're not responsible for this block.
00041  * 1 < (long)X <= MAX_JUMP means the block starts at least
00042  *        X * HBLKSIZE bytes before the current address.
00043  * A valid pointer points to a hdr structure. (The above can't be
00044  * valid pointers due to the GET_MEM return convention.)
00045  */
00046  
00047 static bottom_index all_nils = { 0 };
00048  
00049 /* Non-macro version of header location routine */
00050 hdr * GC_find_header(h)
00051 ptr_t h;
00052 {
00053    return(HDR(h));
00054 }
00055  
00056 /* Routines to dynamically allocate collector data structures that will */
00057 /* never be freed.                                                       */
00058  
00059 static char * scratch_free_ptr = 0;
00060  
00061 static char * scratch_end_ptr = 0;
00062  
00063 ptr_t GC_scratch_alloc(bytes)
00064 register word bytes;
00065 {
00066     register char * result = scratch_free_ptr;
00067     scratch_free_ptr += bytes;
00068     if (scratch_free_ptr <= scratch_end_ptr) {
00069         return(result);
00070     }
00071     {
00072         long bytes_to_get = ((HINCR+1) * HBLKSIZE + bytes) & ~(HBLKSIZE - 1);
00073          
00074         scratch_free_ptr = (char *)GET_MEM(bytes_to_get);
00075         if (scratch_free_ptr == 0) {
00076             GC_err_printf0("Out of memory - trying to allocate less\n");
00077             result = (char *)GET_MEM(bytes);
00078             if (result == 0) {
00079                 GC_err_printf0("Out of memory - giving up\n");
00080             } else {
00081                 scratch_free_ptr -= bytes;
00082                 return(result);
00083             }
00084         }
00085         scratch_end_ptr = scratch_free_ptr + bytes_to_get;
00086         return(GC_scratch_alloc(bytes));
00087     }
00088 }
00089 
00090 static hdr * hdr_free_list = 0;
00091 
00092 /* Return an uninitialized header */
00093 static hdr * alloc_hdr()
00094 {
00095     register hdr * result;
00096     
00097     if (hdr_free_list == 0) {
00098         result = (hdr *) GC_scratch_alloc((word)(sizeof(hdr)));
00099     } else {
00100         result = hdr_free_list;
00101         hdr_free_list = (hdr *) (result -> hb_next);
00102     }
00103     return(result);
00104 }
00105 
00106 static void free_hdr(hhdr)
00107 hdr * hhdr;
00108 {
00109     hhdr -> hb_next = (struct hblk *) hdr_free_list;
00110     hdr_free_list = hhdr;
00111 }
00112  
00113 GC_init_headers()
00114 {
00115     register int i;
00116      
00117     for (i = 0; i < TOP_SZ; i++) {
00118         GC_top_index[i] = all_nils;
00119     }
00120 }
00121 
00122 /* Make sure that there is a bottom level index block for address addr  */
00123 static void get_index(addr)
00124 register word addr;
00125 {
00126     register word indx =
00127                 (word)(addr) >> (LOG_BOTTOM_SZ + LOG_HBLKSIZE);
00128                 
00129     if (GC_top_index[indx] == all_nils) {
00130         GC_top_index[indx] = (hdr **)
00131                         GC_scratch_alloc((word)(sizeof (bottom_index)));
00132         bzero((char *)(GC_top_index[indx]), (int)(sizeof (bottom_index)));
00133     }
00134 }
00135 
00136 /* Install a header for block h.  */
00137 /* The header is uninitialized.   */
00138 void GC_install_header(h)
00139 register struct hblk * h;
00140 {
00141     get_index((word) h);
00142     HDR(h) = alloc_hdr();
00143 }
00144 
00145 /* Set up forwarding counts for block h of size sz */
00146 void GC_install_counts(h, sz)
00147 register struct hblk * h;
00148 register word sz; /* bytes */
00149 {
00150     register struct hblk * hbp;
00151     register int i;
00152     
00153     for (hbp = h; (char *)hbp < (char *)h + sz; hbp += BOTTOM_SZ) {
00154         get_index((word) hbp);
00155     }
00156     get_index((word)h + sz - 1);
00157     for (hbp = h + 1; (char *)hbp < (char *)h + sz; hbp += 1) {
00158         i = hbp - h;
00159         HDR(hbp) = (hdr *)(i > MAX_JUMP? MAX_JUMP : i);
00160     }
00161 }
00162 
00163 /* Remove the header for block h */
00164 void GC_remove_header(h)
00165 register struct hblk * h;
00166 {
00167     free_hdr(HDR(h));
00168     HDR(h) = 0;
00169 }
00170 
00171 /* Remove forwarding counts for h */
00172 void GC_remove_counts(h, sz)
00173 register struct hblk * h;
00174 register word sz; /* bytes */
00175 {
00176     register struct hblk * hbp;
00177     
00178     for (hbp = h+1; (char *)hbp < (char *)h + sz; hbp += 1) {
00179         HDR(hbp) = 0;
00180     }
00181 }
00182 
00183 /* Apply fn to all allocated blocks */
00184 /*VARARGS1*/
00185 void GC_apply_to_all_blocks(fn, client_data)
00186 void (*fn)(/* struct hblk *h, word client_data */);
00187 word client_data;
00188 {
00189     register int i, j;
00190     register hdr ** index_p;
00191     
00192     for (i = 0; i < TOP_SZ; i++) {
00193         index_p = GC_top_index[i];
00194         if (index_p != all_nils) {
00195             for (j = BOTTOM_SZ-1; j >= 0;) {
00196                 if (!IS_FORWARDING_ADDR_OR_NIL(index_p[j])) {
00197                   if (index_p[j]->hb_map != GC_invalid_map) {
00198                     (*fn)(((struct hblk *)
00199                               (((i << LOG_BOTTOM_SZ) + j) << LOG_HBLKSIZE)),
00200                           client_data);
00201                   }
00202                   j--;
00203                 } else if (index_p[j] == 0) {
00204                   j--;
00205                 } else {
00206                   j -= (int)(index_p[j]);
00207                 }
00208             }
00209         }
00210     }
00211 }

Generated on Fri Jan 25 10:39:45 2008 for russell by  doxygen 1.5.4