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 */
23 # include "private/gc_priv.h"
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.
30 ptr_t
GC_build_fl1(h
, ofl
)
34 register word
* p
= h
-> hb_body
;
35 register word
* lim
= (word
*)(h
+ 1);
42 for (; p
< lim
; p
+= 4) {
51 /* The same for size 2 cleared objects */
52 ptr_t
GC_build_fl_clear2(h
, ofl
)
56 register word
* p
= h
-> hb_body
;
57 register word
* lim
= (word
*)(h
+ 1);
64 for (; p
< lim
; p
+= 4) {
73 /* The same for size 3 cleared objects */
74 ptr_t
GC_build_fl_clear3(h
, ofl
)
78 register word
* p
= h
-> hb_body
;
79 register word
* lim
= (word
*)(h
+ 1) - 2;
85 for (; p
< lim
; p
+= 3) {
93 /* The same for size 4 cleared objects */
94 ptr_t
GC_build_fl_clear4(h
, ofl
)
98 register word
* p
= h
-> hb_body
;
99 register word
* lim
= (word
*)(h
+ 1);
106 for (; p
< lim
; p
+= 4) {
107 PREFETCH_FOR_WRITE(p
+64);
112 return((ptr_t
)(p
-4));
115 /* The same for size 2 uncleared objects */
116 ptr_t
GC_build_fl2(h
, ofl
)
120 register word
* p
= h
-> hb_body
;
121 register word
* lim
= (word
*)(h
+ 1);
126 for (; p
< lim
; p
+= 4) {
130 return((ptr_t
)(p
-2));
133 /* The same for size 4 uncleared objects */
134 ptr_t
GC_build_fl4(h
, ofl
)
138 register word
* p
= h
-> hb_body
;
139 register word
* lim
= (word
*)(h
+ 1);
144 for (; p
< lim
; p
+= 8) {
145 PREFETCH_FOR_WRITE(p
+64);
149 return((ptr_t
)(p
-4));
152 #endif /* !SMALL_CONFIG */
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
)
168 word
*last_object
; /* points to last object in new hblk */
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 */
174 PREFETCH_FOR_WRITE((char *)h
);
175 PREFETCH_FOR_WRITE((char *)h
+ 128);
176 PREFETCH_FOR_WRITE((char *)h
+ 256);
177 PREFETCH_FOR_WRITE((char *)h
+ 378);
178 /* Handle small objects sizes more efficiently. For larger objects */
179 /* the difference is less significant. */
180 # ifndef SMALL_CONFIG
182 case 1: return GC_build_fl1(h
, list
);
184 return GC_build_fl_clear2(h
, list
);
186 return GC_build_fl2(h
, list
);
189 return GC_build_fl_clear3(h
, list
);
191 /* It's messy to do better than the default here. */
195 return GC_build_fl_clear4(h
, list
);
197 return GC_build_fl4(h
, list
);
202 # endif /* !SMALL_CONFIG */
204 /* Clear the page if necessary. */
205 if (clear
) BZERO(h
, HBLKSIZE
);
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
);
212 /* Last place for last object to start */
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
;
221 p
-= sz
; /* p now points to last object */
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.
227 obj_link(h
-> hb_body
) = list
;
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
235 * Set all mark bits if objects are uncollectable.
236 * Will fail to do anything if we are out of memory.
238 void GC_new_hblk(sz
, kind
)
242 register struct hblk
*h
; /* the new heap block */
243 register GC_bool clear
= GC_obj_kinds
[kind
].ok_init
;
246 if ((sizeof (struct hblk
)) > HBLKSIZE
) {
247 ABORT("HBLK SZ inconsistency");
251 /* Allocate a new heap block */
252 h
= GC_allochblk(sz
, kind
, 0);
255 /* Mark all objects if appropriate. */
256 if (IS_UNCOLLECTABLE(kind
)) GC_set_hdr_marks(HDR(h
));
258 /* Build the free list */
259 GC_obj_kinds
[kind
].ok_freelist
[sz
] =
260 GC_build_fl(h
, sz
, clear
, GC_obj_kinds
[kind
].ok_freelist
[sz
]);