11debfc3dSmrg /* objalloc.h -- routines to allocate memory for objects 2*8feb0f0bSmrg Copyright (C) 1997-2020 Free Software Foundation, Inc. 31debfc3dSmrg Written by Ian Lance Taylor, Cygnus Solutions. 41debfc3dSmrg 51debfc3dSmrg This program is free software; you can redistribute it and/or modify it 61debfc3dSmrg under the terms of the GNU General Public License as published by the 71debfc3dSmrg Free Software Foundation; either version 2, or (at your option) any 81debfc3dSmrg later version. 91debfc3dSmrg 101debfc3dSmrg This program is distributed in the hope that it will be useful, 111debfc3dSmrg but WITHOUT ANY WARRANTY; without even the implied warranty of 121debfc3dSmrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 131debfc3dSmrg GNU General Public License for more details. 141debfc3dSmrg 151debfc3dSmrg You should have received a copy of the GNU General Public License 161debfc3dSmrg along with this program; if not, write to the Free Software 171debfc3dSmrg Foundation, 51 Franklin Street - Fifth Floor, 181debfc3dSmrg Boston, MA 02110-1301, USA. */ 191debfc3dSmrg 201debfc3dSmrg #ifndef OBJALLOC_H 211debfc3dSmrg #define OBJALLOC_H 221debfc3dSmrg 231debfc3dSmrg #include "ansidecl.h" 241debfc3dSmrg 251debfc3dSmrg /* These routines allocate space for an object. The assumption is 261debfc3dSmrg that the object will want to allocate space as it goes along, but 271debfc3dSmrg will never want to free any particular block. There is a function 281debfc3dSmrg to free a block, which also frees all more recently allocated 291debfc3dSmrg blocks. There is also a function to free all the allocated space. 301debfc3dSmrg 311debfc3dSmrg This is essentially a specialization of obstacks. The main 321debfc3dSmrg difference is that a block may not be allocated a bit at a time. 331debfc3dSmrg Another difference is that these routines are always built on top 341debfc3dSmrg of malloc, and always pass an malloc failure back to the caller, 351debfc3dSmrg unlike more recent versions of obstacks. */ 361debfc3dSmrg 371debfc3dSmrg /* This is what an objalloc structure looks like. Callers should not 381debfc3dSmrg refer to these fields, nor should they allocate these structure 391debfc3dSmrg themselves. Instead, they should only create them via 401debfc3dSmrg objalloc_init, and only access them via the functions and macros 411debfc3dSmrg listed below. The structure is only defined here so that we can 421debfc3dSmrg access it via macros. */ 431debfc3dSmrg 441debfc3dSmrg struct objalloc 451debfc3dSmrg { 461debfc3dSmrg char *current_ptr; 471debfc3dSmrg unsigned int current_space; 481debfc3dSmrg void *chunks; 491debfc3dSmrg }; 501debfc3dSmrg 511debfc3dSmrg /* Work out the required alignment. */ 521debfc3dSmrg 531debfc3dSmrg struct objalloc_align { char x; double d; }; 541debfc3dSmrg 551debfc3dSmrg #if defined (__STDC__) && __STDC__ 561debfc3dSmrg #ifndef offsetof 571debfc3dSmrg #include <stddef.h> 581debfc3dSmrg #endif 591debfc3dSmrg #endif 601debfc3dSmrg #ifndef offsetof 611debfc3dSmrg #define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER) 621debfc3dSmrg #endif 631debfc3dSmrg #define OBJALLOC_ALIGN offsetof (struct objalloc_align, d) 641debfc3dSmrg 651debfc3dSmrg /* Create an objalloc structure. Returns NULL if malloc fails. */ 661debfc3dSmrg 671debfc3dSmrg extern struct objalloc *objalloc_create (void); 681debfc3dSmrg 691debfc3dSmrg /* Allocate space from an objalloc structure. Returns NULL if malloc 701debfc3dSmrg fails. */ 711debfc3dSmrg 721debfc3dSmrg extern void *_objalloc_alloc (struct objalloc *, unsigned long); 731debfc3dSmrg 741debfc3dSmrg /* The macro version of objalloc_alloc. We only define this if using 751debfc3dSmrg gcc, because otherwise we would have to evaluate the arguments 761debfc3dSmrg multiple times, or use a temporary field as obstack.h does. */ 771debfc3dSmrg 781debfc3dSmrg #if defined (__GNUC__) && defined (__STDC__) && __STDC__ 791debfc3dSmrg 801debfc3dSmrg /* NextStep 2.0 cc is really gcc 1.93 but it defines __GNUC__ = 2 and 811debfc3dSmrg does not implement __extension__. But that compiler doesn't define 821debfc3dSmrg __GNUC_MINOR__. */ 831debfc3dSmrg #if __GNUC__ < 2 || (__NeXT__ && !__GNUC_MINOR__) 841debfc3dSmrg #define __extension__ 851debfc3dSmrg #endif 861debfc3dSmrg 871debfc3dSmrg #define objalloc_alloc(o, l) \ 881debfc3dSmrg __extension__ \ 891debfc3dSmrg ({ struct objalloc *__o = (o); \ 901debfc3dSmrg unsigned long __len = (l); \ 911debfc3dSmrg if (__len == 0) \ 921debfc3dSmrg __len = 1; \ 931debfc3dSmrg __len = (__len + OBJALLOC_ALIGN - 1) &~ (OBJALLOC_ALIGN - 1); \ 941debfc3dSmrg (__len != 0 && __len <= __o->current_space \ 951debfc3dSmrg ? (__o->current_ptr += __len, \ 961debfc3dSmrg __o->current_space -= __len, \ 971debfc3dSmrg (void *) (__o->current_ptr - __len)) \ 981debfc3dSmrg : _objalloc_alloc (__o, __len)); }) 991debfc3dSmrg 1001debfc3dSmrg #else /* ! __GNUC__ */ 1011debfc3dSmrg 1021debfc3dSmrg #define objalloc_alloc(o, l) _objalloc_alloc ((o), (l)) 1031debfc3dSmrg 1041debfc3dSmrg #endif /* ! __GNUC__ */ 1051debfc3dSmrg 1061debfc3dSmrg /* Free an entire objalloc structure. */ 1071debfc3dSmrg 1081debfc3dSmrg extern void objalloc_free (struct objalloc *); 1091debfc3dSmrg 1101debfc3dSmrg /* Free a block allocated by objalloc_alloc. This also frees all more 1111debfc3dSmrg recently allocated blocks. */ 1121debfc3dSmrg 1131debfc3dSmrg extern void objalloc_free_block (struct objalloc *, void *); 1141debfc3dSmrg 1151debfc3dSmrg #endif /* OBJALLOC_H */ 116