Fix mysterious unremovable file part 2 ?
[cacao.git] / src / mm / boehm-gc / new_hblk.c
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 #include "config.h"
22
23 # include <stdio.h>
24 # include "private/gc_priv.h"
25
26 #ifndef SMALL_CONFIG
27 /*
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.
30  */
31 ptr_t GC_build_fl1(h, ofl)
32 struct hblk *h;
33 ptr_t ofl;
34 {
35     register word * p = h -> hb_body;
36     register word * lim = (word *)(h + 1);
37     
38     p[0] = (word)ofl;
39     p[1] = (word)(p);
40     p[2] = (word)(p+1);
41     p[3] = (word)(p+2);
42     p += 4;
43     for (; p < lim; p += 4) {
44         p[0] = (word)(p-1);
45         p[1] = (word)(p);
46         p[2] = (word)(p+1);
47         p[3] = (word)(p+2);
48     };
49     return((ptr_t)(p-1));
50 }
51
52 /* The same for size 2 cleared objects */
53 ptr_t GC_build_fl_clear2(h, ofl)
54 struct hblk *h;
55 ptr_t ofl;
56 {
57     register word * p = h -> hb_body;
58     register word * lim = (word *)(h + 1);
59     
60     p[0] = (word)ofl;
61     p[1] = 0;
62     p[2] = (word)p;
63     p[3] = 0;
64     p += 4;
65     for (; p < lim; p += 4) {
66         p[0] = (word)(p-2);
67         p[1] = 0;
68         p[2] = (word)p;
69         p[3] = 0;
70     };
71     return((ptr_t)(p-2));
72 }
73
74 /* The same for size 3 cleared objects */
75 ptr_t GC_build_fl_clear3(h, ofl)
76 struct hblk *h;
77 ptr_t ofl;
78 {
79     register word * p = h -> hb_body;
80     register word * lim = (word *)(h + 1) - 2;
81     
82     p[0] = (word)ofl;
83     p[1] = 0;
84     p[2] = 0;
85     p += 3;
86     for (; p < lim; p += 3) {
87         p[0] = (word)(p-3);
88         p[1] = 0;
89         p[2] = 0;
90     };
91     return((ptr_t)(p-3));
92 }
93
94 /* The same for size 4 cleared objects */
95 ptr_t GC_build_fl_clear4(h, ofl)
96 struct hblk *h;
97 ptr_t ofl;
98 {
99     register word * p = h -> hb_body;
100     register word * lim = (word *)(h + 1);
101     
102     p[0] = (word)ofl;
103     p[1] = 0;
104     p[2] = 0;
105     p[3] = 0;
106     p += 4;
107     for (; p < lim; p += 4) {
108         PREFETCH_FOR_WRITE((ptr_t)(p+64));
109         p[0] = (word)(p-4);
110         p[1] = 0;
111         CLEAR_DOUBLE(p+2);
112     };
113     return((ptr_t)(p-4));
114 }
115
116 /* The same for size 2 uncleared objects */
117 ptr_t GC_build_fl2(h, ofl)
118 struct hblk *h;
119 ptr_t ofl;
120 {
121     register word * p = h -> hb_body;
122     register word * lim = (word *)(h + 1);
123     
124     p[0] = (word)ofl;
125     p[2] = (word)p;
126     p += 4;
127     for (; p < lim; p += 4) {
128         p[0] = (word)(p-2);
129         p[2] = (word)p;
130     };
131     return((ptr_t)(p-2));
132 }
133
134 /* The same for size 4 uncleared objects */
135 ptr_t GC_build_fl4(h, ofl)
136 struct hblk *h;
137 ptr_t ofl;
138 {
139     register word * p = h -> hb_body;
140     register word * lim = (word *)(h + 1);
141     
142     p[0] = (word)ofl;
143     p[4] = (word)p;
144     p += 8;
145     for (; p < lim; p += 8) {
146         PREFETCH_FOR_WRITE((ptr_t)(p+64));
147         p[0] = (word)(p-4);
148         p[4] = (word)p;
149     };
150     return((ptr_t)(p-4));
151 }
152
153 #endif /* !SMALL_CONFIG */
154
155
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)
163 struct hblk *h;
164 word sz;
165 GC_bool clear;
166 ptr_t list;
167 {
168   word *p, *prev;
169   word *last_object;            /* points to last object in new hblk    */
170
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     */
174   /* matter much.                                               */
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
182     switch (sz) {
183         case 1: return GC_build_fl1(h, list);
184         case 2: if (clear) {
185                     return GC_build_fl_clear2(h, list);
186                 } else {
187                     return GC_build_fl2(h, list);
188                 }
189         case 3: if (clear) {
190                     return GC_build_fl_clear3(h, list);
191                 } else {
192                     /* It's messy to do better than the default here. */
193                     break;
194                 }
195         case 4: if (clear) {
196                     return GC_build_fl_clear4(h, list);
197                 } else {
198                     return GC_build_fl4(h, list);
199                 }
200         default:
201                 break;
202     }
203 #  endif /* !SMALL_CONFIG */
204     
205   /* Clear the page if necessary. */
206     if (clear) BZERO(h, HBLKSIZE);
207     
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);
212     last_object -= sz;
213                             /* Last place for last object to start */
214
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;
219         prev = p;
220         p += sz;
221     }
222     p -= sz;                    /* p now points to last object */
223
224   /*
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.
227    */
228       obj_link(h -> hb_body) = list;
229       return ((ptr_t)p);
230 }
231
232 /*
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
235  * of that size.
236  * Set all mark bits if objects are uncollectable.
237  * Will fail to do anything if we are out of memory.
238  */
239 void GC_new_hblk(sz, kind)
240 register word sz;
241 int kind;
242 {
243     register struct hblk *h;    /* the new heap block                   */
244     register GC_bool clear = GC_obj_kinds[kind].ok_init;
245
246 #   ifdef PRINTSTATS
247         if ((sizeof (struct hblk)) > HBLKSIZE) {
248             ABORT("HBLK SZ inconsistency");
249         }
250 #   endif
251   if (GC_debugging_started) clear = TRUE;
252
253   /* Allocate a new heap block */
254     h = GC_allochblk(sz, kind, 0);
255     if (h == 0) return;
256
257   /* Mark all objects if appropriate. */
258       if (IS_UNCOLLECTABLE(kind)) GC_set_hdr_marks(HDR(h));
259
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]);
263 }
264