Back to index

cell-binutils  2.17cvs20070401
objalloc.h
Go to the documentation of this file.
00001 /* objalloc.h -- routines to allocate memory for objects
00002    Copyright 1997, 2001 Free Software Foundation, Inc.
00003    Written by Ian Lance Taylor, Cygnus Solutions.
00004 
00005 This program is free software; you can redistribute it and/or modify it
00006 under the terms of the GNU General Public License as published by the
00007 Free Software Foundation; either version 2, or (at your option) any
00008 later version.
00009 
00010 This program is distributed in the hope that it will be useful,
00011 but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 GNU General Public License for more details.
00014 
00015 You should have received a copy of the GNU General Public License
00016 along with this program; if not, write to the Free Software
00017 Foundation, 51 Franklin Street - Fifth Floor,
00018 Boston, MA 02110-1301, USA.  */
00019 
00020 #ifndef OBJALLOC_H
00021 #define OBJALLOC_H
00022 
00023 #include "ansidecl.h"
00024 
00025 /* These routines allocate space for an object.  The assumption is
00026    that the object will want to allocate space as it goes along, but
00027    will never want to free any particular block.  There is a function
00028    to free a block, which also frees all more recently allocated
00029    blocks.  There is also a function to free all the allocated space.
00030 
00031    This is essentially a specialization of obstacks.  The main
00032    difference is that a block may not be allocated a bit at a time.
00033    Another difference is that these routines are always built on top
00034    of malloc, and always pass an malloc failure back to the caller,
00035    unlike more recent versions of obstacks.  */
00036 
00037 /* This is what an objalloc structure looks like.  Callers should not
00038    refer to these fields, nor should they allocate these structure
00039    themselves.  Instead, they should only create them via
00040    objalloc_init, and only access them via the functions and macros
00041    listed below.  The structure is only defined here so that we can
00042    access it via macros.  */
00043 
00044 struct objalloc
00045 {
00046   char *current_ptr;
00047   unsigned int current_space;
00048   void *chunks;
00049 };
00050 
00051 /* Work out the required alignment.  */
00052 
00053 struct objalloc_align { char x; double d; };
00054 
00055 #if defined (__STDC__) && __STDC__
00056 #ifndef offsetof
00057 #include <stddef.h>
00058 #endif
00059 #endif
00060 #ifndef offsetof
00061 #define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
00062 #endif
00063 #define OBJALLOC_ALIGN offsetof (struct objalloc_align, d)
00064 
00065 /* Create an objalloc structure.  Returns NULL if malloc fails.  */
00066 
00067 extern struct objalloc *objalloc_create (void);
00068 
00069 /* Allocate space from an objalloc structure.  Returns NULL if malloc
00070    fails.  */
00071 
00072 extern void *_objalloc_alloc (struct objalloc *, unsigned long);
00073 
00074 /* The macro version of objalloc_alloc.  We only define this if using
00075    gcc, because otherwise we would have to evaluate the arguments
00076    multiple times, or use a temporary field as obstack.h does.  */
00077 
00078 #if defined (__GNUC__) && defined (__STDC__) && __STDC__
00079 
00080 /* NextStep 2.0 cc is really gcc 1.93 but it defines __GNUC__ = 2 and
00081    does not implement __extension__.  But that compiler doesn't define
00082    __GNUC_MINOR__.  */
00083 #if __GNUC__ < 2 || (__NeXT__ && !__GNUC_MINOR__)
00084 #define __extension__
00085 #endif
00086 
00087 #define objalloc_alloc(o, l)                                          \
00088   __extension__                                                       \
00089   ({ struct objalloc *__o = (o);                               \
00090      unsigned long __len = (l);                                       \
00091      if (__len == 0)                                           \
00092        __len = 1;                                              \
00093      __len = (__len + OBJALLOC_ALIGN - 1) &~ (OBJALLOC_ALIGN - 1);    \
00094      (__len <= __o->current_space                              \
00095       ? (__o->current_ptr += __len,                                   \
00096         __o->current_space -= __len,                                  \
00097         (void *) (__o->current_ptr - __len))                          \
00098       : _objalloc_alloc (__o, __len)); })
00099 
00100 #else /* ! __GNUC__ */
00101 
00102 #define objalloc_alloc(o, l) _objalloc_alloc ((o), (l))
00103 
00104 #endif /* ! __GNUC__ */
00105 
00106 /* Free an entire objalloc structure.  */
00107 
00108 extern void objalloc_free (struct objalloc *);
00109 
00110 /* Free a block allocated by objalloc_alloc.  This also frees all more
00111    recently allocated blocks.  */
00112 
00113 extern void objalloc_free_block (struct objalloc *, void *);
00114 
00115 #endif /* OBJALLOC_H */