2 * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
3 * Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved.
5 * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
6 * OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
8 * Permission is hereby granted to use or copy this program
9 * for any purpose, provided the above notices are retained on all copies.
10 * Permission to modify the code and to distribute modified code is granted,
11 * provided the above notices are retained, and a notice that the code was
12 * modified is included with the above copyright notice.
14 * This file contains the functions:
15 * ptr_t GC_build_flXXX(h, old_fl)
18 /* Boehm, May 19, 1994 2:09 pm PDT */
26 * Build a free list for size 1 objects inside hblk h. Set the last link to
27 * be ofl. Return a pointer tpo the first free list entry.
29 ptr_t GC_build_fl1(h, ofl)
33 register word * p = (word *)h;
34 register word * lim = (word *)(h + 1);
41 for (; p < lim; p += 4) {
50 /* The same for size 2 cleared objects */
51 ptr_t GC_build_fl_clear2(h, ofl)
55 register word * p = (word *)h;
56 register word * lim = (word *)(h + 1);
63 for (; p < lim; p += 4) {
72 /* The same for size 3 cleared objects */
73 ptr_t GC_build_fl_clear3(h, ofl)
77 register word * p = (word *)h;
78 register word * lim = (word *)(h + 1) - 2;
84 for (; p < lim; p += 3) {
92 /* The same for size 4 cleared objects */
93 ptr_t GC_build_fl_clear4(h, ofl)
97 register word * p = (word *)h;
98 register word * lim = (word *)(h + 1);
105 for (; p < lim; p += 4) {
106 PREFETCH_FOR_WRITE(p+64);
111 return((ptr_t)(p-4));
114 /* The same for size 2 uncleared objects */
115 ptr_t GC_build_fl2(h, ofl)
119 register word * p = (word *)h;
120 register word * lim = (word *)(h + 1);
125 for (; p < lim; p += 4) {
129 return((ptr_t)(p-2));
132 /* The same for size 4 uncleared objects */
133 ptr_t GC_build_fl4(h, ofl)
137 register word * p = (word *)h;
138 register word * lim = (word *)(h + 1);
143 for (; p < lim; p += 8) {
144 PREFETCH_FOR_WRITE(p+64);
148 return((ptr_t)(p-4));
151 #endif /* !SMALL_CONFIG */
154 * Allocate a new heapblock for small objects of size n.
155 * Add all of the heapblock's objects to the free list for objects
157 * Set all mark bits if objects are uncollectable.
158 * Will fail to do anything if we are out of memory.
160 void GC_new_hblk(sz, kind)
166 word *last_object; /* points to last object in new hblk */
167 register struct hblk *h; /* the new heap block */
168 register GC_bool clear = GC_obj_kinds[kind].ok_init;
171 if ((sizeof (struct hblk)) > HBLKSIZE) {
172 ABORT("HBLK SZ inconsistency");
176 /* Allocate a new heap block */
177 h = GC_allochblk(sz, kind, 0);
180 /* Mark all objects if appropriate. */
181 if (IS_UNCOLLECTABLE(kind)) GC_set_hdr_marks(HDR(h));
183 PREFETCH_FOR_WRITE((char *)h);
184 PREFETCH_FOR_WRITE((char *)h + 128);
185 PREFETCH_FOR_WRITE((char *)h + 256);
186 PREFETCH_FOR_WRITE((char *)h + 378);
187 /* Handle small objects sizes more efficiently. For larger objects */
188 /* the difference is less significant. */
189 # ifndef SMALL_CONFIG
191 case 1: GC_obj_kinds[kind].ok_freelist[1] =
192 GC_build_fl1(h, GC_obj_kinds[kind].ok_freelist[1]);
195 GC_obj_kinds[kind].ok_freelist[2] =
196 GC_build_fl_clear2(h, GC_obj_kinds[kind].ok_freelist[2]);
198 GC_obj_kinds[kind].ok_freelist[2] =
199 GC_build_fl2(h, GC_obj_kinds[kind].ok_freelist[2]);
203 GC_obj_kinds[kind].ok_freelist[3] =
204 GC_build_fl_clear3(h, GC_obj_kinds[kind].ok_freelist[3]);
207 /* It's messy to do better than the default here. */
211 GC_obj_kinds[kind].ok_freelist[4] =
212 GC_build_fl_clear4(h, GC_obj_kinds[kind].ok_freelist[4]);
214 GC_obj_kinds[kind].ok_freelist[4] =
215 GC_build_fl4(h, GC_obj_kinds[kind].ok_freelist[4]);
221 # endif /* !SMALL_CONFIG */
223 /* Clear the page if necessary. */
224 if (clear) BZERO(h, HBLKSIZE);
226 /* Add objects to free list */
227 p = &(h -> hb_body[sz]); /* second object in *h */
228 prev = &(h -> hb_body[0]); /* One object behind p */
229 last_object = (word *)((char *)h + HBLKSIZE);
231 /* Last place for last object to start */
233 /* make a list of all objects in *h with head as last object */
234 while (p <= last_object) {
235 /* current object's link points to last object */
236 obj_link(p) = (ptr_t)prev;
240 p -= sz; /* p now points to last object */
243 * put p (which is now head of list of objects in *h) as first
244 * pointer in the appropriate free list for this size.
246 obj_link(h -> hb_body) = GC_obj_kinds[kind].ok_freelist[sz];
247 GC_obj_kinds[kind].ok_freelist[sz] = ((ptr_t)p);