OSDN Git Service

Initial revision
[pf3gnuchains/gcc-fork.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  *
5  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
6  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
7  *
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.
13  *
14  * This file contains the functions:
15  *      ptr_t GC_build_flXXX(h, old_fl)
16  *      void GC_new_hblk(n)
17  */
18 /* Boehm, May 19, 1994 2:09 pm PDT */
19
20
21 # include <stdio.h>
22 # include "gc_priv.h"
23
24 #ifndef SMALL_CONFIG
25 /*
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.
28  */
29 ptr_t GC_build_fl1(h, ofl)
30 struct hblk *h;
31 ptr_t ofl;
32 {
33     register word * p = (word *)h;
34     register word * lim = (word *)(h + 1);
35     
36     p[0] = (word)ofl;
37     p[1] = (word)(p);
38     p[2] = (word)(p+1);
39     p[3] = (word)(p+2);
40     p += 4;
41     for (; p < lim; p += 4) {
42         p[0] = (word)(p-1);
43         p[1] = (word)(p);
44         p[2] = (word)(p+1);
45         p[3] = (word)(p+2);
46     };
47     return((ptr_t)(p-1));
48 }
49
50 /* The same for size 2 cleared objects */
51 ptr_t GC_build_fl_clear2(h, ofl)
52 struct hblk *h;
53 ptr_t ofl;
54 {
55     register word * p = (word *)h;
56     register word * lim = (word *)(h + 1);
57     
58     p[0] = (word)ofl;
59     p[1] = 0;
60     p[2] = (word)p;
61     p[3] = 0;
62     p += 4;
63     for (; p < lim; p += 4) {
64         p[0] = (word)(p-2);
65         p[1] = 0;
66         p[2] = (word)p;
67         p[3] = 0;
68     };
69     return((ptr_t)(p-2));
70 }
71
72 /* The same for size 3 cleared objects */
73 ptr_t GC_build_fl_clear3(h, ofl)
74 struct hblk *h;
75 ptr_t ofl;
76 {
77     register word * p = (word *)h;
78     register word * lim = (word *)(h + 1) - 2;
79     
80     p[0] = (word)ofl;
81     p[1] = 0;
82     p[2] = 0;
83     p += 3;
84     for (; p < lim; p += 3) {
85         p[0] = (word)(p-3);
86         p[1] = 0;
87         p[2] = 0;
88     };
89     return((ptr_t)(p-3));
90 }
91
92 /* The same for size 4 cleared objects */
93 ptr_t GC_build_fl_clear4(h, ofl)
94 struct hblk *h;
95 ptr_t ofl;
96 {
97     register word * p = (word *)h;
98     register word * lim = (word *)(h + 1);
99     
100     p[0] = (word)ofl;
101     p[1] = 0;
102     p[2] = 0;
103     p[3] = 0;
104     p += 4;
105     for (; p < lim; p += 4) {
106         p[0] = (word)(p-4);
107         p[1] = 0;
108         p[2] = 0;
109         p[3] = 0;
110     };
111     return((ptr_t)(p-4));
112 }
113
114 /* The same for size 2 uncleared objects */
115 ptr_t GC_build_fl2(h, ofl)
116 struct hblk *h;
117 ptr_t ofl;
118 {
119     register word * p = (word *)h;
120     register word * lim = (word *)(h + 1);
121     
122     p[0] = (word)ofl;
123     p[2] = (word)p;
124     p += 4;
125     for (; p < lim; p += 4) {
126         p[0] = (word)(p-2);
127         p[2] = (word)p;
128     };
129     return((ptr_t)(p-2));
130 }
131
132 /* The same for size 4 uncleared objects */
133 ptr_t GC_build_fl4(h, ofl)
134 struct hblk *h;
135 ptr_t ofl;
136 {
137     register word * p = (word *)h;
138     register word * lim = (word *)(h + 1);
139     
140     p[0] = (word)ofl;
141     p[4] = (word)p;
142     p += 8;
143     for (; p < lim; p += 8) {
144         p[0] = (word)(p-4);
145         p[4] = (word)p;
146     };
147     return((ptr_t)(p-4));
148 }
149
150 #endif /* !SMALL_CONFIG */
151
152 /*
153  * Allocate a new heapblock for small objects of size n.
154  * Add all of the heapblock's objects to the free list for objects
155  * of that size.
156  * Set all mark bits if objects are uncollectable.
157  * Will fail to do anything if we are out of memory.
158  */
159 void GC_new_hblk(sz, kind)
160 register word sz;
161 int kind;
162 {
163     register word *p,
164                   *prev;
165     word *last_object;          /* points to last object in new hblk    */
166     register struct hblk *h;    /* the new heap block                   */
167     register GC_bool clear = GC_obj_kinds[kind].ok_init;
168
169 #   ifdef PRINTSTATS
170         if ((sizeof (struct hblk)) > HBLKSIZE) {
171             ABORT("HBLK SZ inconsistency");
172         }
173 #   endif
174
175   /* Allocate a new heap block */
176     h = GC_allochblk(sz, kind, 0);
177     if (h == 0) return;
178
179   /* Mark all objects if appropriate. */
180       if (IS_UNCOLLECTABLE(kind)) GC_set_hdr_marks(HDR(h));
181
182   /* Handle small objects sizes more efficiently.  For larger objects   */
183   /* the difference is less significant.                                */
184 #  ifndef SMALL_CONFIG
185     switch (sz) {
186         case 1: GC_obj_kinds[kind].ok_freelist[1] =
187                   GC_build_fl1(h, GC_obj_kinds[kind].ok_freelist[1]);
188                 return;
189         case 2: if (clear) {
190                     GC_obj_kinds[kind].ok_freelist[2] =
191                       GC_build_fl_clear2(h, GC_obj_kinds[kind].ok_freelist[2]);
192                 } else {
193                     GC_obj_kinds[kind].ok_freelist[2] =
194                       GC_build_fl2(h, GC_obj_kinds[kind].ok_freelist[2]);
195                 }
196                 return;
197         case 3: if (clear) {
198                     GC_obj_kinds[kind].ok_freelist[3] =
199                       GC_build_fl_clear3(h, GC_obj_kinds[kind].ok_freelist[3]);
200                     return;
201                 } else {
202                     /* It's messy to do better than the default here. */
203                     break;
204                 }
205         case 4: if (clear) {
206                     GC_obj_kinds[kind].ok_freelist[4] =
207                       GC_build_fl_clear4(h, GC_obj_kinds[kind].ok_freelist[4]);
208                 } else {
209                     GC_obj_kinds[kind].ok_freelist[4] =
210                       GC_build_fl4(h, GC_obj_kinds[kind].ok_freelist[4]);
211                 }
212                 return;
213         default:
214                 break;
215     }
216 #  endif /* !SMALL_CONFIG */
217     
218   /* Clear the page if necessary. */
219     if (clear) BZERO(h, HBLKSIZE);
220     
221   /* Add objects to free list */
222     p = &(h -> hb_body[sz]);    /* second object in *h  */
223     prev = &(h -> hb_body[0]);          /* One object behind p  */
224     last_object = (word *)((char *)h + HBLKSIZE);
225     last_object -= sz;
226                             /* Last place for last object to start */
227
228   /* make a list of all objects in *h with head as last object */
229     while (p <= last_object) {
230       /* current object's link points to last object */
231         obj_link(p) = (ptr_t)prev;
232         prev = p;
233         p += sz;
234     }
235     p -= sz;                    /* p now points to last object */
236
237   /*
238    * put p (which is now head of list of objects in *h) as first
239    * pointer in the appropriate free list for this size.
240    */
241       obj_link(h -> hb_body) = GC_obj_kinds[kind].ok_freelist[sz];
242       GC_obj_kinds[kind].ok_freelist[sz] = ((ptr_t)p);
243 }
244