Mercurial > emacs
comparison gc/new_hblk.c @ 51488:5de98dce4bd1
*** empty log message ***
author | Dave Love <fx@gnu.org> |
---|---|
date | Thu, 05 Jun 2003 17:49:22 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
51487:01d68b199093 | 51488:5de98dce4bd1 |
---|---|
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(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(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((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 | |
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 |