xref: /netbsd-src/external/gpl3/binutils/dist/include/objalloc.h (revision dd7241df2fae9da4ea2bd20a68f001fa86ecf909)
12a6b7db3Sskrll /* objalloc.h -- routines to allocate memory for objects
2*dd7241dfSchristos    Copyright (C) 1997-2024 Free Software Foundation, Inc.
32a6b7db3Sskrll    Written by Ian Lance Taylor, Cygnus Solutions.
42a6b7db3Sskrll 
52a6b7db3Sskrll This program is free software; you can redistribute it and/or modify it
62a6b7db3Sskrll under the terms of the GNU General Public License as published by the
72a6b7db3Sskrll Free Software Foundation; either version 2, or (at your option) any
82a6b7db3Sskrll later version.
92a6b7db3Sskrll 
102a6b7db3Sskrll This program is distributed in the hope that it will be useful,
112a6b7db3Sskrll but WITHOUT ANY WARRANTY; without even the implied warranty of
122a6b7db3Sskrll MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
132a6b7db3Sskrll GNU General Public License for more details.
142a6b7db3Sskrll 
152a6b7db3Sskrll You should have received a copy of the GNU General Public License
162a6b7db3Sskrll along with this program; if not, write to the Free Software
172a6b7db3Sskrll Foundation, 51 Franklin Street - Fifth Floor,
182a6b7db3Sskrll Boston, MA 02110-1301, USA.  */
192a6b7db3Sskrll 
202a6b7db3Sskrll #ifndef OBJALLOC_H
212a6b7db3Sskrll #define OBJALLOC_H
222a6b7db3Sskrll 
232a6b7db3Sskrll #include "ansidecl.h"
242a6b7db3Sskrll 
252a6b7db3Sskrll /* These routines allocate space for an object.  The assumption is
262a6b7db3Sskrll    that the object will want to allocate space as it goes along, but
272a6b7db3Sskrll    will never want to free any particular block.  There is a function
282a6b7db3Sskrll    to free a block, which also frees all more recently allocated
292a6b7db3Sskrll    blocks.  There is also a function to free all the allocated space.
302a6b7db3Sskrll 
312a6b7db3Sskrll    This is essentially a specialization of obstacks.  The main
322a6b7db3Sskrll    difference is that a block may not be allocated a bit at a time.
332a6b7db3Sskrll    Another difference is that these routines are always built on top
342a6b7db3Sskrll    of malloc, and always pass an malloc failure back to the caller,
352a6b7db3Sskrll    unlike more recent versions of obstacks.  */
362a6b7db3Sskrll 
372a6b7db3Sskrll /* This is what an objalloc structure looks like.  Callers should not
382a6b7db3Sskrll    refer to these fields, nor should they allocate these structure
392a6b7db3Sskrll    themselves.  Instead, they should only create them via
402a6b7db3Sskrll    objalloc_init, and only access them via the functions and macros
412a6b7db3Sskrll    listed below.  The structure is only defined here so that we can
422a6b7db3Sskrll    access it via macros.  */
432a6b7db3Sskrll 
442a6b7db3Sskrll struct objalloc
452a6b7db3Sskrll {
462a6b7db3Sskrll   char *current_ptr;
472a6b7db3Sskrll   unsigned int current_space;
482a6b7db3Sskrll   void *chunks;
492a6b7db3Sskrll };
502a6b7db3Sskrll 
512a6b7db3Sskrll /* Work out the required alignment.  */
522a6b7db3Sskrll 
532a6b7db3Sskrll struct objalloc_align { char x; double d; };
542a6b7db3Sskrll 
552a6b7db3Sskrll #if defined (__STDC__) && __STDC__
562a6b7db3Sskrll #ifndef offsetof
572a6b7db3Sskrll #include <stddef.h>
582a6b7db3Sskrll #endif
592a6b7db3Sskrll #endif
602a6b7db3Sskrll #ifndef offsetof
612a6b7db3Sskrll #define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
622a6b7db3Sskrll #endif
632a6b7db3Sskrll #define OBJALLOC_ALIGN offsetof (struct objalloc_align, d)
642a6b7db3Sskrll 
652a6b7db3Sskrll /* Create an objalloc structure.  Returns NULL if malloc fails.  */
662a6b7db3Sskrll 
672a6b7db3Sskrll extern struct objalloc *objalloc_create (void);
682a6b7db3Sskrll 
692a6b7db3Sskrll /* Allocate space from an objalloc structure.  Returns NULL if malloc
702a6b7db3Sskrll    fails.  */
712a6b7db3Sskrll 
722a6b7db3Sskrll extern void *_objalloc_alloc (struct objalloc *, unsigned long);
732a6b7db3Sskrll 
742a6b7db3Sskrll /* The macro version of objalloc_alloc.  We only define this if using
752a6b7db3Sskrll    gcc, because otherwise we would have to evaluate the arguments
762a6b7db3Sskrll    multiple times, or use a temporary field as obstack.h does.  */
772a6b7db3Sskrll 
782a6b7db3Sskrll #if defined (__GNUC__) && defined (__STDC__) && __STDC__
792a6b7db3Sskrll 
802a6b7db3Sskrll /* NextStep 2.0 cc is really gcc 1.93 but it defines __GNUC__ = 2 and
812a6b7db3Sskrll    does not implement __extension__.  But that compiler doesn't define
822a6b7db3Sskrll    __GNUC_MINOR__.  */
832a6b7db3Sskrll #if __GNUC__ < 2 || (__NeXT__ && !__GNUC_MINOR__)
842a6b7db3Sskrll #define __extension__
852a6b7db3Sskrll #endif
862a6b7db3Sskrll 
872a6b7db3Sskrll #define objalloc_alloc(o, l)						\
882a6b7db3Sskrll   __extension__								\
892a6b7db3Sskrll   ({ struct objalloc *__o = (o);					\
902a6b7db3Sskrll      unsigned long __len = (l);						\
912a6b7db3Sskrll      if (__len == 0)							\
922a6b7db3Sskrll        __len = 1;							\
932a6b7db3Sskrll      __len = (__len + OBJALLOC_ALIGN - 1) &~ (OBJALLOC_ALIGN - 1);	\
94d18545deSdrochner      (__len != 0 && __len <= __o->current_space				\
952a6b7db3Sskrll       ? (__o->current_ptr += __len,					\
962a6b7db3Sskrll 	 __o->current_space -= __len,					\
972a6b7db3Sskrll 	 (void *) (__o->current_ptr - __len))				\
982a6b7db3Sskrll       : _objalloc_alloc (__o, __len)); })
992a6b7db3Sskrll 
1002a6b7db3Sskrll #else /* ! __GNUC__ */
1012a6b7db3Sskrll 
1022a6b7db3Sskrll #define objalloc_alloc(o, l) _objalloc_alloc ((o), (l))
1032a6b7db3Sskrll 
1042a6b7db3Sskrll #endif /* ! __GNUC__ */
1052a6b7db3Sskrll 
1062a6b7db3Sskrll /* Free an entire objalloc structure.  */
1072a6b7db3Sskrll 
1082a6b7db3Sskrll extern void objalloc_free (struct objalloc *);
1092a6b7db3Sskrll 
1102a6b7db3Sskrll /* Free a block allocated by objalloc_alloc.  This also frees all more
1112a6b7db3Sskrll    recently allocated blocks.  */
1122a6b7db3Sskrll 
1132a6b7db3Sskrll extern void objalloc_free_block (struct objalloc *, void *);
1142a6b7db3Sskrll 
1152a6b7db3Sskrll #endif /* OBJALLOC_H */
116