This source file includes following definitions.
- call_chunkfun
- call_freefun
- _obstack_begin_worker
- _obstack_begin
- _obstack_begin_1
- _obstack_newchunk
- _obstack_allocated_p
- _obstack_free
- _obstack_memory_used
- print_and_abort
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 #ifdef _LIBC
20 # include <obstack.h>
21 #else
22 # include <config.h>
23 # include "obstack.h"
24 #endif
25
26
27
28
29
30
31
32
33
34
35
36
37
38 #if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1
39 # include <gnu-versions.h>
40 # if (_GNU_OBSTACK_INTERFACE_VERSION == _OBSTACK_INTERFACE_VERSION \
41 || (_GNU_OBSTACK_INTERFACE_VERSION == 1 \
42 && _OBSTACK_INTERFACE_VERSION == 2 \
43 && defined SIZEOF_INT && defined SIZEOF_SIZE_T \
44 && SIZEOF_INT == SIZEOF_SIZE_T))
45 # define _OBSTACK_ELIDE_CODE
46 # endif
47 #endif
48
49 #ifndef _OBSTACK_ELIDE_CODE
50
51
52
53 # if !defined __GNUC__ && !defined __alignof__
54 # include <alignof.h>
55 # define __alignof__(type) alignof_type (type)
56 # endif
57 # include <stdlib.h>
58 # include <stdint.h>
59
60 # ifndef MAX
61 # define MAX(a,b) ((a) > (b) ? (a) : (b))
62 # endif
63
64
65
66
67
68
69
70
71 #define DEFAULT_ALIGNMENT MAX (__alignof__ (long double), \
72 MAX (__alignof__ (uintmax_t), \
73 __alignof__ (void *)))
74 #define DEFAULT_ROUNDING MAX (sizeof (long double), \
75 MAX (sizeof (uintmax_t), \
76 sizeof (void *)))
77
78
79
80
81
82 static void *
83 call_chunkfun (struct obstack *h, size_t size)
84 {
85 if (h->use_extra_arg)
86 return h->chunkfun.extra (h->extra_arg, size);
87 else
88 return h->chunkfun.plain (size);
89 }
90
91 static void
92 call_freefun (struct obstack *h, void *old_chunk)
93 {
94 if (h->use_extra_arg)
95 h->freefun.extra (h->extra_arg, old_chunk);
96 else
97 h->freefun.plain (old_chunk);
98 }
99
100
101
102
103
104
105
106
107 static int
108 _obstack_begin_worker (struct obstack *h,
109 _OBSTACK_SIZE_T size, _OBSTACK_SIZE_T alignment)
110 {
111 struct _obstack_chunk *chunk;
112
113 if (alignment == 0)
114 alignment = DEFAULT_ALIGNMENT;
115 if (size == 0)
116
117 {
118
119
120
121
122
123
124
125
126 int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
127 + 4 + DEFAULT_ROUNDING - 1)
128 & ~(DEFAULT_ROUNDING - 1));
129 size = 4096 - extra;
130 }
131
132 h->chunk_size = size;
133 h->alignment_mask = alignment - 1;
134
135 chunk = h->chunk = call_chunkfun (h, h->chunk_size);
136 if (!chunk)
137 (*obstack_alloc_failed_handler) ();
138 h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents,
139 alignment - 1);
140 h->chunk_limit = chunk->limit = (char *) chunk + h->chunk_size;
141 chunk->prev = 0;
142
143 h->maybe_empty_object = 0;
144 h->alloc_failed = 0;
145 return 1;
146 }
147
148 int
149 _obstack_begin (struct obstack *h,
150 _OBSTACK_SIZE_T size, _OBSTACK_SIZE_T alignment,
151 void *(*chunkfun) (size_t),
152 void (*freefun) (void *))
153 {
154 h->chunkfun.plain = chunkfun;
155 h->freefun.plain = freefun;
156 h->use_extra_arg = 0;
157 return _obstack_begin_worker (h, size, alignment);
158 }
159
160 int
161 _obstack_begin_1 (struct obstack *h,
162 _OBSTACK_SIZE_T size, _OBSTACK_SIZE_T alignment,
163 void *(*chunkfun) (void *, size_t),
164 void (*freefun) (void *, void *),
165 void *arg)
166 {
167 h->chunkfun.extra = chunkfun;
168 h->freefun.extra = freefun;
169 h->extra_arg = arg;
170 h->use_extra_arg = 1;
171 return _obstack_begin_worker (h, size, alignment);
172 }
173
174
175
176
177
178
179
180 void
181 _obstack_newchunk (struct obstack *h, _OBSTACK_SIZE_T length)
182 {
183 struct _obstack_chunk *old_chunk = h->chunk;
184 struct _obstack_chunk *new_chunk = 0;
185 size_t obj_size = h->next_free - h->object_base;
186 char *object_base;
187
188
189 size_t sum1 = obj_size + length;
190 size_t sum2 = sum1 + h->alignment_mask;
191 size_t new_size = sum2 + (obj_size >> 3) + 100;
192 if (new_size < sum2)
193 new_size = sum2;
194 if (new_size < h->chunk_size)
195 new_size = h->chunk_size;
196
197
198 if (obj_size <= sum1 && sum1 <= sum2)
199 new_chunk = call_chunkfun (h, new_size);
200 if (!new_chunk)
201 (*obstack_alloc_failed_handler)();
202 h->chunk = new_chunk;
203 new_chunk->prev = old_chunk;
204 new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
205
206
207 object_base =
208 __PTR_ALIGN ((char *) new_chunk, new_chunk->contents, h->alignment_mask);
209
210
211 memcpy (object_base, h->object_base, obj_size);
212
213
214
215
216 if (!h->maybe_empty_object
217 && (h->object_base
218 == __PTR_ALIGN ((char *) old_chunk, old_chunk->contents,
219 h->alignment_mask)))
220 {
221 new_chunk->prev = old_chunk->prev;
222 call_freefun (h, old_chunk);
223 }
224
225 h->object_base = object_base;
226 h->next_free = h->object_base + obj_size;
227
228 h->maybe_empty_object = 0;
229 }
230
231
232
233
234
235
236
237 int _obstack_allocated_p (struct obstack *h, void *obj) __attribute_pure__;
238
239 int
240 _obstack_allocated_p (struct obstack *h, void *obj)
241 {
242 struct _obstack_chunk *lp;
243 struct _obstack_chunk *plp;
244
245 lp = (h)->chunk;
246
247
248
249 while (lp != 0 && ((void *) lp >= obj || (void *) (lp)->limit < obj))
250 {
251 plp = lp->prev;
252 lp = plp;
253 }
254 return lp != 0;
255 }
256
257
258
259
260 void
261 _obstack_free (struct obstack *h, void *obj)
262 {
263 struct _obstack_chunk *lp;
264 struct _obstack_chunk *plp;
265
266 lp = h->chunk;
267
268
269
270 while (lp != 0 && ((void *) lp >= obj || (void *) (lp)->limit < obj))
271 {
272 plp = lp->prev;
273 call_freefun (h, lp);
274 lp = plp;
275
276
277 h->maybe_empty_object = 1;
278 }
279 if (lp)
280 {
281 h->object_base = h->next_free = (char *) (obj);
282 h->chunk_limit = lp->limit;
283 h->chunk = lp;
284 }
285 else if (obj != 0)
286
287 abort ();
288 }
289
290 _OBSTACK_SIZE_T
291 _obstack_memory_used (struct obstack *h)
292 {
293 struct _obstack_chunk *lp;
294 _OBSTACK_SIZE_T nbytes = 0;
295
296 for (lp = h->chunk; lp != 0; lp = lp->prev)
297 {
298 nbytes += lp->limit - (char *) lp;
299 }
300 return nbytes;
301 }
302
303 # ifndef _OBSTACK_NO_ERROR_HANDLER
304
305 # include <stdio.h>
306
307
308 # ifdef _LIBC
309 int obstack_exit_failure = EXIT_FAILURE;
310 # else
311 # include "exitfail.h"
312 # define obstack_exit_failure exit_failure
313 # endif
314
315 # ifdef _LIBC
316 # include <libintl.h>
317 # else
318 # include "gettext.h"
319 # endif
320 # ifndef _
321 # define _(msgid) gettext (msgid)
322 # endif
323
324 # ifdef _LIBC
325 # include <libio/iolibio.h>
326 # endif
327
328 static __attribute_noreturn__ void
329 print_and_abort (void)
330 {
331
332
333
334
335
336 # ifdef _LIBC
337 (void) __fxprintf (NULL, "%s\n", _("memory exhausted"));
338 # else
339 fprintf (stderr, "%s\n", _("memory exhausted"));
340 # endif
341 exit (obstack_exit_failure);
342 }
343
344
345
346
347
348
349
350 __attribute_noreturn__ void (*obstack_alloc_failed_handler) (void)
351 = print_and_abort;
352 # endif
353 #endif