Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
dwarf_DST_mem.cxx
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  *  25-Apr-93 - Original Version
00042  *
00043  * Description:
00044  *
00045  * The DST info is internally represented as an array of block headers,
00046  * where each block header contains the kind, size, and offset of a block
00047  * of DST data.  In particular, there should be one block each for the
00048  * file-scope, include, file-names, and macro info, then one block for
00049  * each local-scope PU info.  
00050  *
00051  * When a block grows beyond its size, we allocate a new block.
00052  * We can't realloc space because there are places where we use a pointer
00053  * to the info in order to get the attributes.
00054  * In the intermediate file, only the exact size of the blocks 
00055  * is written and read.
00056  * ====================================================================
00057  * ====================================================================
00058  */
00059 
00060 #ifdef USE_PCH
00061 #include "common_com_pch.h"
00062 #endif /* USE_PCH */
00063 #pragma hdrstop
00064 #include "defs.h"
00065 #include "mempool.h"
00066 #define USE_DST_INTERNALS
00067 #include "dwarf_DST_mem.h"
00068 #include "errors.h"
00069 #include "stab.h"
00070 
00071 static inline void *
00072 Symtab_Alloc (size_t bytes, BOOL is_global)
00073 {
00074     if ( is_global ) {
00075         return (void *) Src_Alloc ( bytes );
00076     } else {
00077         return (void *) Pu_Alloc ( bytes );
00078     }
00079 }
00080 
00081 
00082 #define NUM_BLOCK_HEADERS 1024          /* initial # of block headers */
00083 #define BLOCK_SIZE 256                  /* size of individual block */
00084 
00085 DST_TYPE Current_DST = NULL;
00086 DST_Type *current_DST = NULL;
00087 
00088 
00089 /* Represents a NULL DST_IDX value. Always initialize a declared
00090  * DST_IDX with this value!!
00091 */
00092 const DST_IDX DST_INVALID_IDX = {DST_INVALID_BLOCK_IDX, DST_INVALID_BYTE_IDX};
00093 
00094 
00095          /*----------------*
00096           * Error Checking *
00097           *----------------*/
00098 
00099 #ifdef Is_True_On
00100 /* then do Error Checking */
00101 
00102 static DST_BLOCK_IDX
00103 DST_CHECK_BLOCK_IDX(DST_BLOCK_IDX b)
00104 {
00105    Is_True((b != DST_INVALID_BLOCK_IDX && b >= 0 &&
00106             b <= current_DST->last_block_header),
00107               ("Illegal DST block idx"));
00108    return b;
00109 }
00110 
00111 static DST_IDX
00112 DST_CHECK_IDX(DST_IDX i)
00113 {
00114    Is_True( ((i.byte_idx >= 0 &&
00115        i.byte_idx < current_DST->dst_blocks[DST_CHECK_BLOCK_IDX(i.block_idx)].size)) || DST_IS_FOREIGN_OBJ(i),
00116       ("Illegal DST idx"));
00117    return i;
00118 }
00119 
00120 #else  /* do not do Error Checking */
00121 
00122 #define DST_CHECK_BLOCK_IDX(b) (b)
00123 #define DST_CHECK_IDX(i) (i)
00124 
00125 /* Error Checking */
00126 #endif
00127 
00128 
00129 extern DST_TYPE
00130 New_DST (void)
00131 {
00132         INT32 i;
00133         DST_Type *dst = TYPE_MEM_POOL_ALLOC(DST_Type, MEM_src_pool_ptr);
00134 
00135         dst->last_block_header = -1;
00136         dst->max_block_header = NUM_BLOCK_HEADERS;
00137         dst->current_block_header = -1;
00138 
00139         /* the block_list should point to the first block
00140            for each of the block kinds */
00141         for (i = 0; i < DST_noblock; i++) {
00142                 dst->block_list[i] = DST_INVALID_BLOCK_IDX;
00143         }
00144 
00145         return (DST_TYPE)dst;
00146 }
00147 
00148 
00149 extern void
00150 DST_Init (char *start, INT32 num_blocks)
00151 {
00152         INT i;
00153         block_header *blocks;
00154         DST_BLOCK_IDX *blklist;
00155 
00156 
00157         if (Current_DST == NULL) 
00158             Current_DST = New_DST();
00159         
00160         current_DST = (DST_Type *)Current_DST;
00161 
00162         if (start == NULL) {
00163                 /* create new list of blocks */
00164                 blocks = (block_header*) Symtab_Alloc (NUM_BLOCK_HEADERS*sizeof(block_header), TRUE);
00165         } else {
00166                 /* use existing space as list of blocks */
00167                 blocks = (block_header *) start;
00168                 current_DST->max_block_header = num_blocks;
00169                 current_DST->last_block_header = num_blocks - 1;
00170 
00171                 blklist = &current_DST->block_list[0];
00172                 FOREACH_DST_BLOCK(i) {
00173                         /* Would be nice if global blocks came first,
00174                          * but that doesn't seem to be true, so search
00175                          * thru all blocks. */
00176                         /* Assume that when multiple blocks are used for a
00177                          * kind, first block will be earliest in the array. */
00178                         if (blklist[blocks[i].kind] == DST_INVALID_BLOCK_IDX)
00179                                 blklist[blocks[i].kind] = i;
00180                 }
00181 #if defined(_SUPPORT_IPA) || defined(_STANDALONE_INLINER) || defined(MONGOOSE_BE)
00182                 blocks[current_DST->last_block_header].allocsize = 
00183                         blocks[current_DST->last_block_header].size;
00184 #endif
00185         }
00186         current_DST->dst_blocks = blocks;
00187         current_DST->current_dst = blocks;
00188 }
00189 
00190 static void
00191 set_current_dst_to_current ( void )
00192 {
00193   current_DST->current_block_header = current_DST->last_block_header;
00194   current_DST->current_dst =
00195         &current_DST->dst_blocks[current_DST->current_block_header];
00196 }
00197 
00198 /*
00199 #if !(defined(MONGOOSE_BE)) || defined(_STANDALONE_INLINER) || defined(_SUPPORT_IPA)
00200 */
00201 
00202 static block_header *
00203 new_block (DST_BLOCK_KIND kind, INT32 size)
00204 {
00205         INT32 allocsize = (size < BLOCK_SIZE ? BLOCK_SIZE : size);
00206         DST_BLOCK_IDX last_block = current_DST->last_block_header;
00207         DST_BLOCK_IDX max_block = current_DST->max_block_header;
00208         block_header *blocks = current_DST->dst_blocks;
00209         block_header *current;
00210 
00211         if (++last_block >= max_block) {
00212                 blocks = TYPE_MEM_POOL_REALLOC_N(block_header,
00213                                                  MEM_src_pool_ptr ,
00214                                                  blocks, max_block,
00215                                                  2 * max_block);
00216                 max_block *= 2;
00217 
00218                 current_DST->dst_blocks = blocks;
00219                 current_DST->max_block_header = max_block;
00220         }
00221         current_DST->last_block_header = last_block;
00222         current_DST->current_block_header = last_block;
00223 
00224 #if defined(_SUPPORT_IPA) || defined(_STANDALONE_INLINER) || defined(MONGOOSE_BE)
00225         /* force Symtab_Alloc to allocate from the Src_block, not the PU_block
00226          */
00227         blocks[last_block].offset = (char*) Symtab_Alloc(allocsize,
00228                 TRUE);
00229 #else
00230         blocks[last_block].offset = (char*) Symtab_Alloc(allocsize,
00231                 (kind == DST_local_scope_block) ? FALSE : TRUE);
00232 #endif
00233         current = &blocks[last_block];
00234         current->kind = kind;
00235         current->size = 0;
00236         current->allocsize = allocsize;
00237         current_DST->current_dst = current;
00238 
00239         return current;
00240 }
00241 
00242 
00243 extern void
00244 DST_begin_block (DST_BLOCK_KIND block_kind)
00245 {
00246         DST_BLOCK_IDX *blklist;
00247         current_DST = (DST_Type *)Current_DST;
00248         blklist = &current_DST->block_list[0];
00249         current_DST->current_dst = new_block (block_kind, 0);
00250         if (blklist[block_kind] == DST_INVALID_BLOCK_IDX)
00251                 blklist[block_kind] = current_DST->last_block_header;
00252 }
00253 
00254 extern DST_IDX
00255 DST_allocate (INT32 size, INT32 align)
00256 {
00257         DST_IDX new_idx;
00258         INT32 total_size;
00259         INT32 align_mod, align_padding;
00260         block_header *current;
00261         current_DST = (DST_Type *)Current_DST;
00262 
00263 #if defined(_SUPPORT_IPA) || defined(_STANDALONE_INLINER) || defined(MONGOOSE_BE)
00264 #if 0
00265         if ((current_DST->dst_blocks == current_DST->current_dst) &&
00266             (current_DST->current_dst->kind != DST_local_scope_block)) {
00267             /* we should set current_dst to a new block */
00268             current = new_block (DST_local_scope_block, size);
00269             /* recalculate the alignment padding in the current_block */
00270             align_padding = 0;
00271             total_size = size;
00272             set_current_dst_to_current();
00273         }
00274         else {
00275 #endif
00276             set_current_dst_to_current();
00277             current = current_DST->current_dst;
00278 #if 0
00279         }
00280 #endif
00281 #else
00282             current = current_DST->current_dst;
00283 #endif
00284 
00285 
00286         /* Calculate the alignment padding in the current_block */
00287         align_mod = current->size % align;
00288         align_padding = (align_mod ? (align - align_mod) : 0);
00289         total_size = current->size + size + align_padding;
00290 
00291         if (total_size > current->allocsize) {
00292         /* Turn off the following if inliner/ipa is the one calling this
00293          * the first time
00294          * because by this time current->allocsize is NOT the amount
00295          * of space you can use anymore.  FE only reserved current->size
00296          * + align_padding for this current block
00297          */
00298                 /* allocate new block */
00299 #if defined(_SUPPORT_IPA) || defined(_STANDALONE_INLINER) || defined(MONGOOSE_BE)
00300                 current = new_block (DST_local_scope_block, size);
00301 #else
00302                 current = new_block (current->kind, size);
00303 #endif
00304                 /* recalculate the alignment padding in the current_block */
00305                 align_padding = 0;
00306                 total_size = size;
00307         }
00308 
00309         new_idx.block_idx = current_DST->current_block_header;
00310         new_idx.byte_idx = current->size + align_padding;
00311         current->size = total_size;
00312         return new_idx;
00313 }
00314 
00315 
00316 /* Resets "current_block" to become the last block in the block-list
00317  * into which idx points.
00318 */
00319 extern void
00320 DST_return_to_block(DST_IDX idx)
00321 {
00322         DST_BLOCK_IDX current_block;
00323         current_DST = (DST_Type *)Current_DST;
00324         current_block = DST_CHECK_IDX(idx).block_idx;
00325         current_DST->current_block_header = current_block;
00326         current_DST->current_dst = &current_DST->dst_blocks[current_block];
00327 }
00328 /*
00329 #endif * !MONGOOSE_BE  || _STANDALONE_INLINER  || _SUPPORT_IPA */
00330 
00331 
00332 /* Returns a pointer to the beginning of an allocated data area.  It
00333  * is up to the caller to ensure that access does not occur beyond the
00334  * end of the allocated area.  The accessed block must not yet be
00335  * written to file.
00336 */
00337 extern char * 
00338 DST_idx_to_string(DST_IDX idx)
00339 {
00340         block_header *block;
00341         current_DST = (DST_Type *)Current_DST;
00342         block = &current_DST->dst_blocks[DST_CHECK_IDX(idx).block_idx];
00343         if (idx.byte_idx == DST_INVALID_BYTE_IDX)
00344             return NULL;
00345         else
00346             return &(block->offset[idx.byte_idx]);
00347 }
00348 
00349 
00350 static DST_IDX
00351 DST_get_block_list(DST_BLOCK_KIND block_kind)
00352 {
00353         DST_IDX idx;
00354         DST_BLOCK_IDX bidx = current_DST->block_list[block_kind];
00355 
00356         if ((bidx == DST_INVALID_BLOCK_IDX) || 
00357             (current_DST->dst_blocks[DST_CHECK_BLOCK_IDX(bidx)].size <= 0)) {
00358                 idx = DST_INVALID_IDX;
00359         } else {
00360                 idx.byte_idx  = 0;   /* First byte in block */
00361                 idx.block_idx = bidx;
00362                 current_DST->current_dst = &current_DST->dst_blocks[bidx];
00363         }
00364         return idx;
00365 }
00366 
00367 
00368 /* Returns an index to the first DST_INCLUDE_DIR entry, which may be 
00369  * DST_INVALID_IDX in the abscence of any DST_INCLUDE_DIR entries.
00370 */
00371 extern DST_IDX
00372 DST_get_include_dirs(void)
00373 {
00374         current_DST = (DST_Type *)Current_DST;
00375         return DST_get_block_list(DST_include_dirs_block);
00376 }
00377 
00378 
00379 /* Returns an index to the first DST_FILE_NAME entry, which may be 
00380  * DST_INVALID_IDX in the abscence of any DST_FILE_NAME entries.
00381 */
00382 extern DST_IDX
00383 DST_get_file_names(void)
00384 {
00385         current_DST = (DST_Type *)Current_DST;
00386         return DST_get_block_list(DST_file_names_block);
00387 }
00388 
00389 
00390 /* Returns an index to the first DST_MACRO_INFO entry, which may be 
00391  * DST_INVALID_IDX in the abscence of any DST_MACRO_INFO entries.
00392 */
00393 extern DST_IDX
00394 DST_get_macro_info(void)
00395 {
00396         current_DST = (DST_Type *)Current_DST;
00397         return DST_get_block_list(DST_macro_info_block);
00398 }
00399 
00400 
00401 /* Returns an index to the DST_COMPILE_UNIT entry, which may be 
00402  * DST_INVALID_IDX in the abscence of any DST_COMPILE_UNIT entry.
00403 */
00404 extern DST_IDX
00405 DST_get_compile_unit(void)
00406 {
00407         current_DST = (DST_Type *)Current_DST;
00408         return DST_get_block_list(DST_file_scope_block);
00409 }
00410 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines