Open64 (mfef90, whirl2f, and IR tools)
TAG: version-openad; SVN changeset: 916
|
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 */