Back to index

lightning-sunbird  0.9+nobinonly
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  *
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 use or copy this program
00009  * for any purpose,  provided the above notices are retained on all copies.
00010  * Permission to modify the code and to distribute modified code is granted,
00011  * provided the above notices are retained, and a notice that the code was
00012  * modified is included with the above copyright notice.
00013  *
00014  * This file contains the functions:
00015  *     ptr_t GC_build_flXXX(h, old_fl)
00016  *     void GC_new_hblk(n)
00017  */
00018 /* Boehm, May 19, 1994 2:09 pm PDT */
00019 
00020 
00021 # include <stdio.h>
00022 # include "gc_priv.h"
00023 
00024 #ifndef SMALL_CONFIG
00025 /*
00026  * Build a free list for size 1 objects inside hblk h.  Set the last link to
00027  * be ofl.  Return a pointer tpo the first free list entry.
00028  */
00029 ptr_t GC_build_fl1(h, ofl)
00030 struct hblk *h;
00031 ptr_t ofl;
00032 {
00033     register word * p = (word *)h;
00034     register word * lim = (word *)(h + 1);
00035     
00036     p[0] = (word)ofl;
00037     p[1] = (word)(p);
00038     p[2] = (word)(p+1);
00039     p[3] = (word)(p+2);
00040     p += 4;
00041     for (; p < lim; p += 4) {
00042         p[0] = (word)(p-1);
00043         p[1] = (word)(p);
00044         p[2] = (word)(p+1);
00045         p[3] = (word)(p+2);
00046     };
00047     return((ptr_t)(p-1));
00048 }
00049 
00050 /* The same for size 2 cleared objects */
00051 ptr_t GC_build_fl_clear2(h, ofl)
00052 struct hblk *h;
00053 ptr_t ofl;
00054 {
00055     register word * p = (word *)h;
00056     register word * lim = (word *)(h + 1);
00057     
00058     p[0] = (word)ofl;
00059     p[1] = 0;
00060     p[2] = (word)p;
00061     p[3] = 0;
00062     p += 4;
00063     for (; p < lim; p += 4) {
00064         p[0] = (word)(p-2);
00065         p[1] = 0;
00066         p[2] = (word)p;
00067         p[3] = 0;
00068     };
00069     return((ptr_t)(p-2));
00070 }
00071 
00072 /* The same for size 3 cleared objects */
00073 ptr_t GC_build_fl_clear3(h, ofl)
00074 struct hblk *h;
00075 ptr_t ofl;
00076 {
00077     register word * p = (word *)h;
00078     register word * lim = (word *)(h + 1) - 2;
00079     
00080     p[0] = (word)ofl;
00081     p[1] = 0;
00082     p[2] = 0;
00083     p += 3;
00084     for (; p < lim; p += 3) {
00085         p[0] = (word)(p-3);
00086         p[1] = 0;
00087         p[2] = 0;
00088     };
00089     return((ptr_t)(p-3));
00090 }
00091 
00092 /* The same for size 4 cleared objects */
00093 ptr_t GC_build_fl_clear4(h, ofl)
00094 struct hblk *h;
00095 ptr_t ofl;
00096 {
00097     register word * p = (word *)h;
00098     register word * lim = (word *)(h + 1);
00099     
00100     p[0] = (word)ofl;
00101     p[1] = 0;
00102     p[2] = 0;
00103     p[3] = 0;
00104     p += 4;
00105     for (; p < lim; p += 4) {
00106         p[0] = (word)(p-4);
00107         p[1] = 0;
00108         p[2] = 0;
00109         p[3] = 0;
00110     };
00111     return((ptr_t)(p-4));
00112 }
00113 
00114 /* The same for size 2 uncleared objects */
00115 ptr_t GC_build_fl2(h, ofl)
00116 struct hblk *h;
00117 ptr_t ofl;
00118 {
00119     register word * p = (word *)h;
00120     register word * lim = (word *)(h + 1);
00121     
00122     p[0] = (word)ofl;
00123     p[2] = (word)p;
00124     p += 4;
00125     for (; p < lim; p += 4) {
00126         p[0] = (word)(p-2);
00127         p[2] = (word)p;
00128     };
00129     return((ptr_t)(p-2));
00130 }
00131 
00132 /* The same for size 4 uncleared objects */
00133 ptr_t GC_build_fl4(h, ofl)
00134 struct hblk *h;
00135 ptr_t ofl;
00136 {
00137     register word * p = (word *)h;
00138     register word * lim = (word *)(h + 1);
00139     
00140     p[0] = (word)ofl;
00141     p[4] = (word)p;
00142     p += 8;
00143     for (; p < lim; p += 8) {
00144         p[0] = (word)(p-4);
00145         p[4] = (word)p;
00146     };
00147     return((ptr_t)(p-4));
00148 }
00149 
00150 #endif /* !SMALL_CONFIG */
00151 
00152 /*
00153  * Allocate a new heapblock for small objects of size n.
00154  * Add all of the heapblock's objects to the free list for objects
00155  * of that size.
00156  * Set all mark bits if objects are uncollectable.
00157  * Will fail to do anything if we are out of memory.
00158  */
00159 void GC_new_hblk(sz, kind)
00160 register word sz;
00161 int kind;
00162 {
00163     register word *p,
00164                 *prev;
00165     word *last_object;             /* points to last object in new hblk      */
00166     register struct hblk *h;       /* the new heap block                     */
00167     register GC_bool clear = GC_obj_kinds[kind].ok_init;
00168 
00169 #   ifdef PRINTSTATS
00170        if ((sizeof (struct hblk)) > HBLKSIZE) {
00171            ABORT("HBLK SZ inconsistency");
00172         }
00173 #   endif
00174 
00175   /* Allocate a new heap block */
00176     h = GC_allochblk(sz, kind, 0);
00177     if (h == 0) return;
00178 
00179   /* Mark all objects if appropriate. */
00180       if (IS_UNCOLLECTABLE(kind)) GC_set_hdr_marks(HDR(h));
00181 
00182   /* Handle small objects sizes more efficiently.  For larger objects        */
00183   /* the difference is less significant.                       */
00184 #  ifndef SMALL_CONFIG
00185     switch (sz) {
00186         case 1: GC_obj_kinds[kind].ok_freelist[1] =
00187                 GC_build_fl1(h, GC_obj_kinds[kind].ok_freelist[1]);
00188               return;
00189         case 2: if (clear) {
00190                   GC_obj_kinds[kind].ok_freelist[2] =
00191                     GC_build_fl_clear2(h, GC_obj_kinds[kind].ok_freelist[2]);
00192               } else {
00193                   GC_obj_kinds[kind].ok_freelist[2] =
00194                     GC_build_fl2(h, GC_obj_kinds[kind].ok_freelist[2]);
00195               }
00196               return;
00197         case 3: if (clear) {
00198                   GC_obj_kinds[kind].ok_freelist[3] =
00199                     GC_build_fl_clear3(h, GC_obj_kinds[kind].ok_freelist[3]);
00200                   return;
00201               } else {
00202                   /* It's messy to do better than the default here. */
00203                   break;
00204               }
00205         case 4: if (clear) {
00206                   GC_obj_kinds[kind].ok_freelist[4] =
00207                     GC_build_fl_clear4(h, GC_obj_kinds[kind].ok_freelist[4]);
00208               } else {
00209                   GC_obj_kinds[kind].ok_freelist[4] =
00210                     GC_build_fl4(h, GC_obj_kinds[kind].ok_freelist[4]);
00211               }
00212               return;
00213         default:
00214               break;
00215     }
00216 #  endif /* !SMALL_CONFIG */
00217     
00218   /* Clear the page if necessary. */
00219     if (clear) BZERO(h, HBLKSIZE);
00220     
00221   /* Add objects to free list */
00222     p = &(h -> hb_body[sz]);       /* second object in *h      */
00223     prev = &(h -> hb_body[0]);            /* One object behind p      */
00224     last_object = (word *)((char *)h + HBLKSIZE);
00225     last_object -= sz;
00226                          /* Last place for last object to start */
00227 
00228   /* make a list of all objects in *h with head as last object */
00229     while (p <= last_object) {
00230       /* current object's link points to last object */
00231         obj_link(p) = (ptr_t)prev;
00232        prev = p;
00233        p += sz;
00234     }
00235     p -= sz;                /* p now points to last object */
00236 
00237   /*
00238    * put p (which is now head of list of objects in *h) as first
00239    * pointer in the appropriate free list for this size.
00240    */
00241       obj_link(h -> hb_body) = GC_obj_kinds[kind].ok_freelist[sz];
00242       GC_obj_kinds[kind].ok_freelist[sz] = ((ptr_t)p);
00243 }
00244