1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/***************************************************************************/ 2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* ftdbgmem.c */ 4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* Memory debugger (body). */ 6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 7ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann/* Copyright 2001-2015 by */ 8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* David Turner, Robert Wilhelm, and Werner Lemberg. */ 9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* This file is part of the FreeType project, and may only be used, */ 11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* modified, and distributed under the terms of the FreeType project */ 12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* this file you indicate that you have read the license and */ 14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* understand and accept it fully. */ 15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/***************************************************************************/ 17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 19e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include <ft2build.h> 20e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include FT_CONFIG_CONFIG_H 21e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include FT_INTERNAL_DEBUG_H 22e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include FT_INTERNAL_MEMORY_H 23e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include FT_SYSTEM_H 24e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include FT_ERRORS_H 25e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include FT_TYPES_H 26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_DEBUG_MEMORY 29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define KEEPALIVE /* `Keep alive' means that freed blocks aren't released 31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * to the heap. This is useful to detect double-frees 32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * or weird heap corruption, but it uses large amounts of 33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * memory, however. 34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 36e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include FT_CONFIG_STANDARD_LIBRARY_H 37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 38ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FT_BASE_DEF( const char* ) _ft_debug_file = NULL; 39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( long ) _ft_debug_lineno = 0; 40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov extern void 42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_DumpMemory( FT_Memory memory ); 43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef struct FT_MemSourceRec_* FT_MemSource; 46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef struct FT_MemNodeRec_* FT_MemNode; 47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef struct FT_MemTableRec_* FT_MemTable; 48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 50ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#define FT_MEM_VAL( addr ) ( (FT_PtrDist)(FT_Pointer)( addr ) ) 51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* 53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * This structure holds statistics for a single allocation/release 54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * site. This is useful to know where memory operations happen the 55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * most. 56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef struct FT_MemSourceRec_ 58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const char* file_name; 60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov long line_no; 61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long cur_blocks; /* current number of allocated blocks */ 63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long max_blocks; /* max. number of allocated blocks */ 64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long all_blocks; /* total number of blocks allocated */ 65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long cur_size; /* current cumulative allocated size */ 67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long max_size; /* maximum cumulative allocated size */ 68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long all_size; /* total cumulative allocated size */ 69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long cur_max; /* current maximum allocated size */ 71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 hash; 73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MemSource link; 74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } FT_MemSourceRec; 76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* 79ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * We don't need a resizable array for the memory sources because 80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * their number is pretty limited within FreeType. 81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_MEM_SOURCE_BUCKETS 128 83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* 85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * This structure holds information related to a single allocated 86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * memory block. If KEEPALIVE is defined, blocks that are freed by 87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * FreeType are never released to the system. Instead, their `size' 88ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * field is set to `-size'. This is mainly useful to detect double 89ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * frees, at the price of a large memory footprint during execution. 90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef struct FT_MemNodeRec_ 92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* address; 94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long size; /* < 0 if the block was freed */ 95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MemSource source; 97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef KEEPALIVE 99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const char* free_file_name; 100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long free_line_no; 101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MemNode link; 104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } FT_MemNodeRec; 106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* 109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * The global structure, containing compound statistics and all hash 110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * tables. 111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef struct FT_MemTableRec_ 113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 114ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FT_Long size; 115ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FT_Long nodes; 116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MemNode* buckets; 117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 118ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FT_Long alloc_total; 119ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FT_Long alloc_current; 120ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FT_Long alloc_max; 121ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FT_Long alloc_count; 122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bool bound_total; 124ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FT_Long alloc_total_max; 125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bool bound_count; 127ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FT_Long alloc_count_max; 128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MemSource sources[FT_MEM_SOURCE_BUCKETS]; 130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bool keep_alive; 132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory; 134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Pointer memory_user; 135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Alloc_Func alloc; 136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Free_Func free; 137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Realloc_Func realloc; 138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } FT_MemTableRec; 140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_MEM_SIZE_MIN 7 143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_MEM_SIZE_MAX 13845163 144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 145ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#define FT_FILENAME( x ) ( (x) ? (x) : "unknown file" ) 146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* 149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Prime numbers are ugly to handle. It would be better to implement 150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * L-Hashing, which is 10% faster and doesn't require divisions. 151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 152ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann static const FT_Int ft_mem_primes[] = 153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 7, 155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 11, 156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 19, 157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 37, 158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 73, 159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 109, 160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 163, 161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 251, 162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 367, 163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 557, 164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 823, 165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1237, 166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1861, 167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2777, 168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4177, 169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 6247, 170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 9371, 171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 14057, 172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 21089, 173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 31627, 174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 47431, 175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 71143, 176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 106721, 177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 160073, 178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 240101, 179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 360163, 180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 540217, 181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 810343, 182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1215497, 183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1823231, 184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2734867, 185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4102283, 186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 6153409, 187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 9230113, 188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 13845163, 189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov }; 190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 192ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann static FT_Long 193ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann ft_mem_closest_prime( FT_Long num ) 194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 195ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann size_t i; 196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( i = 0; 199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov i < sizeof ( ft_mem_primes ) / sizeof ( ft_mem_primes[0] ); i++ ) 200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ft_mem_primes[i] > num ) 201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return ft_mem_primes[i]; 202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_MEM_SIZE_MAX; 204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 207ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann static void 208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_debug_panic( const char* fmt, 209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ... ) 210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov va_list ap; 212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov printf( "FreeType.Debug: " ); 215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov va_start( ap, fmt ); 217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov vprintf( fmt, ap ); 218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov va_end( ap ); 219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov printf( "\n" ); 221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov exit( EXIT_FAILURE ); 222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Pointer 226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_table_alloc( FT_MemTable table, 227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long size ) 228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = table->memory; 230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Pointer block; 231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memory->user = table->memory_user; 234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov block = table->alloc( memory, size ); 235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memory->user = table; 236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return block; 238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_table_free( FT_MemTable table, 243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Pointer block ) 244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = table->memory; 246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memory->user = table->memory_user; 249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->free( memory, block ); 250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memory->user = table; 251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_table_resize( FT_MemTable table ) 256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 257ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FT_Long new_size; 258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov new_size = ft_mem_closest_prime( table->nodes ); 261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( new_size != table->size ) 262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MemNode* new_buckets; 264ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FT_Long i; 265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov new_buckets = (FT_MemNode *) 268ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann ft_mem_table_alloc( 269ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann table, 270ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann new_size * (FT_Long)sizeof ( FT_MemNode ) ); 271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( new_buckets == NULL ) 272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ARRAY_ZERO( new_buckets, new_size ); 275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( i = 0; i < table->size; i++ ) 277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MemNode node, next, *pnode; 279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_PtrDist hash; 280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node = table->buckets[i]; 283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( node ) 284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov next = node->link; 286ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann hash = FT_MEM_VAL( node->address ) % (FT_PtrDist)new_size; 287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pnode = new_buckets + hash; 288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node->link = pnode[0]; 290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pnode[0] = node; 291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node = next; 293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( table->buckets ) 297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_table_free( table, table->buckets ); 298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->buckets = new_buckets; 300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->size = new_size; 301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_MemTable 306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_table_new( FT_Memory memory ) 307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MemTable table; 309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table = (FT_MemTable)memory->alloc( memory, sizeof ( *table ) ); 312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( table == NULL ) 313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ZERO( table ); 316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->size = FT_MEM_SIZE_MIN; 318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->nodes = 0; 319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->memory = memory; 321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->memory_user = memory->user; 323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->alloc = memory->alloc; 325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->realloc = memory->realloc; 326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->free = memory->free; 327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->buckets = (FT_MemNode *) 329ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann memory->alloc( 330ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann memory, 331ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann table->size * (FT_Long)sizeof ( FT_MemNode ) ); 332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( table->buckets ) 333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ARRAY_ZERO( table->buckets, table->size ); 334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memory->free( memory, table ); 337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table = NULL; 338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return table; 342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_table_destroy( FT_MemTable table ) 347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 348ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FT_Long i; 349ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FT_Long leak_count = 0; 350ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FT_Long leaks = 0; 351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_DumpMemory( table->memory ); 354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* remove all blocks from the table, revealing leaked ones */ 356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( i = 0; i < table->size; i++ ) 357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MemNode *pnode = table->buckets + i, next, node = *pnode; 359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( node ) 362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov next = node->link; 364ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann node->link = NULL; 365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( node->size > 0 ) 367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov printf( 369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov "leaked memory block at address %p, size %8ld in (%s:%ld)\n", 370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node->address, node->size, 371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FILENAME( node->source->file_name ), 372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node->source->line_no ); 373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov leak_count++; 375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov leaks += node->size; 376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_table_free( table, node->address ); 378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node->address = NULL; 381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node->size = 0; 382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_table_free( table, node ); 384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node = next; 385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 386ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann table->buckets[i] = NULL; 387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_table_free( table, table->buckets ); 390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->buckets = NULL; 391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->size = 0; 393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->nodes = 0; 394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* remove all sources */ 396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( i = 0; i < FT_MEM_SOURCE_BUCKETS; i++ ) 397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MemSource source, next; 399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( source = table->sources[i]; source != NULL; source = next ) 402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov next = source->link; 404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_table_free( table, source ); 405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->sources[i] = NULL; 408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov printf( "FreeType: total memory allocations = %ld\n", 411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->alloc_total ); 412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov printf( "FreeType: maximum memory footprint = %ld\n", 413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->alloc_max ); 414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_table_free( table, table ); 416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( leak_count > 0 ) 418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_debug_panic( 419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov "FreeType: %ld bytes of memory leaked in %ld blocks\n", 420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov leaks, leak_count ); 421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov printf( "FreeType: no memory leaks detected\n" ); 423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_MemNode* 427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_table_get_nodep( FT_MemTable table, 428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* address ) 429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_PtrDist hash; 431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MemNode *pnode, node; 432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov hash = FT_MEM_VAL( address ); 435ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann pnode = table->buckets + ( hash % (FT_PtrDist)table->size ); 436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (;;) 438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node = pnode[0]; 440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !node ) 441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( node->address == address ) 444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pnode = &node->link; 447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return pnode; 449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_MemSource 453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_table_get_source( FT_MemTable table ) 454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 hash; 456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MemSource node, *pnode; 457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* cast to FT_PtrDist first since void* can be larger */ 460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* than FT_UInt32 and GCC 4.1.1 emits a warning */ 461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov hash = (FT_UInt32)(FT_PtrDist)(void*)_ft_debug_file + 462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_UInt32)( 5 * _ft_debug_lineno ); 463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pnode = &table->sources[hash % FT_MEM_SOURCE_BUCKETS]; 464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( ;; ) 466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node = *pnode; 468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( node == NULL ) 469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 471ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ( node->file_name == _ft_debug_file && 472ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann node->line_no == _ft_debug_lineno ) 473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pnode = &node->link; 476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node = (FT_MemSource)ft_mem_table_alloc( table, sizeof ( *node ) ); 479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( node == NULL ) 480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_debug_panic( 481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov "not enough memory to perform memory debugging\n" ); 482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node->file_name = _ft_debug_file; 484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node->line_no = _ft_debug_lineno; 485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node->cur_blocks = 0; 487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node->max_blocks = 0; 488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node->all_blocks = 0; 489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 490ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann node->cur_size = 0; 491ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann node->max_size = 0; 492ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann node->all_size = 0; 493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 494ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann node->cur_max = 0; 495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node->link = NULL; 497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node->hash = hash; 498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *pnode = node; 499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return node; 502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_table_set( FT_MemTable table, 507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* address, 508ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FT_Long size, 509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long delta ) 510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MemNode *pnode, node; 512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( table ) 515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MemSource source; 517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pnode = ft_mem_table_get_nodep( table, address ); 520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node = *pnode; 521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( node ) 522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( node->size < 0 ) 524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* This block was already freed. Our memory is now completely */ 526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* corrupted! */ 527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* This can only happen in keep-alive mode. */ 528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_debug_panic( 529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov "memory heap corrupted (allocating freed block)" ); 530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* This block was already allocated. This means that our memory */ 534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* is also corrupted! */ 535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_debug_panic( 536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov "memory heap corrupted (re-allocating allocated block at" 537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " %p, of size %ld)\n" 538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov "org=%s:%d new=%s:%d\n", 539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node->address, node->size, 540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FILENAME( node->source->file_name ), node->source->line_no, 541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FILENAME( _ft_debug_file ), _ft_debug_lineno ); 542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* we need to create a new node in this table */ 546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node = (FT_MemNode)ft_mem_table_alloc( table, sizeof ( *node ) ); 547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( node == NULL ) 548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_debug_panic( "not enough memory to run memory tests" ); 549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node->address = address; 551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node->size = size; 552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node->source = source = ft_mem_table_get_source( table ); 553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( delta == 0 ) 555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* this is an allocation */ 557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov source->all_blocks++; 558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov source->cur_blocks++; 559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( source->cur_blocks > source->max_blocks ) 560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov source->max_blocks = source->cur_blocks; 561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 563ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ( size > source->cur_max ) 564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov source->cur_max = size; 565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( delta != 0 ) 567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* we are growing or shrinking a reallocated block */ 569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov source->cur_size += delta; 570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->alloc_current += delta; 571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* we are allocating a new block */ 575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov source->cur_size += size; 576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->alloc_current += size; 577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov source->all_size += size; 580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( source->cur_size > source->max_size ) 582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov source->max_size = source->cur_size; 583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node->free_file_name = NULL; 585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node->free_line_no = 0; 586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node->link = pnode[0]; 588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pnode[0] = node; 590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->nodes++; 591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->alloc_total += size; 593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( table->alloc_current > table->alloc_max ) 595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->alloc_max = table->alloc_current; 596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( table->nodes * 3 < table->size || 598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->size * 3 < table->nodes ) 599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_table_resize( table ); 600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_table_remove( FT_MemTable table, 606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* address, 607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long delta ) 608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( table ) 610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MemNode *pnode, node; 612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pnode = ft_mem_table_get_nodep( table, address ); 615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node = *pnode; 616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( node ) 617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MemSource source; 619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( node->size < 0 ) 622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_debug_panic( 623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov "freeing memory block at %p more than once at (%s:%ld)\n" 624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov "block allocated at (%s:%ld) and released at (%s:%ld)", 625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov address, 626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FILENAME( _ft_debug_file ), _ft_debug_lineno, 627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FILENAME( node->source->file_name ), node->source->line_no, 628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FILENAME( node->free_file_name ), node->free_line_no ); 629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* scramble the node's content for additional safety */ 631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MEM_SET( address, 0xF3, node->size ); 632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( delta == 0 ) 634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov source = node->source; 636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov source->cur_blocks--; 638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov source->cur_size -= node->size; 639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->alloc_current -= node->size; 641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( table->keep_alive ) 644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* we simply invert the node's size to indicate that the node */ 646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* was freed. */ 647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node->size = -node->size; 648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node->free_file_name = _ft_debug_file; 649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node->free_line_no = _ft_debug_lineno; 650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->nodes--; 654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *pnode = node->link; 656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node->size = 0; 658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node->source = NULL; 659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_table_free( table, node ); 661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 662ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( table->nodes * 3 < table->size || 663ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->size * 3 < table->nodes ) 664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_table_resize( table ); 665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_debug_panic( 669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov "trying to free unknown block at %p in (%s:%ld)\n", 670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov address, 671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FILENAME( _ft_debug_file ), _ft_debug_lineno ); 672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 676ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann static FT_Pointer 677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_debug_alloc( FT_Memory memory, 678ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long size ) 679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MemTable table = (FT_MemTable)memory->user; 681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* block; 682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( size <= 0 ) 685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_debug_panic( "negative block size allocation (%ld)", size ); 686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* return NULL if the maximum number of allocations was reached */ 688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( table->bound_count && 689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->alloc_count >= table->alloc_count_max ) 690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* return NULL if this allocation would overflow the maximum heap size */ 693ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ( table->bound_total && 694ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann table->alloc_total_max - table->alloc_current > size ) 695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 696ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 697ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov block = (FT_Byte *)ft_mem_table_alloc( table, size ); 698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( block ) 699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 700ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann ft_mem_table_set( table, block, size, 0 ); 701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->alloc_count++; 703ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _ft_debug_file = "<unknown>"; 706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _ft_debug_lineno = 0; 707ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (FT_Pointer)block; 709ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 712ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann static void 713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_debug_free( FT_Memory memory, 714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Pointer block ) 715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MemTable table = (FT_MemTable)memory->user; 717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( block == NULL ) 720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_debug_panic( "trying to free NULL in (%s:%ld)", 721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FILENAME( _ft_debug_file ), 722ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _ft_debug_lineno ); 723ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 724ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_table_remove( table, (FT_Byte*)block, 0 ); 725ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 726ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !table->keep_alive ) 727ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_table_free( table, block ); 728ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 729ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->alloc_count--; 730ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 731ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _ft_debug_file = "<unknown>"; 732ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _ft_debug_lineno = 0; 733ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 734ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 735ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 736ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann static FT_Pointer 737ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_debug_realloc( FT_Memory memory, 738ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long cur_size, 739ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long new_size, 740ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Pointer block ) 741ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 742ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MemTable table = (FT_MemTable)memory->user; 743ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MemNode node, *pnode; 744ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Pointer new_block; 745ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long delta; 746ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 747ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const char* file_name = FT_FILENAME( _ft_debug_file ); 748ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long line_no = _ft_debug_lineno; 749ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 750ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 751ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* unlikely, but possible */ 752ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( new_size == cur_size ) 753ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return block; 754ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 755ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* the following is valid according to ANSI C */ 756ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if 0 757ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( block == NULL || cur_size == 0 ) 758ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_debug_panic( "trying to reallocate NULL in (%s:%ld)", 759ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov file_name, line_no ); 760ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 761ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 762ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* while the following is allowed in ANSI C also, we abort since */ 763ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* such case should be handled by FreeType. */ 764ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( new_size <= 0 ) 765ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_debug_panic( 766ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov "trying to reallocate %p to size 0 (current is %ld) in (%s:%ld)", 767ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov block, cur_size, file_name, line_no ); 768ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 769ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check `cur_size' value */ 770ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pnode = ft_mem_table_get_nodep( table, (FT_Byte*)block ); 771ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node = *pnode; 772ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !node ) 773ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_debug_panic( 774ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov "trying to reallocate unknown block at %p in (%s:%ld)", 775ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov block, file_name, line_no ); 776ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 777ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( node->size <= 0 ) 778ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_debug_panic( 779ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov "trying to reallocate freed block at %p in (%s:%ld)", 780ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov block, file_name, line_no ); 781ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 782ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( node->size != cur_size ) 783ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_debug_panic( "invalid ft_realloc request for %p. cur_size is " 784ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov "%ld instead of %ld in (%s:%ld)", 785ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov block, cur_size, node->size, file_name, line_no ); 786ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 787ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* return NULL if the maximum number of allocations was reached */ 788ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( table->bound_count && 789ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->alloc_count >= table->alloc_count_max ) 790ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 791ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 792ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann delta = new_size - cur_size; 793ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 794ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* return NULL if this allocation would overflow the maximum heap size */ 795ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ( delta > 0 && 796ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann table->bound_total && 797ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann table->alloc_current + delta > table->alloc_total_max ) 798ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 799ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 800ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann new_block = (FT_Pointer)ft_mem_table_alloc( table, new_size ); 801ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( new_block == NULL ) 802ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 803ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 804ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_table_set( table, (FT_Byte*)new_block, new_size, delta ); 805ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 806ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann ft_memcpy( new_block, block, cur_size < new_size ? (size_t)cur_size 807ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann : (size_t)new_size ); 808ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 809ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_table_remove( table, (FT_Byte*)block, delta ); 810ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 811ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _ft_debug_file = "<unknown>"; 812ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _ft_debug_lineno = 0; 813ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 814ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !table->keep_alive ) 815ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_table_free( table, block ); 816ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 817ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return new_block; 818ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 819ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 820ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 821ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov extern FT_Int 822ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_debug_init( FT_Memory memory ) 823ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 824ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MemTable table; 825ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int result = 0; 826ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 827ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 828e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if ( getenv( "FT2_DEBUG_MEMORY" ) ) 829ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 830ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table = ft_mem_table_new( memory ); 831ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( table ) 832ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 833ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const char* p; 834ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 835ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 836ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memory->user = table; 837ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memory->alloc = ft_mem_debug_alloc; 838ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memory->realloc = ft_mem_debug_realloc; 839ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memory->free = ft_mem_debug_free; 840ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 841ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = getenv( "FT2_ALLOC_TOTAL_MAX" ); 842ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( p != NULL ) 843ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 844ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long total_max = ft_atol( p ); 845ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 846ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 847ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( total_max > 0 ) 848ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 849ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->bound_total = 1; 850ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann table->alloc_total_max = total_max; 851ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 852ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 853ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 854ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = getenv( "FT2_ALLOC_COUNT_MAX" ); 855ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( p != NULL ) 856ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 857ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long total_count = ft_atol( p ); 858ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 859ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 860ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( total_count > 0 ) 861ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 862ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->bound_count = 1; 863ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann table->alloc_count_max = total_count; 864ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 865ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 866ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 867ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = getenv( "FT2_KEEP_ALIVE" ); 868ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( p != NULL ) 869ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 870ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long keep_alive = ft_atol( p ); 871ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 872ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 873ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( keep_alive > 0 ) 874ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->keep_alive = 1; 875ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 876ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 877ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = 1; 878ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 879ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 880ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return result; 881ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 882ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 883ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 884ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov extern void 885ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_debug_done( FT_Memory memory ) 886ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 887ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MemTable table = (FT_MemTable)memory->user; 888ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 889ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 890ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( table ) 891ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 892ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memory->free = table->free; 893ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memory->realloc = table->realloc; 894ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memory->alloc = table->alloc; 895ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 896ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_table_destroy( table ); 897ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memory->user = NULL; 898ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 899ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 900ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 901ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 902ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static int 903ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_source_compare( const void* p1, 904ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const void* p2 ) 905ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 906ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MemSource s1 = *(FT_MemSource*)p1; 907ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MemSource s2 = *(FT_MemSource*)p2; 908ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 909ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 910ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( s2->max_size > s1->max_size ) 911ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 1; 912ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( s2->max_size < s1->max_size ) 913ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return -1; 914ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 915ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 0; 916ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 917ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 918ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 919ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov extern void 920ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_DumpMemory( FT_Memory memory ) 921ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 922ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MemTable table = (FT_MemTable)memory->user; 923ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 924ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 925ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( table ) 926ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 927ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MemSource* bucket = table->sources; 928ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MemSource* limit = bucket + FT_MEM_SOURCE_BUCKETS; 929ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MemSource* sources; 930ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FT_Int nn, count; 931ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const char* fmt; 932ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 933ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 934ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov count = 0; 935ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( ; bucket < limit; bucket++ ) 936ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 937ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MemSource source = *bucket; 938ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 939ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 940ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( ; source; source = source->link ) 941ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov count++; 942ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 943ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 944ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann sources = (FT_MemSource*) 945ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann ft_mem_table_alloc( 946ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann table, count * (FT_Long)sizeof ( *sources ) ); 947ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 948ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov count = 0; 949ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( bucket = table->sources; bucket < limit; bucket++ ) 950ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 951ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MemSource source = *bucket; 952ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 953ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 954ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( ; source; source = source->link ) 955ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov sources[count++] = source; 956ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 957ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 958ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann ft_qsort( sources, 959ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann (size_t)count, 960ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann sizeof ( *sources ), 961ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann ft_mem_source_compare ); 962ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 963ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov printf( "FreeType Memory Dump: " 964ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov "current=%ld max=%ld total=%ld count=%ld\n", 965ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->alloc_current, table->alloc_max, 966ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table->alloc_total, table->alloc_count ); 967ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov printf( " block block sizes sizes sizes source\n" ); 968ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov printf( " count high sum highsum max location\n" ); 969ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov printf( "-------------------------------------------------\n" ); 970ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 971ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov fmt = "%6ld %6ld %8ld %8ld %8ld %s:%d\n"; 972ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 973ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( nn = 0; nn < count; nn++ ) 974ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 975ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MemSource source = sources[nn]; 976ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 977ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 978ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov printf( fmt, 979ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov source->cur_blocks, source->max_blocks, 980ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov source->cur_size, source->max_size, source->cur_max, 981ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FILENAME( source->file_name ), 982ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov source->line_no ); 983ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 984ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov printf( "------------------------------------------------\n" ); 985ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 986ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_table_free( table, sources ); 987ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 988ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 989ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 990ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else /* !FT_DEBUG_MEMORY */ 991ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 992ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* ANSI C doesn't like empty source files */ 993ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef int _debug_mem_dummy; 994ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 995ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* !FT_DEBUG_MEMORY */ 996ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 997ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 998ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* END */ 999