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.
6 * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
7 * OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
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.
15 * This file contains the functions:
16 * ptr_t GC_build_flXXX(h, old_fl)
19 /* Boehm, May 19, 1994 2:09 pm PDT */
24 # include "private/gc_priv.h"
28 * Build a free list for size 1 objects inside hblk h. Set the last link to
29 * be ofl. Return a pointer tpo the first free list entry.
31 ptr_t GC_build_fl1(h, ofl)
35 register word * p = h -> hb_body;
36 register word * lim = (word *)(h + 1);
43 for (; p < lim; p += 4) {
52 /* The same for size 2 cleared objects */
53 ptr_t GC_build_fl_clear2(h, ofl)
57 register word * p = h -> hb_body;
58 register word * lim = (word *)(h + 1);
65 for (; p < lim; p += 4) {
74 /* The same for size 3 cleared objects */
75 ptr_t GC_build_fl_clear3(h, ofl)
79 register word * p = h -> hb_body;
80 register word * lim = (word *)(h + 1) - 2;
86 for (; p < lim; p += 3) {
94 /* The same for size 4 cleared objects */
95 ptr_t GC_build_fl_clear4(h, ofl)
99 register word * p = h -> hb_body;
100 register word * lim = (word *)(h + 1);
107 for (; p < lim; p += 4) {
108 PREFETCH_FOR_WRITE((ptr_t)(p+64));
113 return((ptr_t)(p-4));
116 /* The same for size 2 uncleared objects */
117 ptr_t GC_build_fl2(h, ofl)
121 register word * p = h -> hb_body;
122 register word * lim = (word *)(h + 1);
127 for (; p < lim; p += 4) {
131 return((ptr_t)(p-2));
134 /* The same for size 4 uncleared objects */
135 ptr_t GC_build_fl4(h, ofl)
139 register word * p = h -> hb_body;
140 register word * lim = (word *)(h + 1);
145 for (; p < lim; p += 8) {
146 PREFETCH_FOR_WRITE((ptr_t)(p+64));
150 return((ptr_t)(p-4));
153 #endif /* !SMALL_CONFIG */
156 /* Build a free list for objects of size sz inside heap block h. */
157 /* Clear objects inside h if clear is set. Add list to the end of */
158 /* the free list we build. Return the new free list. */
159 /* This could be called without the main GC lock, if we ensure that */
160 /* there is no concurrent collection which might reclaim objects that */
161 /* we have not yet allocated. */
162 ptr_t GC_build_fl(h, sz, clear, list)
169 word *last_object; /* points to last object in new hblk */
171 /* Do a few prefetches here, just because its cheap. */
172 /* If we were more serious about it, these should go inside */
173 /* the loops. But write prefetches usually don't seem to */
175 PREFETCH_FOR_WRITE((ptr_t)h);
176 PREFETCH_FOR_WRITE((ptr_t)h + 128);
177 PREFETCH_FOR_WRITE((ptr_t)h + 256);
178 PREFETCH_FOR_WRITE((ptr_t)h + 378);
179 /* Handle small objects sizes more efficiently. For larger objects */
180 /* the difference is less significant. */
181 # ifndef SMALL_CONFIG
183 case 1: return GC_build_fl1(h, list);
185 return GC_build_fl_clear2(h, list);
187 return GC_build_fl2(h, list);
190 return GC_build_fl_clear3(h, list);
192 /* It's messy to do better than the default here. */
196 return GC_build_fl_clear4(h, list);
198 return GC_build_fl4(h, list);
203 # endif /* !SMALL_CONFIG */
205 /* Clear the page if necessary. */
206 if (clear) BZERO(h, HBLKSIZE);
208 /* Add objects to free list */
209 p = &(h -> hb_body[sz]); /* second object in *h */
210 prev = &(h -> hb_body[0]); /* One object behind p */
211 last_object = (word *)((char *)h + HBLKSIZE);
213 /* Last place for last object to start */
215 /* make a list of all objects in *h with head as last object */
216 while (p <= last_object) {
217 /* current object's link points to last object */
218 obj_link(p) = (ptr_t)prev;
222 p -= sz; /* p now points to last object */
225 * put p (which is now head of list of objects in *h) as first
226 * pointer in the appropriate free list for this size.
228 obj_link(h -> hb_body) = list;
233 * Allocate a new heapblock for small objects of size n.
234 * Add all of the heapblock's objects to the free list for objects
236 * Set all mark bits if objects are uncollectable.
237 * Will fail to do anything if we are out of memory.
239 void GC_new_hblk(sz, kind)
243 register struct hblk *h; /* the new heap block */
244 register GC_bool clear = GC_obj_kinds[kind].ok_init;
247 if ((sizeof (struct hblk)) > HBLKSIZE) {
248 ABORT("HBLK SZ inconsistency");
251 if (GC_debugging_started) clear = TRUE;
253 /* Allocate a new heap block */
254 h = GC_allochblk(sz, kind, 0);
257 /* Mark all objects if appropriate. */
258 if (IS_UNCOLLECTABLE(kind)) GC_set_hdr_marks(HDR(h));
260 /* Build the free list */
261 GC_obj_kinds[kind].ok_freelist[sz] =
262 GC_build_fl(h, sz, clear, GC_obj_kinds[kind].ok_freelist[sz]);