xref: /netbsd-src/external/gpl3/binutils.old/dist/include/objalloc.h (revision e992f068c547fd6e84b3f104dc2340adcc955732)
175fd0b74Schristos /* objalloc.h -- routines to allocate memory for objects
2*e992f068Schristos    Copyright (C) 1997-2022 Free Software Foundation, Inc.
375fd0b74Schristos    Written by Ian Lance Taylor, Cygnus Solutions.
475fd0b74Schristos 
575fd0b74Schristos This program is free software; you can redistribute it and/or modify it
675fd0b74Schristos under the terms of the GNU General Public License as published by the
775fd0b74Schristos Free Software Foundation; either version 2, or (at your option) any
875fd0b74Schristos later version.
975fd0b74Schristos 
1075fd0b74Schristos This program is distributed in the hope that it will be useful,
1175fd0b74Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of
1275fd0b74Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1375fd0b74Schristos GNU General Public License for more details.
1475fd0b74Schristos 
1575fd0b74Schristos You should have received a copy of the GNU General Public License
1675fd0b74Schristos along with this program; if not, write to the Free Software
1775fd0b74Schristos Foundation, 51 Franklin Street - Fifth Floor,
1875fd0b74Schristos Boston, MA 02110-1301, USA.  */
1975fd0b74Schristos 
2075fd0b74Schristos #ifndef OBJALLOC_H
2175fd0b74Schristos #define OBJALLOC_H
2275fd0b74Schristos 
2375fd0b74Schristos #include "ansidecl.h"
2475fd0b74Schristos 
2575fd0b74Schristos /* These routines allocate space for an object.  The assumption is
2675fd0b74Schristos    that the object will want to allocate space as it goes along, but
2775fd0b74Schristos    will never want to free any particular block.  There is a function
2875fd0b74Schristos    to free a block, which also frees all more recently allocated
2975fd0b74Schristos    blocks.  There is also a function to free all the allocated space.
3075fd0b74Schristos 
3175fd0b74Schristos    This is essentially a specialization of obstacks.  The main
3275fd0b74Schristos    difference is that a block may not be allocated a bit at a time.
3375fd0b74Schristos    Another difference is that these routines are always built on top
3475fd0b74Schristos    of malloc, and always pass an malloc failure back to the caller,
3575fd0b74Schristos    unlike more recent versions of obstacks.  */
3675fd0b74Schristos 
3775fd0b74Schristos /* This is what an objalloc structure looks like.  Callers should not
3875fd0b74Schristos    refer to these fields, nor should they allocate these structure
3975fd0b74Schristos    themselves.  Instead, they should only create them via
4075fd0b74Schristos    objalloc_init, and only access them via the functions and macros
4175fd0b74Schristos    listed below.  The structure is only defined here so that we can
4275fd0b74Schristos    access it via macros.  */
4375fd0b74Schristos 
4475fd0b74Schristos struct objalloc
4575fd0b74Schristos {
4675fd0b74Schristos   char *current_ptr;
4775fd0b74Schristos   unsigned int current_space;
4875fd0b74Schristos   void *chunks;
4975fd0b74Schristos };
5075fd0b74Schristos 
5175fd0b74Schristos /* Work out the required alignment.  */
5275fd0b74Schristos 
5375fd0b74Schristos struct objalloc_align { char x; double d; };
5475fd0b74Schristos 
5575fd0b74Schristos #if defined (__STDC__) && __STDC__
5675fd0b74Schristos #ifndef offsetof
5775fd0b74Schristos #include <stddef.h>
5875fd0b74Schristos #endif
5975fd0b74Schristos #endif
6075fd0b74Schristos #ifndef offsetof
6175fd0b74Schristos #define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
6275fd0b74Schristos #endif
6375fd0b74Schristos #define OBJALLOC_ALIGN offsetof (struct objalloc_align, d)
6475fd0b74Schristos 
6575fd0b74Schristos /* Create an objalloc structure.  Returns NULL if malloc fails.  */
6675fd0b74Schristos 
6775fd0b74Schristos extern struct objalloc *objalloc_create (void);
6875fd0b74Schristos 
6975fd0b74Schristos /* Allocate space from an objalloc structure.  Returns NULL if malloc
7075fd0b74Schristos    fails.  */
7175fd0b74Schristos 
7275fd0b74Schristos extern void *_objalloc_alloc (struct objalloc *, unsigned long);
7375fd0b74Schristos 
7475fd0b74Schristos /* The macro version of objalloc_alloc.  We only define this if using
7575fd0b74Schristos    gcc, because otherwise we would have to evaluate the arguments
7675fd0b74Schristos    multiple times, or use a temporary field as obstack.h does.  */
7775fd0b74Schristos 
7875fd0b74Schristos #if defined (__GNUC__) && defined (__STDC__) && __STDC__
7975fd0b74Schristos 
8075fd0b74Schristos /* NextStep 2.0 cc is really gcc 1.93 but it defines __GNUC__ = 2 and
8175fd0b74Schristos    does not implement __extension__.  But that compiler doesn't define
8275fd0b74Schristos    __GNUC_MINOR__.  */
8375fd0b74Schristos #if __GNUC__ < 2 || (__NeXT__ && !__GNUC_MINOR__)
8475fd0b74Schristos #define __extension__
8575fd0b74Schristos #endif
8675fd0b74Schristos 
8775fd0b74Schristos #define objalloc_alloc(o, l)						\
8875fd0b74Schristos   __extension__								\
8975fd0b74Schristos   ({ struct objalloc *__o = (o);					\
9075fd0b74Schristos      unsigned long __len = (l);						\
9175fd0b74Schristos      if (__len == 0)							\
9275fd0b74Schristos        __len = 1;							\
9375fd0b74Schristos      __len = (__len + OBJALLOC_ALIGN - 1) &~ (OBJALLOC_ALIGN - 1);	\
9475fd0b74Schristos      (__len != 0 && __len <= __o->current_space				\
9575fd0b74Schristos       ? (__o->current_ptr += __len,					\
9675fd0b74Schristos 	 __o->current_space -= __len,					\
9775fd0b74Schristos 	 (void *) (__o->current_ptr - __len))				\
9875fd0b74Schristos       : _objalloc_alloc (__o, __len)); })
9975fd0b74Schristos 
10075fd0b74Schristos #else /* ! __GNUC__ */
10175fd0b74Schristos 
10275fd0b74Schristos #define objalloc_alloc(o, l) _objalloc_alloc ((o), (l))
10375fd0b74Schristos 
10475fd0b74Schristos #endif /* ! __GNUC__ */
10575fd0b74Schristos 
10675fd0b74Schristos /* Free an entire objalloc structure.  */
10775fd0b74Schristos 
10875fd0b74Schristos extern void objalloc_free (struct objalloc *);
10975fd0b74Schristos 
11075fd0b74Schristos /* Free a block allocated by objalloc_alloc.  This also frees all more
11175fd0b74Schristos    recently allocated blocks.  */
11275fd0b74Schristos 
11375fd0b74Schristos extern void objalloc_free_block (struct objalloc *, void *);
11475fd0b74Schristos 
11575fd0b74Schristos #endif /* OBJALLOC_H */
116