NAME NameDummy( void ) /********************/ { name_dummy_index_t ni; unsigned xhash; unsigned bucket; unsigned len; idname **head; char buff[ 1 + 1 + sizeof( ni ) * 3 + 1 ]; ExtraRptIncrementCtr( ctr_dummy_names ); ni = nameDummyIndex++; xhash = ni % NAME_TABLE_HASH; bucket = xhash; buff[0] = NAME_OPERATOR_OR_DUMMY_PREFIX1; buff[1] = NAME_DUMMY_PREFIX2; // the contents of the name don't have to be different just the address // but for debugging it is handy to have unique contents #ifndef NDEBUG ultoa( ni, &buff[2], 10 ); len = strlen( buff ); #else buff[2] = '0'; buff[3] = '\0'; len = 3; #endif head = &(hashTable[ bucket ]); return( nameAdd( head, bucket, xhash, buff, len ) ); }
NAME NameCreateLen( const char *id, unsigned len ) /************************************************/ { unsigned xhash; unsigned bucket; unsigned cmp_len; idname *name; idname **head; idname **prev; ExtraRptIncrementCtr( ctr_searches ); xhash = NameCalcHashLen( id, len ); #if NAME_TABLE_HASH != NAME_HASH bucket = xhash % NAME_TABLE_HASH; #else bucket = xhash; #endif // xhash cannot overflow a uint_16 ( 0x0fff + 0x00ff <= 0x1fff ) xhash += (uint_8) len; head = &(hashTable[ bucket ]); prev = head; cmp_len = len + 1; ExtraRptZeroCtr( ctr_length ); for( name = *prev; ; name = *prev ) { ExtraRptIncrementCtr( ctr_probes ); ExtraRptIncrementCtr( ctr_length ); if( name == NULL ) break; if( name->xhash == xhash ) { ExtraRptIncrementCtr( ctr_memcmp ); if( NameMemCmp( name->name, id, cmp_len ) == 0 ) { /* move name to front of list in hash table */ *prev = name->next; name->next = *head; *head = name; return( NAME_RETVAL( name ) ); } ExtraRptIncrementCtr( ctr_memcmp_fail ); } prev = &(name->next); } ExtraRptMaximum( ctr_length, ctr_max_length ); return( nameAdd( head, bucket, xhash, id, len ) ); }
static NAME nameAdd( idname **head, unsigned bucket, unsigned xhash, const char *id, unsigned len ) { idname *name; #ifdef XTRA_RPT if( *head == NULL ) { ExtraRptIncrementCtr( ctr_chains ); } #endif ExtraRptIncrementCtr( ctr_names ); DbgVerify( !nameFlags.no_creates_allowed, "name create occurred during precompiled header processing" ); name = CPermAlloc( NAME_SIZE + len + 1 ); memcpy( name->name, id, len + 1 ); name->xhash = xhash; name->hash = bucket; name->next = *head; *head = name; ++nameCount; return( NAME_RETVAL( name ) ); }
static void macroAllocSegment( // ALLOCATE MACRO SEGMENT unsigned minimum ) // - minimum size req'd { MACRO_SEG_LIST *macroSegment; if( minimum > MAC_SEGMENT_LIMIT ) { CErr1( ERR_OUT_OF_MACRO_MEMORY ); CSuicide(); } macroSegment = RingAlloc( ¯oSegmentList, sizeof( MACRO_SEG_LIST ) ); MacroOffset = macroSegment->segment; macroSegmentLimit = MAC_SEGMENT_LIMIT; ExtraRptIncrementCtr( macro_segments ); }
unsigned NameCalcHashLen( const char *id, unsigned len ) /******************************************************/ { const unsigned *s = (const unsigned *)id; unsigned mask; unsigned c; unsigned g; unsigned h; ExtraRptIncrementCtr( ctr_hashes ); /* modelled on hashpjw from the Dragon book */ /* should not be used in mangled names so that it can change in patches */ h = len; c = len; if( len > sizeof( unsigned ) ) { do { c ^= *s; h = ( h << 4 ) + c; g = h & ~0x0ffffff; h ^= g; h ^= g >> (4+4+4+4+4); ++s; len -= sizeof( unsigned ); } while( len > sizeof( unsigned ) ); } mask = NameCmpMask[ len ]; c ^= *s & mask; h = ( h << 4 ) + c; g = h & ~0x0ffffff; h ^= g; h ^= g >> (4+4+4+4+4); g = h & ~0x0fff; h ^= g; h ^= g >> (4+4+4); h ^= h >> (2+4); DbgAssert(( h % NAME_HASH ) == h ); return( h ); }
static DIRGRAPH_EDGE *cgrfAllocEdge( // ALLOCATE AN EDGE CALLGRAPH *ctl ) // - control information { ExtraRptIncrementCtr( ctr_edges ); return CarveAlloc( ctl->carve_edges ); }
static DIRGRAPH_NODE *cgrfAllocNode( // ALLOCATE A NODE CALLGRAPH *ctl ) // - control information { ExtraRptIncrementCtr( ctr_nodes ); return CarveAlloc( ctl->carve_nodes ); }