xref: /openbsd-src/gnu/lib/libiberty/include/objalloc.h (revision 483f9b85c592a4b6529cdf768372384b6072c25a)
1f7bfebe6Sespie /* objalloc.h -- routines to allocate memory for objects
2*483f9b85Sbluhm    Copyright 1997-2012 Free Software Foundation, Inc.
3f7bfebe6Sespie    Written by Ian Lance Taylor, Cygnus Solutions.
4f7bfebe6Sespie 
5f7bfebe6Sespie This program is free software; you can redistribute it and/or modify it
6f7bfebe6Sespie under the terms of the GNU General Public License as published by the
7f7bfebe6Sespie Free Software Foundation; either version 2, or (at your option) any
8f7bfebe6Sespie later version.
9f7bfebe6Sespie 
10f7bfebe6Sespie This program is distributed in the hope that it will be useful,
11f7bfebe6Sespie but WITHOUT ANY WARRANTY; without even the implied warranty of
12f7bfebe6Sespie MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13f7bfebe6Sespie GNU General Public License for more details.
14f7bfebe6Sespie 
15f7bfebe6Sespie You should have received a copy of the GNU General Public License
16f7bfebe6Sespie along with this program; if not, write to the Free Software
1720fce977Smiod Foundation, 51 Franklin Street - Fifth Floor,
1820fce977Smiod Boston, MA 02110-1301, USA.  */
19f7bfebe6Sespie 
20f7bfebe6Sespie #ifndef OBJALLOC_H
21f7bfebe6Sespie #define OBJALLOC_H
22f7bfebe6Sespie 
23f7bfebe6Sespie #include "ansidecl.h"
24f7bfebe6Sespie 
25f7bfebe6Sespie /* These routines allocate space for an object.  The assumption is
26f7bfebe6Sespie    that the object will want to allocate space as it goes along, but
27f7bfebe6Sespie    will never want to free any particular block.  There is a function
28f7bfebe6Sespie    to free a block, which also frees all more recently allocated
29f7bfebe6Sespie    blocks.  There is also a function to free all the allocated space.
30f7bfebe6Sespie 
31f7bfebe6Sespie    This is essentially a specialization of obstacks.  The main
32f7bfebe6Sespie    difference is that a block may not be allocated a bit at a time.
33f7bfebe6Sespie    Another difference is that these routines are always built on top
34f7bfebe6Sespie    of malloc, and always pass an malloc failure back to the caller,
35f7bfebe6Sespie    unlike more recent versions of obstacks.  */
36f7bfebe6Sespie 
37f7bfebe6Sespie /* This is what an objalloc structure looks like.  Callers should not
38f7bfebe6Sespie    refer to these fields, nor should they allocate these structure
39f7bfebe6Sespie    themselves.  Instead, they should only create them via
40f7bfebe6Sespie    objalloc_init, and only access them via the functions and macros
41f7bfebe6Sespie    listed below.  The structure is only defined here so that we can
42f7bfebe6Sespie    access it via macros.  */
43f7bfebe6Sespie 
44f7bfebe6Sespie struct objalloc
45f7bfebe6Sespie {
46f7bfebe6Sespie   char *current_ptr;
47f7bfebe6Sespie   unsigned int current_space;
4820fce977Smiod   void *chunks;
49f7bfebe6Sespie };
50f7bfebe6Sespie 
51f7bfebe6Sespie /* Work out the required alignment.  */
52f7bfebe6Sespie 
53f7bfebe6Sespie struct objalloc_align { char x; double d; };
54f7bfebe6Sespie 
55f7bfebe6Sespie #if defined (__STDC__) && __STDC__
56f7bfebe6Sespie #ifndef offsetof
57f7bfebe6Sespie #include <stddef.h>
58f7bfebe6Sespie #endif
59f7bfebe6Sespie #endif
609588ddcfSespie #ifndef offsetof
619588ddcfSespie #define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
629588ddcfSespie #endif
639588ddcfSespie #define OBJALLOC_ALIGN offsetof (struct objalloc_align, d)
64f7bfebe6Sespie 
65f7bfebe6Sespie /* Create an objalloc structure.  Returns NULL if malloc fails.  */
66f7bfebe6Sespie 
6720fce977Smiod extern struct objalloc *objalloc_create (void);
68f7bfebe6Sespie 
69f7bfebe6Sespie /* Allocate space from an objalloc structure.  Returns NULL if malloc
70f7bfebe6Sespie    fails.  */
71f7bfebe6Sespie 
7220fce977Smiod extern void *_objalloc_alloc (struct objalloc *, unsigned long);
73f7bfebe6Sespie 
74f7bfebe6Sespie /* The macro version of objalloc_alloc.  We only define this if using
75f7bfebe6Sespie    gcc, because otherwise we would have to evaluate the arguments
76f7bfebe6Sespie    multiple times, or use a temporary field as obstack.h does.  */
77f7bfebe6Sespie 
78f7bfebe6Sespie #if defined (__GNUC__) && defined (__STDC__) && __STDC__
79f7bfebe6Sespie 
80f7bfebe6Sespie /* NextStep 2.0 cc is really gcc 1.93 but it defines __GNUC__ = 2 and
81f7bfebe6Sespie    does not implement __extension__.  But that compiler doesn't define
82f7bfebe6Sespie    __GNUC_MINOR__.  */
83f7bfebe6Sespie #if __GNUC__ < 2 || (__NeXT__ && !__GNUC_MINOR__)
84f7bfebe6Sespie #define __extension__
85f7bfebe6Sespie #endif
86f7bfebe6Sespie 
87f7bfebe6Sespie #define objalloc_alloc(o, l)						\
88f7bfebe6Sespie   __extension__								\
89f7bfebe6Sespie   ({ struct objalloc *__o = (o);					\
90f7bfebe6Sespie      unsigned long __len = (l);						\
91f7bfebe6Sespie      if (__len == 0)							\
92f7bfebe6Sespie        __len = 1;							\
93f7bfebe6Sespie      __len = (__len + OBJALLOC_ALIGN - 1) &~ (OBJALLOC_ALIGN - 1);	\
94*483f9b85Sbluhm      (__len != 0 && __len <= __o->current_space			\
95f7bfebe6Sespie       ? (__o->current_ptr += __len,					\
96f7bfebe6Sespie 	 __o->current_space -= __len,					\
9720fce977Smiod 	 (void *) (__o->current_ptr - __len))				\
98f7bfebe6Sespie       : _objalloc_alloc (__o, __len)); })
99f7bfebe6Sespie 
100f7bfebe6Sespie #else /* ! __GNUC__ */
101f7bfebe6Sespie 
102f7bfebe6Sespie #define objalloc_alloc(o, l) _objalloc_alloc ((o), (l))
103f7bfebe6Sespie 
104f7bfebe6Sespie #endif /* ! __GNUC__ */
105f7bfebe6Sespie 
106f7bfebe6Sespie /* Free an entire objalloc structure.  */
107f7bfebe6Sespie 
10820fce977Smiod extern void objalloc_free (struct objalloc *);
109f7bfebe6Sespie 
110f7bfebe6Sespie /* Free a block allocated by objalloc_alloc.  This also frees all more
111f7bfebe6Sespie    recently allocated blocks.  */
112f7bfebe6Sespie 
11320fce977Smiod extern void objalloc_free_block (struct objalloc *, void *);
114f7bfebe6Sespie 
115f7bfebe6Sespie #endif /* OBJALLOC_H */
116