]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame_incremental - bfd/obstack.c
Initial revision
[thirdparty/binutils-gdb.git] / bfd / obstack.c
... / ...
CommitLineData
1/* obstack.c - subroutines used implicitly by object stack macros
2 Copyright (C) 1988 Free Software Foundation, Inc.
3
4This program is free software; you can redistribute it and/or modify it
5under the terms of the GNU General Public License as published by the
6Free Software Foundation; either version 1, or (at your option) any
7later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program; if not, write to the Free Software
16Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
17#include <ansidecl.h>
18#include <sysdep.h>
19#include "obstack.h"
20
21
22/* Determine default alignment. */
23struct fooalign {char x; double d;};
24#define DEFAULT_ALIGNMENT ((char *)&((struct fooalign *) 0)->d - (char *)0)
25/* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT.
26 But in fact it might be less smart and round addresses to as much as
27 DEFAULT_ROUNDING. So we prepare for it to do that. */
28union fooround {long x; double d;};
29#define DEFAULT_ROUNDING (sizeof (union fooround))
30
31/* When we copy a long block of data, this is the unit to do it with.
32 On some machines, copying successive ints does not work;
33 in such a case, redefine COPYING_UNIT to `long' (if that works)
34 or `char' as a last resort. */
35#ifndef COPYING_UNIT
36#define COPYING_UNIT int
37#endif
38
39/* The non-GNU-C macros copy the obstack into this global variable
40 to avoid multiple evaluation. */
41
42struct obstack *_obstack;
43\f
44/* Initialize an obstack H for use. Specify chunk size SIZE (0 means default).
45 Objects start on multiples of ALIGNMENT (0 means use default).
46 CHUNKFUN is the function to use to allocate chunks,
47 and FREEFUN the function to free them. */
48
49void DEFUN(_obstack_begin,(h, size, alignment, chunkfun, freefun),
50 struct obstack *h AND
51 int size AND
52 int alignment AND
53 PTR (*chunkfun) () AND
54 void (*freefun) ())
55{
56 register struct _obstack_chunk* chunk; /* points to new chunk */
57
58 if (alignment == 0)
59 alignment = DEFAULT_ALIGNMENT;
60 if (size == 0)
61 /* Default size is what GNU malloc can fit in a 4096-byte block. */
62 {
63 /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
64 Use the values for range checking, because if range checking is off,
65 the extra bytes won't be missed terribly, but if range checking is on
66 and we used a larger request, a whole extra 4096 bytes would be
67 allocated.
68
69 These number are irrelevant to the new GNU malloc. I suspect it is
70 less sensitive to the size of the request. */
71 int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
72 + 4 + DEFAULT_ROUNDING - 1)
73 & ~(DEFAULT_ROUNDING - 1));
74 size = 4096 - extra;
75 }
76
77 h->chunkfun = chunkfun;
78 h->freefun = freefun;
79 h->chunk_size = size;
80 h->alignment_mask = alignment - 1;
81
82 chunk = h->chunk = (struct _obstack_chunk *)(*h->chunkfun) (h->chunk_size);
83 h->next_free = h->object_base = chunk->contents;
84 h->chunk_limit = chunk->limit
85 = (char *) chunk + h->chunk_size;
86 chunk->prev = 0;
87}
88
89/* Allocate a new current chunk for the obstack *H
90 on the assumption that LENGTH bytes need to be added
91 to the current object, or a new object of length LENGTH allocated.
92 Copies any partial object from the end of the old chunk
93 to the beginning of the new one.
94
95 The function must be "int" so it can be used in non-ANSI C
96 compilers in a : expression. */
97
98int
99DEFUN(_obstack_newchunk,(h, length),
100 struct obstack *h AND
101 int length)
102{
103 register struct _obstack_chunk* old_chunk = h->chunk;
104 register struct _obstack_chunk* new_chunk;
105 register long new_size;
106 register int obj_size = h->next_free - h->object_base;
107 register int i;
108 int already;
109
110 /* Compute size for new chunk. */
111 new_size = (obj_size + length) + (obj_size >> 3) + 100;
112 if (new_size < h->chunk_size)
113 new_size = h->chunk_size;
114
115 /* Allocate and initialize the new chunk. */
116 new_chunk = h->chunk = (struct _obstack_chunk *)(*h->chunkfun) (new_size);
117 new_chunk->prev = old_chunk;
118 new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
119
120 /* Move the existing object to the new chunk.
121 Word at a time is fast and is safe if the object
122 is sufficiently aligned. */
123 if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT)
124 {
125 for (i = obj_size / sizeof (COPYING_UNIT) - 1;
126 i >= 0; i--)
127 ((COPYING_UNIT *)new_chunk->contents)[i]
128 = ((COPYING_UNIT *)h->object_base)[i];
129 /* We used to copy the odd few remaining bytes as one extra COPYING_UNIT,
130 but that can cross a page boundary on a machine
131 which does not do strict alignment for COPYING_UNITS. */
132 already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT);
133 }
134 else
135 already = 0;
136 /* Copy remaining bytes one by one. */
137 for (i = already; i < obj_size; i++)
138 new_chunk->contents[i] = h->object_base[i];
139
140 h->object_base = new_chunk->contents;
141 h->next_free = h->object_base + obj_size;
142return 0;
143}
144
145/* Return nonzero if object OBJ has been allocated from obstack H.
146 This is here for debugging.
147 If you use it in a program, you are probably losing. */
148
149int
150DEFUN(_obstack_allocated_p, (h, obj),
151 struct obstack *h AND
152 PTR obj)
153{
154 register struct _obstack_chunk* lp; /* below addr of any objects in this chunk */
155 register struct _obstack_chunk* plp; /* point to previous chunk if any */
156
157 lp = (h)->chunk;
158 while (lp != 0 && ((PTR)lp > obj || (PTR)(lp)->limit < obj))
159 {
160 plp = lp -> prev;
161 lp = plp;
162 }
163 return lp != 0;
164}
165
166/* Free objects in obstack H, including OBJ and everything allocate
167 more recently than OBJ. If OBJ is zero, free everything in H. */
168
169#ifdef __STDC__
170#undef obstack_free
171void
172obstack_free (struct obstack *h, PTR obj)
173#else
174int
175_obstack_free (h, obj)
176 struct obstack *h;
177 PTR obj;
178#endif
179{
180 register struct _obstack_chunk* lp; /* below addr of any objects in this chunk */
181 register struct _obstack_chunk* plp; /* point to previous chunk if any */
182
183 lp = (h)->chunk;
184 /* We use >= because there cannot be an object at the beginning of a chunk.
185 But there can be an empty object at that address
186 at the end of another chunk. */
187 while (lp != 0 && ((PTR)lp >= obj || (PTR)(lp)->limit < obj))
188 {
189 plp = lp -> prev;
190 (*h->freefun) ((PTR) lp);
191 lp = plp;
192 }
193 if (lp)
194 {
195 (h)->object_base = (h)->next_free = (char *)(obj);
196 (h)->chunk_limit = lp->limit;
197 (h)->chunk = lp;
198 }
199 else if (obj != 0)
200 /* obj is not in any of the chunks! */
201 abort ();
202}
203
204/* Let same .o link with output of gcc and other compilers. */
205
206#ifdef __STDC__
207int
208_obstack_free (h, obj)
209 struct obstack *h;
210 PTR obj;
211{
212 obstack_free (h, obj);
213 return 0;
214}
215#endif
216\f
217/* #if 0 */
218/* These are now turned off because the applications do not use it
219 and it uses bcopy via obstack_grow, which causes trouble on sysV. */
220
221/* Now define the functional versions of the obstack macros.
222 Define them to simply use the corresponding macros to do the job. */
223
224#ifdef __STDC__
225/* These function definitions do not work with non-ANSI preprocessors;
226 they won't pass through the macro names in parentheses. */
227
228/* The function names appear in parentheses in order to prevent
229 the macro-definitions of the names from being expanded there. */
230
231PTR (obstack_base) (obstack)
232 struct obstack *obstack;
233{
234 return obstack_base (obstack);
235}
236
237PTR (obstack_next_free) (obstack)
238 struct obstack *obstack;
239{
240 return obstack_next_free (obstack);
241}
242
243int (obstack_object_size) (obstack)
244 struct obstack *obstack;
245{
246 return obstack_object_size (obstack);
247}
248
249int (obstack_room) (obstack)
250 struct obstack *obstack;
251{
252 return obstack_room (obstack);
253}
254
255void (obstack_grow) (obstack, ptr, length)
256 struct obstack *obstack;
257 PTR ptr;
258 int length;
259{
260(void) obstack_grow (obstack, ptr, length);
261}
262
263void (obstack_grow0) (obstack, ptr, length)
264 struct obstack *obstack;
265 PTR ptr;
266 int length;
267{
268(void) obstack_grow0 (obstack, ptr, length);
269}
270
271void (obstack_1grow) (obstack, character)
272 struct obstack *obstack;
273 int character;
274{
275(void) obstack_1grow (obstack, character);
276}
277
278void (obstack_blank) (obstack, length)
279 struct obstack *obstack;
280 int length;
281{
282(void) obstack_blank (obstack, length);
283}
284
285void (obstack_1grow_fast) (obstack, character)
286 struct obstack *obstack;
287 int character;
288{
289 obstack_1grow_fast (obstack, character);
290}
291
292void (obstack_blank_fast) (obstack, length)
293 struct obstack *obstack;
294 int length;
295{
296 obstack_blank_fast (obstack, length);
297}
298
299PTR (obstack_finish) (obstack)
300 struct obstack *obstack;
301{
302 return obstack_finish (obstack);
303}
304
305PTR (obstack_alloc) (obstack, length)
306 struct obstack *obstack;
307 int length;
308{
309 return obstack_alloc (obstack, length);
310}
311
312PTR (obstack_copy) (obstack, ptr, length)
313 struct obstack *obstack;
314 PTR ptr;
315 int length;
316{
317 return obstack_copy (obstack, ptr, length);
318}
319
320PTR (obstack_copy0) (obstack, ptr, length)
321 struct obstack *obstack;
322 PTR ptr;
323 int length;
324{
325 return obstack_copy0 (obstack, ptr, length);
326}
327
328#endif /* __STDC__ */
329
330