Back to index

plt-scheme  4.2.1
new_hblk.c
Go to the documentation of this file.
00001 /*
00002  * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
00003  * Copyright (c) 1991-1994 by Xerox Corporation.  All rights reserved.
00004  * Copyright (c) 2000 by Hewlett-Packard Company.  All rights reserved.
00005  *
00006  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
00007  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
00008  *
00009  * Permission is hereby granted to use or copy this program
00010  * for any purpose,  provided the above notices are retained on all copies.
00011  * Permission to modify the code and to distribute modified code is granted,
00012  * provided the above notices are retained, and a notice that the code was
00013  * modified is included with the above copyright notice.
00014  *
00015  * This file contains the functions:
00016  *     ptr_t GC_build_flXXX(h, old_fl)
00017  *     void GC_new_hblk(n)
00018  */
00019 /* Boehm, May 19, 1994 2:09 pm PDT */
00020 
00021 
00022 # include <stdio.h>
00023 # include "private/gc_priv.h"
00024 
00025 #ifndef SMALL_CONFIG
00026 /*
00027  * Build a free list for size 1 objects inside hblk h.  Set the last link to
00028  * be ofl.  Return a pointer tpo the first free list entry.
00029  */
00030 ptr_t GC_build_fl1(h, ofl)
00031 struct hblk *h;
00032 ptr_t ofl;
00033 {
00034     register word * p = h -> hb_body;
00035     register word * lim = (word *)(h + 1);
00036     
00037     p[0] = (word)ofl;
00038     p[1] = (word)(p);
00039     p[2] = (word)(p+1);
00040     p[3] = (word)(p+2);
00041     p += 4;
00042     for (; p < lim; p += 4) {
00043         p[0] = (word)(p-1);
00044         p[1] = (word)(p);
00045         p[2] = (word)(p+1);
00046         p[3] = (word)(p+2);
00047     };
00048     return((ptr_t)(p-1));
00049 }
00050 
00051 /* The same for size 2 cleared objects */
00052 ptr_t GC_build_fl_clear2(h, ofl)
00053 struct hblk *h;
00054 ptr_t ofl;
00055 {
00056     register word * p = h -> hb_body;
00057     register word * lim = (word *)(h + 1);
00058     
00059     p[0] = (word)ofl;
00060     p[1] = 0;
00061     p[2] = (word)p;
00062     p[3] = 0;
00063     p += 4;
00064     for (; p < lim; p += 4) {
00065         p[0] = (word)(p-2);
00066         p[1] = 0;
00067         p[2] = (word)p;
00068         p[3] = 0;
00069     };
00070     return((ptr_t)(p-2));
00071 }
00072 
00073 /* The same for size 3 cleared objects */
00074 ptr_t GC_build_fl_clear3(h, ofl)
00075 struct hblk *h;
00076 ptr_t ofl;
00077 {
00078     register word * p = h -> hb_body;
00079     register word * lim = (word *)(h + 1) - 2;
00080     
00081     p[0] = (word)ofl;
00082     p[1] = 0;
00083     p[2] = 0;
00084     p += 3;
00085     for (; p < lim; p += 3) {
00086         p[0] = (word)(p-3);
00087         p[1] = 0;
00088         p[2] = 0;
00089     };
00090     return((ptr_t)(p-3));
00091 }
00092 
00093 /* The same for size 4 cleared objects */
00094 ptr_t GC_build_fl_clear4(h, ofl)
00095 struct hblk *h;
00096 ptr_t ofl;
00097 {
00098     register word * p = h -> hb_body;
00099     register word * lim = (word *)(h + 1);
00100     
00101     p[0] = (word)ofl;
00102     p[1] = 0;
00103     p[2] = 0;
00104     p[3] = 0;
00105     p += 4;
00106     for (; p < lim; p += 4) {
00107        PREFETCH_FOR_WRITE((ptr_t)(p+64));
00108         p[0] = (word)(p-4);
00109         p[1] = 0;
00110        CLEAR_DOUBLE(p+2);
00111     };
00112     return((ptr_t)(p-4));
00113 }
00114 
00115 /* The same for size 2 uncleared objects */
00116 ptr_t GC_build_fl2(h, ofl)
00117 struct hblk *h;
00118 ptr_t ofl;
00119 {
00120     register word * p = h -> hb_body;
00121     register word * lim = (word *)(h + 1);
00122     
00123     p[0] = (word)ofl;
00124     p[2] = (word)p;
00125     p += 4;
00126     for (; p < lim; p += 4) {
00127         p[0] = (word)(p-2);
00128         p[2] = (word)p;
00129     };
00130     return((ptr_t)(p-2));
00131 }
00132 
00133 /* The same for size 4 uncleared objects */
00134 ptr_t GC_build_fl4(h, ofl)
00135 struct hblk *h;
00136 ptr_t ofl;
00137 {
00138     register word * p = h -> hb_body;
00139     register word * lim = (word *)(h + 1);
00140     
00141     p[0] = (word)ofl;
00142     p[4] = (word)p;
00143     p += 8;
00144     for (; p < lim; p += 8) {
00145        PREFETCH_FOR_WRITE((ptr_t)(p+64));
00146         p[0] = (word)(p-4);
00147         p[4] = (word)p;
00148     };
00149     return((ptr_t)(p-4));
00150 }
00151 
00152 #endif /* !SMALL_CONFIG */
00153 
00154 
00155 /* Build a free list for objects of size sz inside heap block h.      */
00156 /* Clear objects inside h if clear is set.  Add list to the end of    */
00157 /* the free list we build.  Return the new free list.                 */
00158 /* This could be called without the main GC lock, if we ensure that   */
00159 /* there is no concurrent collection which might reclaim objects that */
00160 /* we have not yet allocated.                                         */
00161 ptr_t GC_build_fl(h, sz, clear, list)
00162 struct hblk *h;
00163 word sz;
00164 GC_bool clear;
00165 ptr_t list;
00166 {
00167   word *p, *prev;
00168   word *last_object;        /* points to last object in new hblk      */
00169 
00170   /* Do a few prefetches here, just because its cheap.         */
00171   /* If we were more serious about it, these should go inside  */
00172   /* the loops.  But write prefetches usually don't seem to    */
00173   /* matter much.                                       */
00174     PREFETCH_FOR_WRITE((ptr_t)h);
00175     PREFETCH_FOR_WRITE((ptr_t)h + 128);
00176     PREFETCH_FOR_WRITE((ptr_t)h + 256);
00177     PREFETCH_FOR_WRITE((ptr_t)h + 378);
00178   /* Handle small objects sizes more efficiently.  For larger objects        */
00179   /* the difference is less significant.                       */
00180 #  ifndef SMALL_CONFIG
00181     switch (sz) {
00182         case 1: return GC_build_fl1(h, list);
00183         case 2: if (clear) {
00184                   return GC_build_fl_clear2(h, list);
00185               } else {
00186                   return GC_build_fl2(h, list);
00187               }
00188         case 3: if (clear) {
00189                   return GC_build_fl_clear3(h, list);
00190               } else {
00191                   /* It's messy to do better than the default here. */
00192                   break;
00193               }
00194         case 4: if (clear) {
00195                   return GC_build_fl_clear4(h, list);
00196               } else {
00197                   return GC_build_fl4(h, list);
00198               }
00199         default:
00200               break;
00201     }
00202 #  endif /* !SMALL_CONFIG */
00203     
00204   /* Clear the page if necessary. */
00205     if (clear) BZERO(h, HBLKSIZE);
00206     
00207   /* Add objects to free list */
00208     p = &(h -> hb_body[sz]);       /* second object in *h      */
00209     prev = &(h -> hb_body[0]);            /* One object behind p      */
00210     last_object = (word *)((char *)h + HBLKSIZE);
00211     last_object -= sz;
00212                          /* Last place for last object to start */
00213 
00214   /* make a list of all objects in *h with head as last object */
00215     while (p <= last_object) {
00216       /* current object's link points to last object */
00217         obj_link(p) = (ptr_t)prev;
00218        prev = p;
00219        p += sz;
00220     }
00221     p -= sz;                /* p now points to last object */
00222 
00223   /*
00224    * put p (which is now head of list of objects in *h) as first
00225    * pointer in the appropriate free list for this size.
00226    */
00227       obj_link(h -> hb_body) = list;
00228       return ((ptr_t)p);
00229 }
00230 
00231 /*
00232  * Allocate a new heapblock for small objects of size n.
00233  * Add all of the heapblock's objects to the free list for objects
00234  * of that size.
00235  * Set all mark bits if objects are uncollectable.
00236  * Will fail to do anything if we are out of memory.
00237  */
00238 void GC_new_hblk(sz, kind)
00239 register word sz;
00240 int kind;
00241 {
00242     register struct hblk *h;       /* the new heap block                     */
00243     register GC_bool clear = GC_obj_kinds[kind].ok_init;
00244 
00245 #   ifdef PRINTSTATS
00246        if ((sizeof (struct hblk)) > HBLKSIZE) {
00247            ABORT("HBLK SZ inconsistency");
00248         }
00249 #   endif
00250   if (GC_debugging_started) clear = TRUE;
00251 
00252   /* Allocate a new heap block */
00253     h = GC_allochblk(sz, kind, 0);
00254     if (h == 0) return;
00255 
00256   /* Mark all objects if appropriate. */
00257       if (IS_UNCOLLECTABLE(kind)) GC_set_hdr_marks(HDR(h));
00258 
00259   /* Build the free list */
00260       GC_obj_kinds[kind].ok_freelist[sz] =
00261        GC_build_fl(h, sz, clear, GC_obj_kinds[kind].ok_freelist[sz]);
00262 }
00263