e5580e4ca218d9770f7dcf171bf4cc61420852c2
[platform/upstream/gcc.git] / 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
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((ptr_t)(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((ptr_t)(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((ptr_t)h);
175     PREFETCH_FOR_WRITE((ptr_t)h + 128);
176     PREFETCH_FOR_WRITE((ptr_t)h + 256);
177     PREFETCH_FOR_WRITE((ptr_t)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