C:/Users/Dennis/src/lang/russell.orig/src/gc/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,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  * This file contains the functions:
00012  *      ptr_t GC_build_flXXX(h, old_fl)
00013  *      void GC_new_hblk(n)
00014  */
00015 
00016 
00017 # include <stdio.h>
00018 # include "gc_private.h"
00019 
00020 /*
00021  * Build a free list for size 1 objects inside hblk h.  Set the last link to
00022  * be ofl.  Return a pointer tpo the first free list entry.
00023  */
00024 ptr_t GC_build_fl1(h, ofl)
00025 struct hblk *h;
00026 ptr_t ofl;
00027 {
00028     register word * p = (word *)h;
00029     register word * lim = (word *)(h + 1);
00030     
00031     p[0] = (word)ofl;
00032     p[1] = (word)(p);
00033     p[2] = (word)(p+1);
00034     p[3] = (word)(p+2);
00035     p += 4;
00036     for (; p < lim; p += 4) {
00037         p[0] = (word)(p-1);
00038         p[1] = (word)(p);
00039         p[2] = (word)(p+1);
00040         p[3] = (word)(p+2);
00041     };
00042     return((ptr_t)(p-1));
00043 }
00044 
00045 /* The same for size 2 cleared objects */
00046 ptr_t GC_build_fl_clear2(h, ofl)
00047 struct hblk *h;
00048 ptr_t ofl;
00049 {
00050     register word * p = (word *)h;
00051     register word * lim = (word *)(h + 1);
00052     
00053     p[0] = (word)ofl;
00054     p[1] = 0;
00055     p[2] = (word)p;
00056     p[3] = 0;
00057     p += 4;
00058     for (; p < lim; p += 4) {
00059         p[0] = (word)(p-2);
00060         p[1] = 0;
00061         p[2] = (word)p;
00062         p[3] = 0;
00063     };
00064     return((ptr_t)(p-2));
00065 }
00066 
00067 /* The same for size 3 cleared objects */
00068 ptr_t GC_build_fl_clear3(h, ofl)
00069 struct hblk *h;
00070 ptr_t ofl;
00071 {
00072     register word * p = (word *)h;
00073     register word * lim = (word *)(h + 1) - 2;
00074     
00075     p[0] = (word)ofl;
00076     p[1] = 0;
00077     p[2] = 0;
00078     p += 3;
00079     for (; p < lim; p += 3) {
00080         p[0] = (word)(p-3);
00081         p[1] = 0;
00082         p[2] = 0;
00083     };
00084     return((ptr_t)(p-3));
00085 }
00086 
00087 /* The same for size 4 cleared objects */
00088 ptr_t GC_build_fl_clear4(h, ofl)
00089 struct hblk *h;
00090 ptr_t ofl;
00091 {
00092     register word * p = (word *)h;
00093     register word * lim = (word *)(h + 1);
00094     
00095     p[0] = (word)ofl;
00096     p[1] = 0;
00097     p[2] = 0;
00098     p[3] = 0;
00099     p += 4;
00100     for (; p < lim; p += 4) {
00101         p[0] = (word)(p-4);
00102         p[1] = 0;
00103         p[2] = 0;
00104         p[3] = 0;
00105     };
00106     return((ptr_t)(p-4));
00107 }
00108 
00109 /* The same for size 2 uncleared objects */
00110 ptr_t GC_build_fl2(h, ofl)
00111 struct hblk *h;
00112 ptr_t ofl;
00113 {
00114     register word * p = (word *)h;
00115     register word * lim = (word *)(h + 1);
00116     
00117     p[0] = (word)ofl;
00118     p[2] = (word)p;
00119     p += 4;
00120     for (; p < lim; p += 4) {
00121         p[0] = (word)(p-2);
00122         p[2] = (word)p;
00123     };
00124     return((ptr_t)(p-2));
00125 }
00126 
00127 /* The same for size 4 uncleared objects */
00128 ptr_t GC_build_fl4(h, ofl)
00129 struct hblk *h;
00130 ptr_t ofl;
00131 {
00132     register word * p = (word *)h;
00133     register word * lim = (word *)(h + 1);
00134     
00135     p[0] = (word)ofl;
00136     p[4] = (word)p;
00137     p += 8;
00138     for (; p < lim; p += 8) {
00139         p[0] = (word)(p-4);
00140         p[4] = (word)p;
00141     };
00142     return((ptr_t)(p-4));
00143 }
00144 
00145 
00146 /*
00147  * Allocate a new heapblock for small objects of size n.
00148  * Add all of the heapblock's objects to the free list for objects
00149  * of that size.  Will fail to do anything if we are out of memory.
00150  */
00151 void GC_new_hblk(sz, kind)
00152 register word sz;
00153 int kind;
00154 {
00155     register word *p,
00156                   *prev;
00157     word *last_object;          /* points to last object in new hblk    */
00158     register struct hblk *h;    /* the new heap block                   */
00159     register bool clear = GC_obj_kinds[kind].ok_init;
00160 
00161 #   ifdef PRINTSTATS
00162         if ((sizeof (struct hblk)) > HBLKSIZE) {
00163             abort("HBLK SZ inconsistency");
00164         }
00165 #   endif
00166 
00167   /* Allocate a new heap block */
00168     h = GC_allochblk(sz, kind);
00169     if (h == 0) return;
00170 
00171   /* Handle small objects sizes more efficiently.  For larger objects   */
00172   /* the difference is less significant.                                */
00173     switch (sz) {
00174         case 1: GC_obj_kinds[kind].ok_freelist[1] =
00175                   GC_build_fl1(h, GC_obj_kinds[kind].ok_freelist[1]);
00176                 return;
00177         case 2: if (clear) {
00178                     GC_obj_kinds[kind].ok_freelist[2] =
00179                       GC_build_fl_clear2(h, GC_obj_kinds[kind].ok_freelist[2]);
00180                 } else {
00181                     GC_obj_kinds[kind].ok_freelist[2] =
00182                       GC_build_fl2(h, GC_obj_kinds[kind].ok_freelist[2]);
00183                 }
00184                 return;
00185         case 3: if (clear) {
00186                     GC_obj_kinds[kind].ok_freelist[3] =
00187                       GC_build_fl_clear3(h, GC_obj_kinds[kind].ok_freelist[3]);
00188                     return;
00189                 } else {
00190                     /* It's messy to do better than the default here. */
00191                     break;
00192                 }
00193         case 4: if (clear) {
00194                     GC_obj_kinds[kind].ok_freelist[4] =
00195                       GC_build_fl_clear4(h, GC_obj_kinds[kind].ok_freelist[4]);
00196                 } else {
00197                     GC_obj_kinds[kind].ok_freelist[4] =
00198                       GC_build_fl4(h, GC_obj_kinds[kind].ok_freelist[4]);
00199                 }
00200                 return;
00201         default:
00202                 break;
00203     }
00204     
00205   /* Clear the page if necessary. */
00206     if (clear) bzero((char *)h, (int)HBLKSIZE);
00207     
00208   /* Add objects to free list */
00209     p = &(h -> hb_body[sz]);    /* second object in *h  */
00210     prev = &(h -> hb_body[0]);          /* One object behind p  */
00211     last_object = ((word *)((char *)h + HBLKSIZE)) - 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) = GC_obj_kinds[kind].ok_freelist[sz];
00228       GC_obj_kinds[kind].ok_freelist[sz] = ((ptr_t)p);
00229 }
00230 

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