]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - bfd/obstack.c
Initial revision
[thirdparty/binutils-gdb.git] / bfd / obstack.c
CommitLineData
87f86b4e
DHW
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. */
03466f17
SC
17#include <ansidecl.h>
18#include <sysdep.h>
87f86b4e
DHW
19#include "obstack.h"
20
87f86b4e
DHW
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
03466f17
SC
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) ())
87f86b4e
DHW
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
03466f17
SC
99DEFUN(_obstack_newchunk,(h, length),
100 struct obstack *h AND
101 int length)
87f86b4e
DHW
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
03466f17
SC
150DEFUN(_obstack_allocated_p, (h, obj),
151 struct obstack *h AND
152 PTR obj)
87f86b4e 153{
03466f17 154 register struct _obstack_chunk* lp; /* below addr of any objects in this chunk */
87f86b4e
DHW
155 register struct _obstack_chunk* plp; /* point to previous chunk if any */
156
157 lp = (h)->chunk;
03466f17
SC
158 while (lp != 0 && ((PTR)lp > obj || (PTR)(lp)->limit < obj))
159 {
160 plp = lp -> prev;
161 lp = plp;
162 }
87f86b4e
DHW
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
03466f17 172obstack_free (struct obstack *h, PTR obj)
87f86b4e
DHW
173#else
174int
175_obstack_free (h, obj)
176 struct obstack *h;
03466f17 177 PTR obj;
87f86b4e
DHW
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. */
03466f17 187 while (lp != 0 && ((PTR)lp >= obj || (PTR)(lp)->limit < obj))
87f86b4e
DHW
188 {
189 plp = lp -> prev;
03466f17 190 (*h->freefun) ((PTR) lp);
87f86b4e
DHW
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;
03466f17 210 PTR obj;
87f86b4e
DHW
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
03466f17 231PTR (obstack_base) (obstack)
87f86b4e
DHW
232 struct obstack *obstack;
233{
234 return obstack_base (obstack);
235}
236
03466f17 237PTR (obstack_next_free) (obstack)
87f86b4e
DHW
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
03466f17 255void (obstack_grow) (obstack, ptr, length)
87f86b4e 256 struct obstack *obstack;
03466f17 257 PTR ptr;
87f86b4e
DHW
258 int length;
259{
03466f17 260(void) obstack_grow (obstack, ptr, length);
87f86b4e
DHW
261}
262
03466f17 263void (obstack_grow0) (obstack, ptr, length)
87f86b4e 264 struct obstack *obstack;
03466f17 265 PTR ptr;
87f86b4e
DHW
266 int length;
267{
03466f17 268(void) obstack_grow0 (obstack, ptr, length);
87f86b4e
DHW
269}
270
271void (obstack_1grow) (obstack, character)
272 struct obstack *obstack;
273 int character;
274{
03466f17 275(void) obstack_1grow (obstack, character);
87f86b4e
DHW
276}
277
278void (obstack_blank) (obstack, length)
279 struct obstack *obstack;
280 int length;
281{
03466f17 282(void) obstack_blank (obstack, length);
87f86b4e
DHW
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
03466f17 299PTR (obstack_finish) (obstack)
87f86b4e
DHW
300 struct obstack *obstack;
301{
302 return obstack_finish (obstack);
303}
304
03466f17 305PTR (obstack_alloc) (obstack, length)
87f86b4e
DHW
306 struct obstack *obstack;
307 int length;
308{
309 return obstack_alloc (obstack, length);
310}
311
03466f17 312PTR (obstack_copy) (obstack, ptr, length)
87f86b4e 313 struct obstack *obstack;
03466f17 314 PTR ptr;
87f86b4e
DHW
315 int length;
316{
03466f17 317 return obstack_copy (obstack, ptr, length);
87f86b4e
DHW
318}
319
03466f17 320PTR (obstack_copy0) (obstack, ptr, length)
87f86b4e 321 struct obstack *obstack;
03466f17 322 PTR ptr;
87f86b4e
DHW
323 int length;
324{
03466f17 325 return obstack_copy0 (obstack, ptr, length);
87f86b4e
DHW
326}
327
328#endif /* __STDC__ */
329
330