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