Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
mempool.h
Go to the documentation of this file.
00001 /*
00002 
00003   Copyright (C) 2000, 2001 Silicon Graphics, Inc.  All Rights Reserved.
00004 
00005   This program is free software; you can redistribute it and/or modify it
00006   under the terms of version 2 of the GNU General Public License as
00007   published by the Free Software Foundation.
00008 
00009   This program is distributed in the hope that it would be useful, but
00010   WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
00012 
00013   Further, this software is distributed without any warranty that it is
00014   free of the rightful claim of any third person regarding infringement 
00015   or the like.  Any license provided herein, whether implied or 
00016   otherwise, applies only to this software file.  Patent licenses, if 
00017   any, provided herein do not apply to combinations of this program with 
00018   other software, or any other product whatsoever.  
00019 
00020   You should have received a copy of the GNU General Public License along
00021   with this program; if not, write the Free Software Foundation, Inc., 59
00022   Temple Place - Suite 330, Boston MA 02111-1307, USA.
00023 
00024   Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
00025   Mountain View, CA 94043, or:
00026 
00027   http://www.sgi.com
00028 
00029   For further information regarding this notice, see:
00030 
00031   http://oss.sgi.com/projects/GenInfo/NoticeExplan
00032 
00033 */
00034 
00035 
00036 /* ====================================================================
00037  * ====================================================================
00038  *
00039  *
00040  * Revision history:
00041  *  19-Sep-89 - Original Version
00042  *  24-Jan-91 - Copied for TP/Muse
00043  *  28-May-91 - Integrated Josie routines
00044  *  20-Sep-91 - Added TYPE_X_MALLOC and TYPE_ALLOC macros
00045  *  05-Apr-93 - Rewritten from scratch to allow statistics, better
00046  *              handling of large blocks.
00047  *
00048  * Description:
00049  *
00050  * This package provides a different interface from the traditional C
00051  * malloc/free memory allocation, and is MUCH more effecient for a
00052  * particular style of memory allocation common in the compiler.  In
00053  * this style, individual memory blocks are not freed one at a time.
00054  * Rather all the outstanding memory in a particular memory pool is
00055  * freed as a whole.  Doing this allow us to replace large numbers of
00056  * calls to alloc/free with only a few calls which allocate and
00057  * deallocate large blocks.
00058  *
00059  * Each MEM_POOL has a current allocation level.  MEM_POOLs may be
00060  * Push'ed onto a new allocation level or Pop'ed back to their
00061  * previous allocation level.  When a MEM_POOL is pop'ed, all the
00062  * memory allocated from it since it was pushed to its current level
00063  * is freed.
00064  *
00065  * Compiling all the compiler sources with -DIs_True_On and MEM_Trace_Enable
00066  * enables collection of memory allocation statistics.  With these it is
00067  * possible to see a lot of information about the callsites where
00068  * memory is allocated.  In particular, it is possible to see how much
00069  * memory allocated from each callsite is outstanding.
00070  *
00071  * Before you begin
00072  * ================
00073  *
00074  *      void MEM_Initialize()
00075  *
00076  *          Initialize the memory pool package.
00077  *
00078  * Global Variables
00079  * ================
00080  *
00081  *      MEM_POOL *Malloc_Mem_Pool
00082  *
00083  *          If this MEM_POOL is passed as an argument to an alloc or free
00084  *          routine, use malloc instead of the mempools.  
00085  *          Note that it causes the use of malloc and not calloc.  Memory
00086  *          from this pool will not be automatically zeroed.
00087  *
00088  *      MEM_POOL *Default_Mem_Pool
00089  *
00090  *          Use the default MEM_POOL  
00091  *
00092  *
00093  * Operations defined on MEM_POOLS
00094  * ===============================
00095  *
00096  *      void MEM_POOL_Set_Default(MEM_POOL *pool)
00097  *
00098  *          All subsequent uses of Default_Mem_Pool will refer to pool
00099  *
00100  *      void MEM_POOL_Initialize(
00101  *          MEM_POOL   *pool,
00102  *          const char *name,
00103  *          BOOL       bz
00104  *      )
00105  *
00106  *          Must be called on a pool before it used for the other
00107  *          operations.
00108  *
00109  *              pool    - is a pointer to the MEM_POOL to initialize.
00110  *              name    - is a name to use when printing information
00111  *                        about it
00112  *              bz      - If TRUE, memory allocated from the pool will
00113  *                        always be zero'ed
00114  *
00115  *          After a MEM_POOL has been initialized, it is important
00116  *          that the structure it points to at no point go out of
00117  *          scope, so MEM_POOLs initialized this way should generally
00118  *          statically allocated.
00119  *
00120  *
00121  *      BOOL MEM_POOL_Zeroed(MEM_POOL *pool)
00122  *
00123  *          Returns TRUE iff <pool> zeroes newly allocated memory
00124  *          (i.e., if <bz> argument was TRUE when pool was initialized).
00125  *
00126  *
00127  *      void MEM_POOL_Push(
00128  *          MEM_POOL *pool
00129  *      )
00130  *
00131  *          Check that the pool is not frozen. If not, 
00132  *          push a pool to a new allocation level.
00133  *
00134  *              pool    - is a pointer to the MEM_POOL to push
00135  *
00136  *      void MEM_POOL_Push_Freeze(
00137  *          MEM_POOL *pool
00138  *      )
00139  *      
00140  *          Same as MEM_POOL_Push, except that after being pushed, 
00141  *          the pool is frozen for subsequent push/pop operations
00142  *          until the pool is unfrozen.
00143  *
00144  *              pool    - is a pointer to the MEM_POOL to push
00145  *
00146  *      void MEM_POOL_Pop(
00147  *          MEM_POOL *pool
00148  *      )
00149  *
00150  *          Check that the pool is not frozen. If not, then
00151  *          pop a MEM_POOL to a previous allcation level.  All memory
00152  *          allocated since the matching call to MEM_POOL_Push is
00153  *          freed.  As a special case, unmatched pop's just free ALL
00154  *          outstanding storage in t
00155  *
00156  *              pool    - is a pointer to the MEM_POOL to pop
00157  *
00158  *      void MEM_POOL_Pop_Unfreeze(
00159  *          MEM_POOL *pool
00160  *      )
00161  *
00162  *          Same as MEM_POOL_Pop, except that the memory pool is first
00163  *          unfrozen. Must be called on a frozen memory pool.
00164  *
00165  *              pool    - is a pointer to the MEM_POOL to pop
00166  *
00167  *
00168  *      MEM_PTR MEM_POOL_Alloc(
00169  *          MEM_POOL *pool,
00170  *          size_t    size
00171  *      )
00172  *
00173  *          Allocate memory from a pool.  Always double word aligned.
00174  *
00175  *              pool    - is a pointer to the MEM_POOL for allocation
00176  *              size    - gives the number of bytes to allocate.
00177  *
00178  *          This is a low level usage and is discouraged in favor of
00179  *          the TYPE_ forms below.
00180  *
00181  *          If pool == Malloc_Mem_Pool this just calls the system malloc
00182  *
00183  *
00184  *      MEM_PTR MEM_POOL_Realloc(
00185  *          MEM_POOL *pool,
00186  *          MEM_PTR   old_block,
00187  *          size_t    old_size,
00188  *          size_t    new_size
00189  *      )
00190  *
00191  *          Reallocate memory from a pool.
00192  *
00193  *              pool      - is a pointer to the MEM_POOL for allocation
00194  *              old_block - is a value previously returned from
00195  *                          MEM_POOL_Alloc, or MEM_POOL_Realloc.
00196  *                          (Very important.)  It must have been
00197  *                          (re)allocated from the given pool. (Very
00198  *                          important.)
00199  *              old_size  - is the size used to (re)allocate old_block
00200  *              new_size  - is the size new allocation size.
00201  *
00202  *          Returns a block of memory 'new_size' bytes long.  The
00203  *          first 'old_size' byte of the returned memory contain the
00204  *          same values as in the 'old_block'.
00205  *
00206  *          Implementation notes: There are some cases in which this
00207  *          is more effecient than just allocating a new block and
00208  *          copying in the firrt old_size bytes.  In particular, if
00209  *          'old_block' was the last block of memory allocated from
00210  *          'pool' the reallocation will often be 'in place'.  Even if
00211  *          it isn't in place, the memory for 'old_block' will be made
00212  *          available for future by the pool package.  If it
00213  *          especially important to get this effect for some reason,
00214  *          you should consider using a dedicated pool to hold the
00215  *          vector that you plan to realloc.
00216  *
00217  *          If pool == Malloc_Mem_Pool this just calls the system realloc
00218  *
00219  *
00220  *      void MEM_POOL_FREE(
00221  *          MEM_POOL *pool,
00222  *          void *data
00223  *      )
00224  *
00225  *          Free the data from a MEM_POOL.  If pool == Malloc_Mem_Pool,
00226  *          this calls the UNIX free.  Otherwise this is a no-op.
00227  *
00228  *
00229  *      void MEM_POOL_Delete(MEM_POOL *pool)
00230  *
00231  *          Free all the memory associated with <pool>.  Currently,
00232  *          deleted pools are not reported by MEM_Trace (but this can
00233  *          be changed).  Note that <*pool> itself is not freed.  A
00234  *          deleted pool cannot be used unless it is first initialized
00235  *          again with MEM_POOL_Initialize.
00236  *
00237  *
00238  *  Typed allocation macros
00239  *  =======================
00240  *
00241  *  Use of these forms is STRONGLY encouraged as they will allow us to
00242  *  collect information by types as will as by callsites.  They are
00243  *  also terser and less error prone than bare calls to alloc with
00244  *  sizeof and a cast.
00245  *
00246  *      type * TYPE_MEM_POOL_ALLOC(
00247  *          type,
00248  *          MEM_POOL *pool
00249  *      )
00250  *
00251  *      type * TYPE_MEM_POOL_ALLOC_N(
00252  *          type,
00253  *          MEM_POOL *pool,
00254  *          size_t    count
00255  *      )
00256  *
00257  *      type * TYPE_MEM_POOL_REALLOC_N(
00258  *          type,
00259  *          MEM_POOL *pool,
00260  *          type     *old_block,
00261  *          size_t    old_count,
00262  *          size_t    new_count
00263  *      )
00264  *
00265  *          Allocate one or more objects of a particular type from a
00266  *          pool and return a typed pointer.  The plain form allocates
00267  *          a single object.  The _N for allocates a vector of such
00268  *          objects.
00269  *
00270  *              type        - is the name of the type to allocate.  Enough
00271  *                            memory is allocated to hold one (plain form)
00272  *                            or n (_N form) for these.
00273  *              pool        - is a pointer to the MEM_POOL to use,
00274  *              count       - How many objects (_N form only).
00275  *
00276  *          If pool == Malloc_Mem_Pool this calls the system malloc/realloc
00277  *
00278  *
00279  *      type * TYPE_MEM_POOL_REALLOC_N(
00280  *          type,
00281  *          MEM_POOL *pool,
00282  *          type     *old_block,
00283  *          size_t    old_count,
00284  *          size_t    new_count
00285  *      )
00286  *
00287  *          Reallocate a vector of one or more objects.  Both the old
00288  *          and new vectors must be in the same pool.
00289  *
00290  *              type        - is the name of the type to allocate.  Enough
00291  *                            memory is allocated to hold one (plain form)
00292  *                            or n (_N form) for these.
00293  *              pool        - is a pointer to the MEM_POOL to use,
00294  *              old_block   - is the block of memory to reallocate.
00295  *                            It must have been (re)allocated from the
00296  *                            given 'pool'
00297  *              old_count   - is the number of elements allocated in
00298  *                            'old_block'.  It is VERY IMPORTANT that
00299  *                            this be accurate.
00300  *              new_count   - How many objects
00301  *
00302  *
00303  *  Tracing memory allocation
00304  *  =========================
00305  *
00306  *  When Is_True_On is enabled, we also support:
00307  *
00308  *      void MEM_Tracing_Enable(void)
00309  *
00310  *          Tell the memory package to collect alloc call site
00311  *          statistics.
00312  *
00313  *      void MEM_Trace(void)
00314  *
00315  *          Produces a report on the TFile at to memory allocation.
00316  *          This report starts with the low-level malloc information
00317  *          (see malloc(3)) provided by the -lmalloc package.
00318  *          Then for each pool, a list MEM_POOL_Alloc callsites is
00319  *          given, sorted by the maximum amount of outstanding memory
00320  *          at any time for each callsite.  Here is a key to the per
00321  *          callsite information:
00322  *
00323  *              maxt    - Maximum outstanding memory at any one time
00324  *              curr    - Current memory outstanding
00325  *              tot     - Total memory allocated from this callsite
00326  *              maxs    - Largest memory block allocated from this
00327  *                        callsite
00328  *              count   - Count of times callsite was executed
00329  *              grew    - Count of times more memory was allocated
00330  *                        from this callsite than last time it was
00331  *                        executed.
00332  *              shrank  - Count of times less memory was allocated
00333  *                        from this callsite than last time it was
00334  *                        executed.
00335  *
00336  *      void Trace_Memory_Allocation(
00337  *          const INT phase,
00338  *          const char *const pname
00339  *      )
00340  *
00341  *          Produce a memory allocation trace (via MEM_Trace) when
00342  *          the trace switch -ta<m> is specified on the compile line.
00343  *
00344  *              phase - Phase after which we're printing
00345  *              pname - Print name for phase 
00346  *
00347  * Related Utilities
00348  * =================
00349  *
00350  * While not strictly MEM_POOL related, the following utilities are
00351  * are provided:
00352  *
00353  *      type * TYPE_ALLOCA(
00354  *          type
00355  *      )
00356  *
00357  *      type * TYPE_ALLOCA_N(
00358  *          type,
00359  *          size_t    count
00360  *      )
00361  *
00362  *          Allocate one or more objects of a particular type using
00363  *          alloca and return a typed pointer.  The plain form allocates
00364  *          a single object.  The _N for allocates a vector of such
00365  *          objects.
00366  *
00367  *              type        - is the name of the type to allocate.  Enough
00368  *                            memory is allocated to hold one (plain form)
00369  *                            or n (_N form) for these.
00370  *              count       - How many objects (_N form only).
00371  *
00372  * Backward Compatibility
00373  * ======================
00374  *
00375  * For the sake of backward compatibility, this package also supports
00376  * an older interface.  It's direct usage in new code is discouraged.
00377  * It deals with allocations from four predefined pools which are
00378  * never directly accessed, but are accessed via function calls.
00379  *
00380  * The four predefined pools are:
00381  *
00382  *      L       - Pushed and popped to get local utility storage
00383  *      Pu      - Pushed and popped to get storage that can be freed
00384  *                up after we are done with each program unit
00385  *      Src     - Pushed and popped to get storage that can be freed
00386  *                up after we are done with each source file.
00387  *      P       - Pushed and popped to get utiity storage that can be
00388  *                freed up when we are done with the current "phase".
00389  *
00390  * All four pools support:
00391  *
00392  *      MEM_PTR X_Alloc(
00393  *          size_t size
00394  *      )
00395  *
00396  *      TYPE_X_ALLOC(
00397  *          type
00398  *      )
00399  *
00400  *      TYPE_X_ALLOC_N(
00401  *          type,
00402  *          INT32 n
00403  *      )
00404  *
00405  * (Where X is one of the predefined pools.)
00406  *
00407  * Additionally, the Local pool supports:
00408  *
00409  *      void L_Save(void)
00410  *
00411  *          Pushes the L pool.
00412  *
00413  *      void L_Free(void)
00414  *
00415  *          Pops the L pool.
00416  *
00417  * ====================================================================
00418  * ==================================================================== */
00419 
00420 
00421 
00422 
00423 
00424 #ifndef mempool_INCLUDED
00425 #define mempool_INCLUDED
00426 #ifdef __cplusplus
00427 extern "C" {
00428 #endif
00429 
00430 
00431 
00432 #include "defs.h"
00433 
00434 #define TYPE_ALLOCA(type) ((type *)alloca(sizeof(type)))
00435 #define TYPE_ALLOCA_N(type,n) ((type *)alloca(sizeof(type) * (n)))
00436 
00437 #if 0
00438 #define TYPE_MALLOC(type) ((type *) malloc(sizeof(type)))
00439 #define TYPE_MALLOC_N(type,n) ((type *) malloc(sizeof(type) * (n)))
00440 #endif
00441 
00442 #define Malloc_Mem_Pool  (MEM_POOL *) 1
00443 #define Default_Mem_Pool  (MEM_POOL *) 0
00444 
00445 /* MEM_BLOCK - Internals private.
00446  */
00447 typedef struct mem_block MEM_BLOCK;
00448 
00449 /* MEM_POOL_BLOCKS - Internals private.
00450  */
00451 typedef struct mem_pool_blocks MEM_POOL_BLOCKS;
00452 
00453 /* MEM_STAT - Internals private.
00454  */
00455 typedef struct mem_stat MEM_STAT;
00456 
00457 /* MEM_PURE_STACK - Internals private.
00458  */
00459 typedef struct mem_pure_stack MEM_PURE_STACK;
00460 
00461 /* MEM_POOL - An object out of which to allocate and free memory.
00462  * See below for currently supported MEM_POOL operations.
00463  *
00464  * Internals private, but documented here, as the
00465  * declaration must be public so its size will be known to clients.
00466  */
00467 typedef struct mem_pool MEM_POOL;
00468 struct mem_pool {
00469   const char      *name;            /* Name of the pool for
00470                                      * debugging only.
00471                                      */
00472   MEM_POOL_BLOCKS *blocks;          /* Current top of allocation
00473                                      * stack.  This changes when the
00474                                      * pool is pushed or popped.
00475                                      */
00476   MEM_POOL        *rest;            /* Used to keep a link of all
00477                                      * initialized pools.
00478                                      */
00479   MEM_PURE_STACK *pure_stack;       /* Stack of pointers, one for each push 
00480                                      * level, each pointer pointing to first 
00481                                      * allocated piece in that push-level.
00482                                      */
00483   mBOOL             bz;             /* To allocate zero'd memory
00484                                      * or not out of this pool.
00485                                      */
00486   mBOOL           frozen;           /* If frozen, then subsequent Push/Pop
00487                                      * operations are disabled until the
00488                                      * mem_pool is unfrozen.
00489                                      * Default unfrozen.
00490                                      */
00491   mUINT16       magic_num;          /* Set to a a magic number when
00492                                      * the MEM_POOL is initialized, and
00493                                      * reset to zero when the pool is deleted.
00494                                      * Used to check that the pool is
00495                                      * initialized before a Push/Alloc.
00496                                      */
00497   MEM_STAT        *alloc_site_list; /* Used to report statistics
00498                                      * about call sites that have
00499                                      * outstanding allocation in the
00500                                      * pool.
00501                                      */
00502 };
00503 
00504 #define MEM_STAT_ARGS(line,file) ,INT32 line, const char *file
00505 
00506 extern void
00507 MEM_Initialize(void);
00508 
00509 #define MEM_POOL_Zeroed(pool) ((pool)->bz)
00510 
00511 /* These pools zero newly-allocated memory.
00512  */
00513 extern MEM_POOL MEM_local_pool;
00514 extern MEM_POOL MEM_src_pool;
00515 extern MEM_POOL MEM_pu_pool;
00516 extern MEM_POOL MEM_phase_pool;
00517 
00518 extern MEM_POOL *MEM_local_pool_ptr;
00519 extern MEM_POOL *MEM_src_pool_ptr;
00520 extern MEM_POOL *MEM_pu_pool_ptr;
00521 extern MEM_POOL *MEM_phase_pool_ptr;
00522 
00523 /* These pools don't zero newly-allocated memory, and hence allocation
00524  * is faster than the zeroed pools above.  These should be used whenever
00525  * appropriate.
00526  */
00527 extern MEM_POOL MEM_local_nz_pool;
00528 extern MEM_POOL MEM_src_nz_pool;
00529 extern MEM_POOL MEM_pu_nz_pool;
00530 extern MEM_POOL MEM_phase_nz_pool;
00531 
00532 extern MEM_POOL *MEM_local_nz_pool_ptr;
00533 extern MEM_POOL *MEM_src_nz_pool_ptr;
00534 extern MEM_POOL *MEM_pu_nz_pool_ptr;
00535 extern MEM_POOL *MEM_phase_nz_pool_ptr;
00536 
00537 extern void MEM_Trace(void);
00538 
00539 extern void 
00540 Trace_Memory_Allocation(
00541   INT phase,
00542   const char *pname
00543 );
00544 
00545 extern void MEM_Tracing_Enable(void);
00546 
00547 extern MEM_PTR
00548 MEM_POOL_Alloc_P
00549 (
00550   MEM_POOL *mempool,
00551   size_t    size
00552   MEM_STAT_ARGS(line,file)
00553 );
00554 
00555 extern MEM_PTR
00556 MEM_POOL_Realloc_P
00557 (
00558   MEM_POOL *mempool,
00559   MEM_PTR   old_block,
00560   size_t    old_size,
00561   size_t    new_size
00562   MEM_STAT_ARGS(line,file)
00563 );
00564 
00565 extern void
00566 MEM_POOL_Push_P
00567 (
00568   MEM_POOL *pool
00569   MEM_STAT_ARGS(line,file)
00570 );
00571 
00572 extern void
00573 MEM_POOL_Push_Freeze_P
00574 (
00575   MEM_POOL *pool
00576   MEM_STAT_ARGS(line,file)
00577 );
00578 
00579 extern void
00580 MEM_POOL_Pop_P
00581 (
00582   MEM_POOL *pool
00583   MEM_STAT_ARGS(line,file)
00584 );
00585 
00586 extern void
00587 MEM_POOL_Pop_Unfreeze_P
00588 (
00589   MEM_POOL *pool
00590   MEM_STAT_ARGS(line,file)
00591 );
00592 
00593 extern void MEM_POOL_Set_Default(MEM_POOL *pool);
00594 extern void MEM_POOL_FREE(MEM_POOL *pool, void *data);
00595 extern void MEM_POOL_Delete(MEM_POOL *pool);
00596 
00597 extern void
00598 MEM_POOL_Initialize_P
00599 (
00600   MEM_POOL     *pool,
00601   const char   *name,
00602   BOOL          bz
00603   MEM_STAT_ARGS(line,file)
00604 );
00605 
00606 #ifdef Is_True_On
00607 #define MEM_POOL_Alloc(pool,size)                                       \
00608   MEM_POOL_Alloc_P(pool,size,__LINE__,__FILE__)
00609 
00610 #define MEM_POOL_Realloc(pool,o,os,ns)                                  \
00611   MEM_POOL_Realloc_P((pool),(o),(os),(ns),__LINE__,__FILE__)
00612 
00613 #define MEM_POOL_Push(pool)                                             \
00614   MEM_POOL_Push_P(pool,__LINE__,__FILE__)
00615 
00616 #define MEM_POOL_Push_Freeze(pool)                                      \
00617   MEM_POOL_Push_Freeze_P(pool,__LINE__,__FILE__)
00618 
00619 #define MEM_POOL_Pop(pool)                                              \
00620   MEM_POOL_Pop_P(pool,__LINE__,__FILE__)
00621 
00622 #define MEM_POOL_Pop_Unfreeze(pool)                                     \
00623   MEM_POOL_Pop_Unfreeze_P(pool,__LINE__,__FILE__)
00624 
00625 #define MEM_POOL_Initialize(pool,name,bz)                               \
00626   MEM_POOL_Initialize_P(pool,name,bz,__LINE__,__FILE__)
00627 #else
00628 #define MEM_POOL_Alloc(pool,size)                                       \
00629   MEM_POOL_Alloc_P(pool,size,0,NULL)
00630 
00631 #define MEM_POOL_Realloc(pool,o,os,ns)                                  \
00632   MEM_POOL_Realloc_P((pool),(o),(os),(ns),0,NULL)
00633 
00634 #define MEM_POOL_Push(pool)                                             \
00635   MEM_POOL_Push_P(pool,0,NULL)
00636 
00637 #define MEM_POOL_Push_Freeze(pool)                                      \
00638   MEM_POOL_Push_Freeze_P(pool,0,NULL)
00639 
00640 #define MEM_POOL_Pop(pool)                                              \
00641   MEM_POOL_Pop_P(pool,0,NULL)
00642 
00643 #define MEM_POOL_Pop_Unfreeze(pool)                                     \
00644   MEM_POOL_Pop_Unfreeze_P(pool,0,NULL)
00645 
00646 #define MEM_POOL_Initialize(pool,name,bz)                               \
00647   MEM_POOL_Initialize_P(pool,name,bz,0,NULL)
00648 #endif
00649 
00650 #define TYPE_MEM_POOL_ALLOC(type,pool)                                  \
00651     ((type *) MEM_POOL_Alloc(pool,sizeof(type)))
00652 
00653 #define TYPE_MEM_POOL_ALLOC_N(type,pool,n)                              \
00654     ((type *) MEM_POOL_Alloc(pool,sizeof(type) * (n)))
00655 
00656 #define TYPE_MEM_POOL_REALLOC_N(type,pool,old_block,old_n,new_n)        \
00657     ((type *) MEM_POOL_Realloc(pool,((MEM_PTR) old_block),              \
00658                                     (sizeof(type) * (old_n)),           \
00659                                     (sizeof(type) * (new_n))))
00660 
00661 
00662 /* Backward compatibility
00663  */
00664 #define L_Save()     MEM_POOL_Push(MEM_local_pool_ptr)
00665 #define L_Alloc(x)   MEM_POOL_Alloc(MEM_local_pool_ptr,(x))
00666 #define L_Free()     MEM_POOL_Pop(MEM_local_pool_ptr)
00667 
00668 #define P_Alloc(x)   MEM_POOL_Alloc(MEM_phase_pool_ptr,(x))
00669 #define Src_Alloc(x) MEM_POOL_Alloc(MEM_src_pool_ptr,(x))
00670 #define Pu_Alloc(x)  MEM_POOL_Alloc(MEM_pu_pool_ptr,(x))
00671 
00672 #define TYPE_L_ALLOC(type)       ((type*)L_Alloc(sizeof(type)))
00673 #define TYPE_L_ALLOC_N(type,n)   ((type*)L_Alloc(sizeof(type)*(n)))
00674 #define TYPE_P_ALLOC(type)       ((type*)P_Alloc(sizeof(type)))
00675 #define TYPE_P_ALLOC_N(type,n)   ((type*)P_Alloc(sizeof(type)*(n)))
00676 #define TYPE_PU_ALLOC(type)      ((type*)Pu_Alloc(sizeof(type)))
00677 #define TYPE_PU_ALLOC_N(type,n)  ((type*)Pu_Alloc(sizeof(type)*(n)))
00678 #define TYPE_SRC_ALLOC(type)     ((type*)Src_Alloc(sizeof(type)))
00679 #define TYPE_SRC_ALLOC_N(type,n) ((type*)Src_Alloc(sizeof(type)*(n)))
00680 
00681 /* Routines to grow space (based on realloc), clearing the new part of
00682  * the grown area while leaving the (copied) original contents
00683  * unmodified.
00684  */
00685 MEM_PTR Realloc_Clear ( /* realloc and clear new space */
00686   MEM_PTR ptr,          /* Currently allocated memory */
00687   INT32 new_size,       /* New size desired */
00688   INT32 old_size        /* Old size (leave this much unchanged) */
00689 );
00690 MEM_PTR Re_Calloc (     /* Realloc and clear -- calloc-style call */
00691   MEM_PTR ptr,          /* Currently allocated memory */
00692   INT32 new_nelem,      /* New element count desired */
00693   INT32 elsize,         /* Element size */
00694   INT32 old_nelem       /* Old element count (leave unchanged) */
00695 );
00696 
00697 
00698 #ifdef __cplusplus
00699 }
00700 #endif
00701 
00702 #ifdef __cplusplus
00703 
00704 /* Class for automatically pushing and popping a mempool.  This is useful
00705  * for automatically doing a MEM_POOL_Pop() whenever we return from a
00706  * function, and for guaranteeing that all objects allocated from a mempool
00707  * are deallocated before the mempool is popped.
00708  *
00709  * Use the class within a function body, like this:
00710  *
00711  *  RETURN_TYPE my_func(...)
00712  *  {
00713  *      // mempool must have already been initialized; typically it's a
00714  *      // file static or global variable.  You MUST declare popper before
00715  *      // you start allocating storage from mempool.
00716  *    MEM_POOL_Popper popper(&mempool); // constructor does MEM_POOL_Push()
00717  *
00718  *      // Temporary that's no longer needed after we return from my_func().
00719  *      // Its declaration MUST come after popper.
00720  *    DYN_ARRAY<WN *> array_of_wn(&mempool);
00721  *      // Other temporaries allocated from mempool.
00722  *
00723  *    ... // code that allocates elements for array_of_wn and other temps.
00724  *
00725  *    if (some_condition)
00726  *        // Temporaries are automatically destructed and mempool is popped,
00727  *        // in the right order, despite early return from function.
00728  *      return val1;
00729  *
00730  *      // Temporaries are automatically destructed and mempool is popped,
00731  *      // in the right order.
00732  *    return val2;
00733  *  }
00734  *
00735  * The reason the MEM_POOL_Popper destructor call (hence also the
00736  * MEM_POOL_Pop()) is guaranteed to follow the destruction of objects
00737  * allocated from the mempool is that C++ guarantees that auto objects are
00738  * destructed in the reverse order of their appearance in the block (see
00739  * Stroustrup, "C++ Programming Language" 3rd ed., p. 245).
00740  */
00741 
00742 class MEM_POOL_Popper {
00743   MEM_POOL *pool;
00744 public:
00745   MEM_POOL_Popper(MEM_POOL *_pool) : pool(_pool) { MEM_POOL_Push(pool); }
00746   ~MEM_POOL_Popper() { MEM_POOL_Pop(pool); }
00747 
00748   MEM_POOL* Pool () const { return pool; }
00749 };
00750 
00751 /* Similar to MEM_POOL_Popper, CXX_MEM_POOL is used for initializing and
00752  * automatically deleting a MEM_POOL within a local scope.
00753  */
00754 
00755 class CXX_MEM_POOL {
00756   MEM_POOL mem_pool;
00757 
00758 public:
00759   MEM_POOL *operator()() { return &mem_pool; }
00760 
00761   CXX_MEM_POOL(const char *name, BOOL bbzero) {
00762     mem_pool.magic_num = 0;             /* force it to be uninitialized */
00763     MEM_POOL_Initialize(&mem_pool, name, bbzero);
00764     MEM_POOL_Push(&mem_pool);
00765   };
00766   ~CXX_MEM_POOL() {
00767     MEM_POOL_Pop(&mem_pool);
00768     MEM_POOL_Delete(&mem_pool);
00769   }
00770 };
00771 
00772 /* MEM_POOL_Constructor:  to be phased out.
00773    This is used for those cases where the MEM_POOL needs to be file-level
00774    static or global.
00775 */
00776 
00777 class MEM_POOL_Constructor
00778 {
00779 private:
00780    MEM_POOL *pool;
00781 
00782 public:
00783 
00784     MEM_POOL_Constructor (MEM_POOL* p, const char* name, BOOL zero) 
00785       : pool (p) {
00786         MEM_POOL_Initialize (pool, name, zero);
00787         MEM_POOL_Push (pool);
00788     }
00789 
00790     ~MEM_POOL_Constructor () {
00791         MEM_POOL_Pop (pool);
00792         MEM_POOL_Delete (pool);
00793     }
00794 
00795     MEM_POOL* Pool () const { return pool; };
00796 };
00797 #endif /* #ifdef __cplusplus */
00798 
00799 #endif /* mempool_INCLUDED */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines