OSDN Git Service

Imported version version 5.0alpha6.
[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         PREFETCH_FOR_WRITE(p+64);
107         p[0] = (word)(p-4);
108         p[1] = 0;
109         CLEAR_DOUBLE(p+2);
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         PREFETCH_FOR_WRITE(p+64);
145         p[0] = (word)(p-4);
146         p[4] = (word)p;
147     };
148     return((ptr_t)(p-4));
149 }
150
151 #endif /* !SMALL_CONFIG */
152
153 /*
154  * Allocate a new heapblock for small objects of size n.
155  * Add all of the heapblock's objects to the free list for objects
156  * of that size.
157  * Set all mark bits if objects are uncollectable.
158  * Will fail to do anything if we are out of memory.
159  */
160 void GC_new_hblk(sz, kind)
161 register word sz;
162 int kind;
163 {
164     register word *p,
165                   *prev;
166     word *last_object;          /* points to last object in new hblk    */
167     register struct hblk *h;    /* the new heap block                   */
168     register GC_bool clear = GC_obj_kinds[kind].ok_init;
169
170 #   ifdef PRINTSTATS
171         if ((sizeof (struct hblk)) > HBLKSIZE) {
172             ABORT("HBLK SZ inconsistency");
173         }
174 #   endif
175
176   /* Allocate a new heap block */
177     h = GC_allochblk(sz, kind, 0);
178     if (h == 0) return;
179
180   /* Mark all objects if appropriate. */
181       if (IS_UNCOLLECTABLE(kind)) GC_set_hdr_marks(HDR(h));
182
183   PREFETCH_FOR_WRITE((char *)h);
184   PREFETCH_FOR_WRITE((char *)h + 128);
185   PREFETCH_FOR_WRITE((char *)h + 256);
186   PREFETCH_FOR_WRITE((char *)h + 378);
187   /* Handle small objects sizes more efficiently.  For larger objects   */
188   /* the difference is less significant.                                */
189 #  ifndef SMALL_CONFIG
190     switch (sz) {
191         case 1: GC_obj_kinds[kind].ok_freelist[1] =
192                   GC_build_fl1(h, GC_obj_kinds[kind].ok_freelist[1]);
193                 return;
194         case 2: if (clear) {
195                     GC_obj_kinds[kind].ok_freelist[2] =
196                       GC_build_fl_clear2(h, GC_obj_kinds[kind].ok_freelist[2]);
197                 } else {
198                     GC_obj_kinds[kind].ok_freelist[2] =
199                       GC_build_fl2(h, GC_obj_kinds[kind].ok_freelist[2]);
200                 }
201                 return;
202         case 3: if (clear) {
203                     GC_obj_kinds[kind].ok_freelist[3] =
204                       GC_build_fl_clear3(h, GC_obj_kinds[kind].ok_freelist[3]);
205                     return;
206                 } else {
207                     /* It's messy to do better than the default here. */
208                     break;
209                 }
210         case 4: if (clear) {
211                     GC_obj_kinds[kind].ok_freelist[4] =
212                       GC_build_fl_clear4(h, GC_obj_kinds[kind].ok_freelist[4]);
213                 } else {
214                     GC_obj_kinds[kind].ok_freelist[4] =
215                       GC_build_fl4(h, GC_obj_kinds[kind].ok_freelist[4]);
216                 }
217                 return;
218         default:
219                 break;
220     }
221 #  endif /* !SMALL_CONFIG */
222     
223   /* Clear the page if necessary. */
224     if (clear) BZERO(h, HBLKSIZE);
225     
226   /* Add objects to free list */
227     p = &(h -> hb_body[sz]);    /* second object in *h  */
228     prev = &(h -> hb_body[0]);          /* One object behind p  */
229     last_object = (word *)((char *)h + HBLKSIZE);
230     last_object -= sz;
231                             /* Last place for last object to start */
232
233   /* make a list of all objects in *h with head as last object */
234     while (p <= last_object) {
235       /* current object's link points to last object */
236         obj_link(p) = (ptr_t)prev;
237         prev = p;
238         p += sz;
239     }
240     p -= sz;                    /* p now points to last object */
241
242   /*
243    * put p (which is now head of list of objects in *h) as first
244    * pointer in the appropriate free list for this size.
245    */
246       obj_link(h -> hb_body) = GC_obj_kinds[kind].ok_freelist[sz];
247       GC_obj_kinds[kind].ok_freelist[sz] = ((ptr_t)p);
248 }
249