Synopsis - Cross-Reference
File: /src/Synopsis/gc/new_hblk.c1/* 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(size) 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 2 (words) cleared objects inside hblk h. 28 * Set the last link to 29 * be ofl. Return a pointer tpo the first free list entry. 30 */ 31ptr_t GC_build_fl_clear2(struct hblk *h, ptr_t ofl) 32{ 33 word * p = (word *)(h -> hb_body); 34 word * lim = (word *)(h + 1); 35 36 p[0] = (word)ofl; 37 p[1] = 0; 38 p[2] = (word)p; 39 p[3] = 0; 40 p += 4; 41 for (; p < lim; p += 4) { 42 p[0] = (word)(p-2); 43 p[1] = 0; 44 p[2] = (word)p; 45 p[3] = 0; 46 }; 47 return((ptr_t)(p-2)); 48} 49 50/* The same for size 4 cleared objects */ 51ptr_t GC_build_fl_clear4(struct hblk *h, ptr_t ofl) 52{ 53 word * p = (word *)(h -> hb_body); 54 word * lim = (word *)(h + 1); 55 56 p[0] = (word)ofl; 57 p[1] = 0; 58 p[2] = 0; 59 p[3] = 0; 60 p += 4; 61 for (; p < lim; p += 4) { 62 PREFETCH_FOR_WRITE((ptr_t)(p+64)); 63 p[0] = (word)(p-4); 64 p[1] = 0; 65 CLEAR_DOUBLE(p+2); 66 }; 67 return((ptr_t)(p-4)); 68} 69 70/* The same for size 2 uncleared objects */ 71ptr_t GC_build_fl2(struct hblk *h, ptr_t ofl) 72{ 73 word * p = (word *)(h -> hb_body); 74 word * lim = (word *)(h + 1); 75 76 p[0] = (word)ofl; 77 p[2] = (word)p; 78 p += 4; 79 for (; p < lim; p += 4) { 80 p[0] = (word)(p-2); 81 p[2] = (word)p; 82 }; 83 return((ptr_t)(p-2)); 84} 85 86/* The same for size 4 uncleared objects */ 87ptr_t GC_build_fl4(struct hblk *h, ptr_t ofl) 88{ 89 word * p = (word *)(h -> hb_body); 90 word * lim = (word *)(h + 1); 91 92 p[0] = (word)ofl; 93 p[4] = (word)p; 94 p += 8; 95 for (; p < lim; p += 8) { 96 PREFETCH_FOR_WRITE((ptr_t)(p+64)); 97 p[0] = (word)(p-4); 98 p[4] = (word)p; 99 }; 100 return((ptr_t)(p-4)); 101} 102 103#endif /* !SMALL_CONFIG */ 104 105 106/* Build a free list for objects of size sz inside heap block h. */ 107/* Clear objects inside h if clear is set. Add list to the end of */ 108/* the free list we build. Return the new free list. */ 109/* This could be called without the main GC lock, if we ensure that */ 110/* there is no concurrent collection which might reclaim objects that */ 111/* we have not yet allocated. */ 112ptr_t GC_build_fl(struct hblk *h, size_t sz, GC_bool clear, ptr_t list) 113{ 114 word *p, *prev; 115 word *last_object; /* points to last object in new hblk */ 116 117 /* Do a few prefetches here, just because its cheap. */ 118 /* If we were more serious about it, these should go inside */ 119 /* the loops. But write prefetches usually don't seem to */ 120 /* matter much. */ 121 PREFETCH_FOR_WRITE((ptr_t)h); 122 PREFETCH_FOR_WRITE((ptr_t)h + 128); 123 PREFETCH_FOR_WRITE((ptr_t)h + 256); 124 PREFETCH_FOR_WRITE((ptr_t)h + 378); 125 /* Handle small objects sizes more efficiently. For larger objects */ 126 /* the difference is less significant. */ 127# ifndef SMALL_CONFIG 128 switch (sz) { 129 case 2: if (clear) { 130 return GC_build_fl_clear2(h, list); 131 } else { 132 return GC_build_fl2(h, list); 133 } 134 case 4: if (clear) { 135 return GC_build_fl_clear4(h, list); 136 } else { 137 return GC_build_fl4(h, list); 138 } 139 default: 140 break; 141 } 142# endif /* !SMALL_CONFIG */ 143 144 /* Clear the page if necessary. */ 145 if (clear) BZERO(h, HBLKSIZE); 146 147 /* Add objects to free list */ 148 p = (word *)(h -> hb_body) + sz; /* second object in *h */ 149 prev = (word *)(h -> hb_body); /* One object behind p */ 150 last_object = (word *)((char *)h + HBLKSIZE); 151 last_object -= sz; 152 /* Last place for last object to start */ 153 154 /* make a list of all objects in *h with head as last object */ 155 while (p <= last_object) { 156 /* current object's link points to last object */ 157 obj_link(p) = (ptr_t)prev; 158 prev = p; 159 p += sz; 160 } 161 p -= sz; /* p now points to last object */ 162 163 /* 164 * put p (which is now head of list of objects in *h) as first 165 * pointer in the appropriate free list for this size. 166 */ 167 obj_link(h -> hb_body) = list; 168 return ((ptr_t)p); 169} 170 171 172/* 173 * Allocate a new heapblock for small objects of size gran granules. 174 * Add all of the heapblock's objects to the free list for objects 175 * of that size. 176 * Set all mark bits if objects are uncollectable. 177 * Will fail to do anything if we are out of memory. 178 */ 179void GC_new_hblk(size_t gran, int kind) 180{ 181 struct hblk *h; /* the new heap block */ 182 GC_bool clear = GC_obj_kinds[kind].ok_init; 183 184 /* Ignore gcc "no effect" warning on the following: */ 185 GC_STATIC_ASSERT((sizeof (struct hblk)) == HBLKSIZE); 186 187 if (GC_debugging_started) clear = TRUE; 188 189 /* Allocate a new heap block */ 190 h = GC_allochblk(GRANULES_TO_BYTES(gran), kind, 0); 191 if (h == 0) return; 192 193 /* Mark all objects if appropriate. */ 194 if (IS_UNCOLLECTABLE(kind)) GC_set_hdr_marks(HDR(h)); 195 196 /* Build the free list */ 197 GC_obj_kinds[kind].ok_freelist[gran] = 198 GC_build_fl(h, GRANULES_TO_WORDS(gran), clear, 199 GC_obj_kinds[kind].ok_freelist[gran]); 200} 201