root/gc/new_hblk.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. GC_build_fl1
  2. GC_build_fl_clear2
  3. GC_build_fl_clear3
  4. GC_build_fl_clear4
  5. GC_build_fl2
  6. GC_build_fl4
  7. GC_build_fl
  8. GC_new_hblk

   1 /*
   2  * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
   3  * Copyright (c) 1991-1994 by Xerox Corporation.  All rights reserved.
   4  * Copyright (c) 2000 by Hewlett-Packard Company.  All rights reserved.
   5  *
   6  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
   7  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
   8  *
   9  * Permission is hereby granted to use or copy this program
  10  * for any purpose,  provided the above notices are retained on all copies.
  11  * Permission to modify the code and to distribute modified code is granted,
  12  * provided the above notices are retained, and a notice that the code was
  13  * modified is included with the above copyright notice.
  14  *
  15  * This file contains the functions:
  16  *      ptr_t GC_build_flXXX(h, old_fl)
  17  *      void GC_new_hblk(n)
  18  */
  19 /* Boehm, May 19, 1994 2:09 pm PDT */
  20 
  21 
  22 # include <stdio.h>
  23 # include "private/gc_priv.h"
  24 
  25 #ifndef SMALL_CONFIG
  26 /*
  27  * Build a free list for size 1 objects inside hblk h.  Set the last link to
  28  * be ofl.  Return a pointer tpo the first free list entry.
  29  */
  30 ptr_t GC_build_fl1(h, ofl)
  31 struct hblk *h;
  32 ptr_t ofl;
  33 {
  34     register word * p = h -> hb_body;
  35     register word * lim = (word *)(h + 1);
  36     
  37     p[0] = (word)ofl;
  38     p[1] = (word)(p);
  39     p[2] = (word)(p+1);
  40     p[3] = (word)(p+2);
  41     p += 4;
  42     for (; p < lim; p += 4) {
  43         p[0] = (word)(p-1);
  44         p[1] = (word)(p);
  45         p[2] = (word)(p+1);
  46         p[3] = (word)(p+2);
  47     };
  48     return((ptr_t)(p-1));
  49 }
  50 
  51 /* The same for size 2 cleared objects */
  52 ptr_t GC_build_fl_clear2(h, ofl)
  53 struct hblk *h;
  54 ptr_t ofl;
  55 {
  56     register word * p = h -> hb_body;
  57     register word * lim = (word *)(h + 1);
  58     
  59     p[0] = (word)ofl;
  60     p[1] = 0;
  61     p[2] = (word)p;
  62     p[3] = 0;
  63     p += 4;
  64     for (; p < lim; p += 4) {
  65         p[0] = (word)(p-2);
  66         p[1] = 0;
  67         p[2] = (word)p;
  68         p[3] = 0;
  69     };
  70     return((ptr_t)(p-2));
  71 }
  72 
  73 /* The same for size 3 cleared objects */
  74 ptr_t GC_build_fl_clear3(h, ofl)
  75 struct hblk *h;
  76 ptr_t ofl;
  77 {
  78     register word * p = h -> hb_body;
  79     register word * lim = (word *)(h + 1) - 2;
  80     
  81     p[0] = (word)ofl;
  82     p[1] = 0;
  83     p[2] = 0;
  84     p += 3;
  85     for (; p < lim; p += 3) {
  86         p[0] = (word)(p-3);
  87         p[1] = 0;
  88         p[2] = 0;
  89     };
  90     return((ptr_t)(p-3));
  91 }
  92 
  93 /* The same for size 4 cleared objects */
  94 ptr_t GC_build_fl_clear4(h, ofl)
  95 struct hblk *h;
  96 ptr_t ofl;
  97 {
  98     register word * p = h -> hb_body;
  99     register word * lim = (word *)(h + 1);
 100     
 101     p[0] = (word)ofl;
 102     p[1] = 0;
 103     p[2] = 0;
 104     p[3] = 0;
 105     p += 4;
 106     for (; p < lim; p += 4) {
 107         PREFETCH_FOR_WRITE((ptr_t)(p+64));
 108         p[0] = (word)(p-4);
 109         p[1] = 0;
 110         CLEAR_DOUBLE(p+2);
 111     };
 112     return((ptr_t)(p-4));
 113 }
 114 
 115 /* The same for size 2 uncleared objects */
 116 ptr_t GC_build_fl2(h, ofl)
 117 struct hblk *h;
 118 ptr_t ofl;
 119 {
 120     register word * p = h -> hb_body;
 121     register word * lim = (word *)(h + 1);
 122     
 123     p[0] = (word)ofl;
 124     p[2] = (word)p;
 125     p += 4;
 126     for (; p < lim; p += 4) {
 127         p[0] = (word)(p-2);
 128         p[2] = (word)p;
 129     };
 130     return((ptr_t)(p-2));
 131 }
 132 
 133 /* The same for size 4 uncleared objects */
 134 ptr_t GC_build_fl4(h, ofl)
 135 struct hblk *h;
 136 ptr_t ofl;
 137 {
 138     register word * p = h -> hb_body;
 139     register word * lim = (word *)(h + 1);
 140     
 141     p[0] = (word)ofl;
 142     p[4] = (word)p;
 143     p += 8;
 144     for (; p < lim; p += 8) {
 145         PREFETCH_FOR_WRITE((ptr_t)(p+64));
 146         p[0] = (word)(p-4);
 147         p[4] = (word)p;
 148     };
 149     return((ptr_t)(p-4));
 150 }
 151 
 152 #endif /* !SMALL_CONFIG */
 153 
 154 
 155 /* Build a free list for objects of size sz inside heap block h.        */
 156 /* Clear objects inside h if clear is set.  Add list to the end of      */
 157 /* the free list we build.  Return the new free list.                   */
 158 /* This could be called without the main GC lock, if we ensure that     */
 159 /* there is no concurrent collection which might reclaim objects that   */
 160 /* we have not yet allocated.                                           */
 161 ptr_t GC_build_fl(h, sz, clear, list)
 162 struct hblk *h;
 163 word sz;
 164 GC_bool clear;
 165 ptr_t list;
 166 {
 167   word *p, *prev;
 168   word *last_object;            /* points to last object in new hblk    */
 169 
 170   /* Do a few prefetches here, just because its cheap.          */
 171   /* If we were more serious about it, these should go inside   */
 172   /* the loops.  But write prefetches usually don't seem to     */
 173   /* matter much.                                               */
 174     PREFETCH_FOR_WRITE((ptr_t)h);
 175     PREFETCH_FOR_WRITE((ptr_t)h + 128);
 176     PREFETCH_FOR_WRITE((ptr_t)h + 256);
 177     PREFETCH_FOR_WRITE((ptr_t)h + 378);
 178   /* Handle small objects sizes more efficiently.  For larger objects   */
 179   /* the difference is less significant.                                */
 180 #  ifndef SMALL_CONFIG
 181     switch (sz) {
 182         case 1: return GC_build_fl1(h, list);
 183         case 2: if (clear) {
 184                     return GC_build_fl_clear2(h, list);
 185                 } else {
 186                     return GC_build_fl2(h, list);
 187                 }
 188         case 3: if (clear) {
 189                     return GC_build_fl_clear3(h, list);
 190                 } else {
 191                     /* It's messy to do better than the default here. */
 192                     break;
 193                 }
 194         case 4: if (clear) {
 195                     return GC_build_fl_clear4(h, list);
 196                 } else {
 197                     return GC_build_fl4(h, list);
 198                 }
 199         default:
 200                 break;
 201     }
 202 #  endif /* !SMALL_CONFIG */
 203     
 204   /* Clear the page if necessary. */
 205     if (clear) BZERO(h, HBLKSIZE);
 206     
 207   /* Add objects to free list */
 208     p = &(h -> hb_body[sz]);    /* second object in *h  */
 209     prev = &(h -> hb_body[0]);          /* One object behind p  */
 210     last_object = (word *)((char *)h + HBLKSIZE);
 211     last_object -= sz;
 212                             /* Last place for last object to start */
 213 
 214   /* make a list of all objects in *h with head as last object */
 215     while (p <= last_object) {
 216       /* current object's link points to last object */
 217         obj_link(p) = (ptr_t)prev;
 218         prev = p;
 219         p += sz;
 220     }
 221     p -= sz;                    /* p now points to last object */
 222 
 223   /*
 224    * put p (which is now head of list of objects in *h) as first
 225    * pointer in the appropriate free list for this size.
 226    */
 227       obj_link(h -> hb_body) = list;
 228       return ((ptr_t)p);
 229 }
 230 
 231 /*
 232  * Allocate a new heapblock for small objects of size n.
 233  * Add all of the heapblock's objects to the free list for objects
 234  * of that size.
 235  * Set all mark bits if objects are uncollectable.
 236  * Will fail to do anything if we are out of memory.
 237  */
 238 void GC_new_hblk(sz, kind)
 239 register word sz;
 240 int kind;
 241 {
 242     register struct hblk *h;    /* the new heap block                   */
 243     register GC_bool clear = GC_obj_kinds[kind].ok_init;
 244 
 245 #   ifdef PRINTSTATS
 246         if ((sizeof (struct hblk)) > HBLKSIZE) {
 247             ABORT("HBLK SZ inconsistency");
 248         }
 249 #   endif
 250   if (GC_debugging_started) clear = TRUE;
 251 
 252   /* Allocate a new heap block */
 253     h = GC_allochblk(sz, kind, 0);
 254     if (h == 0) return;
 255 
 256   /* Mark all objects if appropriate. */
 257       if (IS_UNCOLLECTABLE(kind)) GC_set_hdr_marks(HDR(h));
 258 
 259   /* Build the free list */
 260       GC_obj_kinds[kind].ok_freelist[sz] =
 261         GC_build_fl(h, sz, clear, GC_obj_kinds[kind].ok_freelist[sz]);
 262 }
 263 

/* [<][>][^][v][top][bottom][index][help] */