static void ft_mem_table_set( FT_MemTable table, FT_Byte* address, FT_ULong size ) { FT_MemNode *pnode, node; if ( table ) { pnode = ft_mem_table_get_nodep( table, address ); node = *pnode; if ( node ) { if ( node->size < 0 ) { /* this block was already freed. This means that our memory is */ /* now completely corrupted! */ ft_mem_debug_panic( "memory heap corrupted (allocating freed block)" ); } else { /* this block was already allocated. This means that our memory */ /* is also corrupted! */ ft_mem_debug_panic( "memory heap corrupted (re-allocating allocated block)" ); } } /* we need to create a new node in this table */ node = (FT_MemNode)ft_mem_table_alloc( table, sizeof ( *node ) ); if ( node == NULL ) ft_mem_debug_panic( "not enough memory to run memory tests" ); node->address = address; node->size = size; node->alloc_file_name = table->file_name; node->alloc_line_no = table->line_no; node->free_file_name = NULL; node->free_line_no = 0; node->link = pnode[0]; pnode[0] = node; table->nodes++; table->alloc_total += size; table->alloc_current += size; if ( table->alloc_current > table->alloc_max ) table->alloc_max = table->alloc_current; if ( table->nodes * 3 < table->size || table->size * 3 < table->nodes ) ft_mem_table_resize( table ); } }
static void ft_mem_table_remove( FT_MemTable table, FT_Byte* address, FT_Long delta ) { if ( table ) { FT_MemNode *pnode, node; pnode = ft_mem_table_get_nodep( table, address ); node = *pnode; if ( node ) { FT_MemSource source; if ( node->size < 0 ) ft_mem_debug_panic( "freeing memory block at %p more than once at (%s:%ld)\n" "block allocated at (%s:%ld) and released at (%s:%ld)", address, FT_FILENAME( _ft_debug_file ), _ft_debug_lineno, FT_FILENAME( node->source->file_name ), node->source->line_no, FT_FILENAME( node->free_file_name ), node->free_line_no ); /* scramble the node's content for additional safety */ FT_MEM_SET( address, 0xF3, node->size ); if ( delta == 0 ) { source = node->source; source->cur_blocks--; source->cur_size -= node->size; table->alloc_current -= node->size; } if ( table->keep_alive ) { /* we simply invert the node's size to indicate that the node */ /* was freed. */ node->size = -node->size; node->free_file_name = _ft_debug_file; node->free_line_no = _ft_debug_lineno; } else { table->nodes--; *pnode = node->link; node->size = 0; node->source = NULL; ft_mem_table_free( table, node ); if ( table->nodes * 3 < table->size || table->size * 3 < table->nodes ) ft_mem_table_resize( table ); } } else ft_mem_debug_panic( "trying to free unknown block at %p in (%s:%ld)\n", address, FT_FILENAME( _ft_debug_file ), _ft_debug_lineno ); } }
static void ft_mem_table_set( FT_MemTable table, FT_Byte* address, FT_ULong size, FT_Long delta ) { FT_MemNode *pnode, node; if ( table ) { FT_MemSource source; pnode = ft_mem_table_get_nodep( table, address ); node = *pnode; if ( node ) { if ( node->size < 0 ) { /* This block was already freed. Our memory is now completely */ /* corrupted! */ /* This can only happen in keep-alive mode. */ ft_mem_debug_panic( "memory heap corrupted (allocating freed block)" ); } else { /* This block was already allocated. This means that our memory */ /* is also corrupted! */ ft_mem_debug_panic( "memory heap corrupted (re-allocating allocated block at" " %p, of size %ld)\n" "org=%s:%d new=%s:%d\n", node->address, node->size, FT_FILENAME( node->source->file_name ), node->source->line_no, FT_FILENAME( _ft_debug_file ), _ft_debug_lineno ); } } /* we need to create a new node in this table */ node = (FT_MemNode)ft_mem_table_alloc( table, sizeof ( *node ) ); if ( node == NULL ) ft_mem_debug_panic( "not enough memory to run memory tests" ); node->address = address; node->size = size; node->source = source = ft_mem_table_get_source( table ); if ( delta == 0 ) { /* this is an allocation */ source->all_blocks++; source->cur_blocks++; if ( source->cur_blocks > source->max_blocks ) source->max_blocks = source->cur_blocks; } if ( size > (FT_ULong)source->cur_max ) source->cur_max = size; if ( delta != 0 ) { /* we are growing or shrinking a reallocated block */ source->cur_size += delta; table->alloc_current += delta; } else { /* we are allocating a new block */ source->cur_size += size; table->alloc_current += size; } source->all_size += size; if ( source->cur_size > source->max_size ) source->max_size = source->cur_size; node->free_file_name = NULL; node->free_line_no = 0; node->link = pnode[0]; pnode[0] = node; table->nodes++; table->alloc_total += size; if ( table->alloc_current > table->alloc_max ) table->alloc_max = table->alloc_current; if ( table->nodes * 3 < table->size || table->size * 3 < table->nodes ) ft_mem_table_resize( table ); } }