|
|
1.1 root 1: /* obstack.c - subroutines used implicitly by object stack macros
2: Copyright (C) 1988 Free Software Foundation, Inc.
3:
4: This file is part of the libiberty library.
5: Libiberty is free software; you can redistribute it and/or
6: modify it under the terms of the GNU Library General Public
7: License as published by the Free Software Foundation; either
8: version 2 of the License, or (at your option) any later version.
9:
10: Libiberty is distributed in the hope that it will be useful,
11: but WITHOUT ANY WARRANTY; without even the implied warranty of
12: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13: Library General Public License for more details.
14:
15: You should have received a copy of the GNU Library General Public
16: License along with libiberty; see the file COPYING.LIB. If
17: not, write to the Free Software Foundation, Inc., 675 Mass Ave,
18: Cambridge, MA 02139, USA. */
19:
20: #include "obstack.h"
21:
22: #ifdef __STDC__
23: #define POINTER void *
24: #else
25: #define POINTER char *
26: #endif
27:
28: /* Determine default alignment. */
29: struct fooalign {char x; double d;};
30: #define DEFAULT_ALIGNMENT \
31: ((PTR_INT_TYPE) ((char *)&((struct fooalign *) 0)->d - (char *)0))
32: /* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT.
33: But in fact it might be less smart and round addresses to as much as
34: DEFAULT_ROUNDING. So we prepare for it to do that. */
35: union fooround {long x; double d;};
36: #define DEFAULT_ROUNDING (sizeof (union fooround))
37:
38: /* When we copy a long block of data, this is the unit to do it with.
39: On some machines, copying successive ints does not work;
40: in such a case, redefine COPYING_UNIT to `long' (if that works)
41: or `char' as a last resort. */
42: #ifndef COPYING_UNIT
43: #define COPYING_UNIT int
44: #endif
45:
46: /* The non-GNU-C macros copy the obstack into this global variable
47: to avoid multiple evaluation. */
48:
49: struct obstack *_obstack;
50:
51: /* Define a macro that either calls functions with the traditional malloc/free
52: calling interface, or calls functions with the mmalloc/mfree interface
53: (that adds an extra first argument), based on the state of use_extra_arg.
54: For free, do not use ?:, since some compilers, like the MIPS compilers,
55: do not allow (expr) ? void : void. */
56:
57: #define CALL_CHUNKFUN(h, size) \
58: (((h) -> use_extra_arg) \
59: ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
60: : (*(h)->chunkfun) ((size)))
61:
62: #define CALL_FREEFUN(h, old_chunk) \
63: do { \
64: if ((h) -> use_extra_arg) \
65: (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
66: else \
67: (*(h)->freefun) ((old_chunk)); \
68: } while (0)
69:
70:
71: /* Initialize an obstack H for use. Specify chunk size SIZE (0 means default).
72: Objects start on multiples of ALIGNMENT (0 means use default).
73: CHUNKFUN is the function to use to allocate chunks,
74: and FREEFUN the function to free them. */
75:
76: void
77: _obstack_begin (h, size, alignment, chunkfun, freefun)
78: struct obstack *h;
79: int size;
80: int alignment;
81: POINTER (*chunkfun) ();
82: void (*freefun) ();
83: {
84: register struct _obstack_chunk* chunk; /* points to new chunk */
85:
86: if (alignment == 0)
87: alignment = DEFAULT_ALIGNMENT;
88: if (size == 0)
89: /* Default size is what GNU malloc can fit in a 4096-byte block. */
90: {
91: /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
92: Use the values for range checking, because if range checking is off,
93: the extra bytes won't be missed terribly, but if range checking is on
94: and we used a larger request, a whole extra 4096 bytes would be
95: allocated.
96:
97: These number are irrelevant to the new GNU malloc. I suspect it is
98: less sensitive to the size of the request. */
99: int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
100: + 4 + DEFAULT_ROUNDING - 1)
101: & ~(DEFAULT_ROUNDING - 1));
102: size = 4096 - extra;
103: }
104:
105: h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun;
106: h->freefun = freefun;
107: h->chunk_size = size;
108: h->alignment_mask = alignment - 1;
109: h->use_extra_arg = 0;
110:
111: chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
112: h->next_free = h->object_base = chunk->contents;
113: h->chunk_limit = chunk->limit
114: = (char *) chunk + h->chunk_size;
115: chunk->prev = 0;
116: /* The initial chunk now contains no empty object. */
117: h->maybe_empty_object = 0;
118: }
119:
120: void
121: _obstack_begin_1 (h, size, alignment, chunkfun, freefun, arg)
122: struct obstack *h;
123: int size;
124: int alignment;
125: POINTER (*chunkfun) ();
126: void (*freefun) ();
127: POINTER arg;
128: {
129: register struct _obstack_chunk* chunk; /* points to new chunk */
130:
131: if (alignment == 0)
132: alignment = DEFAULT_ALIGNMENT;
133: if (size == 0)
134: /* Default size is what GNU malloc can fit in a 4096-byte block. */
135: {
136: /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
137: Use the values for range checking, because if range checking is off,
138: the extra bytes won't be missed terribly, but if range checking is on
139: and we used a larger request, a whole extra 4096 bytes would be
140: allocated.
141:
142: These number are irrelevant to the new GNU malloc. I suspect it is
143: less sensitive to the size of the request. */
144: int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
145: + 4 + DEFAULT_ROUNDING - 1)
146: & ~(DEFAULT_ROUNDING - 1));
147: size = 4096 - extra;
148: }
149:
150: h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun;
151: h->freefun = freefun;
152: h->chunk_size = size;
153: h->alignment_mask = alignment - 1;
154: h->extra_arg = arg;
155: h->use_extra_arg = 1;
156:
157: chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
158: h->next_free = h->object_base = chunk->contents;
159: h->chunk_limit = chunk->limit
160: = (char *) chunk + h->chunk_size;
161: chunk->prev = 0;
162: /* The initial chunk now contains no empty object. */
163: h->maybe_empty_object = 0;
164: }
165:
166: /* Allocate a new current chunk for the obstack *H
167: on the assumption that LENGTH bytes need to be added
168: to the current object, or a new object of length LENGTH allocated.
169: Copies any partial object from the end of the old chunk
170: to the beginning of the new one. */
171:
172: void
173: _obstack_newchunk (h, length)
174: struct obstack *h;
175: int length;
176: {
177: register struct _obstack_chunk* old_chunk = h->chunk;
178: register struct _obstack_chunk* new_chunk;
179: register long new_size;
180: register int obj_size = h->next_free - h->object_base;
181: register int i;
182: int already;
183:
184: /* Compute size for new chunk. */
185: new_size = (obj_size + length) + (obj_size >> 3) + 100;
186: if (new_size < h->chunk_size)
187: new_size = h->chunk_size;
188:
189: /* Allocate and initialize the new chunk. */
190: new_chunk = h->chunk = CALL_CHUNKFUN (h, new_size);
191: new_chunk->prev = old_chunk;
192: new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
193:
194: /* Move the existing object to the new chunk.
195: Word at a time is fast and is safe if the object
196: is sufficiently aligned. */
197: if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT)
198: {
199: for (i = obj_size / sizeof (COPYING_UNIT) - 1;
200: i >= 0; i--)
201: ((COPYING_UNIT *)new_chunk->contents)[i]
202: = ((COPYING_UNIT *)h->object_base)[i];
203: /* We used to copy the odd few remaining bytes as one extra COPYING_UNIT,
204: but that can cross a page boundary on a machine
205: which does not do strict alignment for COPYING_UNITS. */
206: already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT);
207: }
208: else
209: already = 0;
210: /* Copy remaining bytes one by one. */
211: for (i = already; i < obj_size; i++)
212: new_chunk->contents[i] = h->object_base[i];
213:
214: /* If the object just copied was the only data in OLD_CHUNK,
215: free that chunk and remove it from the chain.
216: But not if that chunk might contain an empty object. */
217: if (h->object_base == old_chunk->contents && ! h->maybe_empty_object)
218: {
219: new_chunk->prev = old_chunk->prev;
220: CALL_FREEFUN (h, old_chunk);
221: }
222:
223: h->object_base = new_chunk->contents;
224: h->next_free = h->object_base + obj_size;
225: /* The new chunk certainly contains no empty object yet. */
226: h->maybe_empty_object = 0;
227: }
228:
229: /* Return nonzero if object OBJ has been allocated from obstack H.
230: This is here for debugging.
231: If you use it in a program, you are probably losing. */
232:
233: int
234: _obstack_allocated_p (h, obj)
235: struct obstack *h;
236: POINTER obj;
237: {
238: register struct _obstack_chunk* lp; /* below addr of any objects in this chunk */
239: register struct _obstack_chunk* plp; /* point to previous chunk if any */
240:
241: lp = (h)->chunk;
242: /* We use >= rather than > since the object cannot be exactly at
243: the beginning of the chunk but might be an empty object exactly
244: at the end of an adjacent chunk. */
245: while (lp != 0 && ((POINTER)lp >= obj || (POINTER)(lp)->limit < obj))
246: {
247: plp = lp->prev;
248: lp = plp;
249: }
250: return lp != 0;
251: }
252:
253: /* Free objects in obstack H, including OBJ and everything allocate
254: more recently than OBJ. If OBJ is zero, free everything in H. */
255:
256: #undef obstack_free
257:
258: /* This function has two names with identical definitions.
259: This is the first one, called from non-ANSI code. */
260:
261: void
262: _obstack_free (h, obj)
263: struct obstack *h;
264: POINTER obj;
265: {
266: register struct _obstack_chunk* lp; /* below addr of any objects in this chunk */
267: register struct _obstack_chunk* plp; /* point to previous chunk if any */
268:
269: lp = h->chunk;
270: /* We use >= because there cannot be an object at the beginning of a chunk.
271: But there can be an empty object at that address
272: at the end of another chunk. */
273: while (lp != 0 && ((POINTER)lp >= obj || (POINTER)(lp)->limit < obj))
274: {
275: plp = lp->prev;
276: CALL_FREEFUN (h, lp);
277: lp = plp;
278: /* If we switch chunks, we can't tell whether the new current
279: chunk contains an empty object, so assume that it may. */
280: h->maybe_empty_object = 1;
281: }
282: if (lp)
283: {
284: h->object_base = h->next_free = (char *)(obj);
285: h->chunk_limit = lp->limit;
286: h->chunk = lp;
287: }
288: else if (obj != 0)
289: /* obj is not in any of the chunks! */
290: abort ();
291: }
292:
293: /* This function is used from ANSI code. */
294:
295: void
296: obstack_free (h, obj)
297: struct obstack *h;
298: POINTER obj;
299: {
300: register struct _obstack_chunk* lp; /* below addr of any objects in this chunk */
301: register struct _obstack_chunk* plp; /* point to previous chunk if any */
302:
303: lp = h->chunk;
304: /* We use >= because there cannot be an object at the beginning of a chunk.
305: But there can be an empty object at that address
306: at the end of another chunk. */
307: while (lp != 0 && ((POINTER)lp >= obj || (POINTER)(lp)->limit < obj))
308: {
309: plp = lp->prev;
310: CALL_FREEFUN (h, lp);
311: lp = plp;
312: /* If we switch chunks, we can't tell whether the new current
313: chunk contains an empty object, so assume that it may. */
314: h->maybe_empty_object = 1;
315: }
316: if (lp)
317: {
318: h->object_base = h->next_free = (char *)(obj);
319: h->chunk_limit = lp->limit;
320: h->chunk = lp;
321: }
322: else if (obj != 0)
323: /* obj is not in any of the chunks! */
324: abort ();
325: }
326:
327: #if 0
328: /* These are now turned off because the applications do not use it
329: and it uses bcopy via obstack_grow, which causes trouble on sysV. */
330:
331: /* Now define the functional versions of the obstack macros.
332: Define them to simply use the corresponding macros to do the job. */
333:
334: #ifdef __STDC__
335: /* These function definitions do not work with non-ANSI preprocessors;
336: they won't pass through the macro names in parentheses. */
337:
338: /* The function names appear in parentheses in order to prevent
339: the macro-definitions of the names from being expanded there. */
340:
341: POINTER (obstack_base) (obstack)
342: struct obstack *obstack;
343: {
344: return obstack_base (obstack);
345: }
346:
347: POINTER (obstack_next_free) (obstack)
348: struct obstack *obstack;
349: {
350: return obstack_next_free (obstack);
351: }
352:
353: int (obstack_object_size) (obstack)
354: struct obstack *obstack;
355: {
356: return obstack_object_size (obstack);
357: }
358:
359: int (obstack_room) (obstack)
360: struct obstack *obstack;
361: {
362: return obstack_room (obstack);
363: }
364:
365: void (obstack_grow) (obstack, pointer, length)
366: struct obstack *obstack;
367: POINTER pointer;
368: int length;
369: {
370: obstack_grow (obstack, pointer, length);
371: }
372:
373: void (obstack_grow0) (obstack, pointer, length)
374: struct obstack *obstack;
375: POINTER pointer;
376: int length;
377: {
378: obstack_grow0 (obstack, pointer, length);
379: }
380:
381: void (obstack_1grow) (obstack, character)
382: struct obstack *obstack;
383: int character;
384: {
385: obstack_1grow (obstack, character);
386: }
387:
388: void (obstack_blank) (obstack, length)
389: struct obstack *obstack;
390: int length;
391: {
392: obstack_blank (obstack, length);
393: }
394:
395: void (obstack_1grow_fast) (obstack, character)
396: struct obstack *obstack;
397: int character;
398: {
399: obstack_1grow_fast (obstack, character);
400: }
401:
402: void (obstack_blank_fast) (obstack, length)
403: struct obstack *obstack;
404: int length;
405: {
406: obstack_blank_fast (obstack, length);
407: }
408:
409: POINTER (obstack_finish) (obstack)
410: struct obstack *obstack;
411: {
412: return obstack_finish (obstack);
413: }
414:
415: POINTER (obstack_alloc) (obstack, length)
416: struct obstack *obstack;
417: int length;
418: {
419: return obstack_alloc (obstack, length);
420: }
421:
422: POINTER (obstack_copy) (obstack, pointer, length)
423: struct obstack *obstack;
424: POINTER pointer;
425: int length;
426: {
427: return obstack_copy (obstack, pointer, length);
428: }
429:
430: POINTER (obstack_copy0) (obstack, pointer, length)
431: struct obstack *obstack;
432: POINTER pointer;
433: int length;
434: {
435: return obstack_copy0 (obstack, pointer, length);
436: }
437:
438: #endif /* __STDC__ */
439:
440: #endif /* 0 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.