1049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/
2049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
3049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  ftdbgmem.c                                                             */
4049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
5049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*    Memory debugger (body).                                              */
6049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
70a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project/*  Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2009 by                  */
8049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
9049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
10049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  This file is part of the FreeType project, and may only be used,       */
11049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  modified, and distributed under the terms of the FreeType project      */
12049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
13049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  this file you indicate that you have read the license and              */
14049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  understand and accept it fully.                                        */
15049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
16049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/
17049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
18049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
19049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include <ft2build.h>
20049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_CONFIG_CONFIG_H
21049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_DEBUG_H
22049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_MEMORY_H
23049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_SYSTEM_H
24049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_ERRORS_H
25049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_TYPES_H
26049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
27049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
28049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef FT_DEBUG_MEMORY
29049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
30049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define  KEEPALIVE /* `Keep alive' means that freed blocks aren't released
31049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    * to the heap.  This is useful to detect double-frees
32049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    * or weird heap corruption, but it uses large amounts of
33049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    * memory, however.
34049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    */
35049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
360a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#include FT_CONFIG_STANDARD_LIBRARY_H
37049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
38049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( const char* )  _ft_debug_file   = 0;
39049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( long )         _ft_debug_lineno = 0;
40049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
41049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  extern void
42049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_DumpMemory( FT_Memory  memory );
43049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
44049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
45049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  typedef struct FT_MemSourceRec_*  FT_MemSource;
46049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  typedef struct FT_MemNodeRec_*    FT_MemNode;
47049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  typedef struct FT_MemTableRec_*   FT_MemTable;
48049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
49049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
507f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner#define FT_MEM_VAL( addr )  ((FT_PtrDist)(FT_Pointer)( addr ))
51049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
52049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*
53049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project   *  This structure holds statistics for a single allocation/release
54049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project   *  site.  This is useful to know where memory operations happen the
55049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project   *  most.
56049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project   */
57049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  typedef struct  FT_MemSourceRec_
58049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
59049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    const char*   file_name;
60049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    long          line_no;
61049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
62049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long       cur_blocks;   /* current number of allocated blocks */
63049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long       max_blocks;   /* max. number of allocated blocks    */
64049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long       all_blocks;   /* total number of blocks allocated   */
65049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
66049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long       cur_size;     /* current cumulative allocated size */
67049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long       max_size;     /* maximum cumulative allocated size */
68049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long       all_size;     /* total cumulative allocated size   */
69049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
70049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long       cur_max;      /* current maximum allocated size */
71049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
72049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt32     hash;
73049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_MemSource  link;
74049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
75049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  } FT_MemSourceRec;
76049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
77049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
78049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*
79049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project   *  We don't need a resizable array for the memory sources, because
80049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project   *  their number is pretty limited within FreeType.
81049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project   */
82049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_MEM_SOURCE_BUCKETS  128
83049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
84049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*
85049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project   *  This structure holds information related to a single allocated
86049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project   *  memory block.  If KEEPALIVE is defined, blocks that are freed by
87049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project   *  FreeType are never released to the system.  Instead, their `size'
88049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project   *  field is set to -size.  This is mainly useful to detect double frees,
89049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project   *  at the price of large memory footprint during execution.
90049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project   */
91049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  typedef struct  FT_MemNodeRec_
92049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
93049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*      address;
94049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long       size;     /* < 0 if the block was freed */
95049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
96049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_MemSource  source;
97049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
98049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef KEEPALIVE
99049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    const char*   free_file_name;
100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long       free_line_no;
101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_MemNode    link;
104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  } FT_MemNodeRec;
106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*
109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project   *  The global structure, containing compound statistics and all hash
110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project   *  tables.
111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project   */
112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  typedef struct  FT_MemTableRec_
113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong         size;
115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong         nodes;
116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_MemNode*      buckets;
117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong         alloc_total;
119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong         alloc_current;
120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong         alloc_max;
121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong         alloc_count;
122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Bool          bound_total;
124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong         alloc_total_max;
125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Bool          bound_count;
127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong         alloc_count_max;
128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_MemSource     sources[FT_MEM_SOURCE_BUCKETS];
130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Bool          keep_alive;
132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory        memory;
134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Pointer       memory_user;
135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Alloc_Func    alloc;
136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Free_Func     free;
137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Realloc_Func  realloc;
138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  } FT_MemTableRec;
140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_MEM_SIZE_MIN  7
143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_MEM_SIZE_MAX  13845163
144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_FILENAME( x )  ((x) ? (x) : "unknown file")
146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*
149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project   *  Prime numbers are ugly to handle.  It would be better to implement
150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project   *  L-Hashing, which is 10% faster and doesn't require divisions.
151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project   */
152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static const FT_UInt  ft_mem_primes[] =
153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    7,
155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    11,
156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    19,
157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    37,
158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    73,
159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    109,
160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    163,
161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    251,
162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    367,
163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    557,
164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    823,
165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    1237,
166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    1861,
167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    2777,
168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    4177,
169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    6247,
170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    9371,
171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    14057,
172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    21089,
173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    31627,
174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    47431,
175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    71143,
176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    106721,
177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    160073,
178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    240101,
179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    360163,
180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    540217,
181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    810343,
182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    1215497,
183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    1823231,
184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    2734867,
185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    4102283,
186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    6153409,
187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    9230113,
188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    13845163,
189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  };
190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_ULong
193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_mem_closest_prime( FT_ULong  num )
194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt  i;
196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( i = 0;
199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          i < sizeof ( ft_mem_primes ) / sizeof ( ft_mem_primes[0] ); i++ )
200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( ft_mem_primes[i] > num )
201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return ft_mem_primes[i];
202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_MEM_SIZE_MAX;
204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  extern void
208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_mem_debug_panic( const char*  fmt,
209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      ... )
210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    va_list  ap;
212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    printf( "FreeType.Debug: " );
215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    va_start( ap, fmt );
217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    vprintf( fmt, ap );
218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    va_end( ap );
219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    printf( "\n" );
221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    exit( EXIT_FAILURE );
222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Pointer
226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_mem_table_alloc( FT_MemTable  table,
227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Long      size )
228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory   memory = table->memory;
230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Pointer  block;
231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    memory->user = table->memory_user;
234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    block = table->alloc( memory, size );
235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    memory->user = table;
236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return block;
238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_mem_table_free( FT_MemTable  table,
243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Pointer   block )
244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory = table->memory;
246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    memory->user = table->memory_user;
249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    table->free( memory, block );
250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    memory->user = table;
251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_mem_table_resize( FT_MemTable  table )
256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong  new_size;
258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    new_size = ft_mem_closest_prime( table->nodes );
261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( new_size != table->size )
262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_MemNode*  new_buckets;
264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_ULong     i;
265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      new_buckets = (FT_MemNode *)
268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      ft_mem_table_alloc( table,
269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                          new_size * sizeof ( FT_MemNode ) );
270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( new_buckets == NULL )
271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return;
272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_ARRAY_ZERO( new_buckets, new_size );
274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( i = 0; i < table->size; i++ )
276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_MemNode  node, next, *pnode;
2787f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        FT_PtrDist  hash;
279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        node = table->buckets[i];
282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        while ( node )
283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          next  = node->link;
285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          hash  = FT_MEM_VAL( node->address ) % new_size;
286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          pnode = new_buckets + hash;
287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          node->link = pnode[0];
289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          pnode[0]   = node;
290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          node = next;
292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( table->buckets )
296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ft_mem_table_free( table, table->buckets );
297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      table->buckets = new_buckets;
299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      table->size    = new_size;
300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_MemTable
305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_mem_table_new( FT_Memory  memory )
306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_MemTable  table;
308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    table = (FT_MemTable)memory->alloc( memory, sizeof ( *table ) );
311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( table == NULL )
312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ZERO( table );
315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    table->size  = FT_MEM_SIZE_MIN;
317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    table->nodes = 0;
318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    table->memory = memory;
320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    table->memory_user = memory->user;
322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    table->alloc   = memory->alloc;
324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    table->realloc = memory->realloc;
325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    table->free    = memory->free;
326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    table->buckets = (FT_MemNode *)
328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                       memory->alloc( memory,
329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                      table->size * sizeof ( FT_MemNode ) );
330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( table->buckets )
331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_ARRAY_ZERO( table->buckets, table->size );
332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      memory->free( memory, table );
335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      table = NULL;
336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return table;
340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_mem_table_destroy( FT_MemTable  table )
345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong  i;
347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_DumpMemory( table->memory );
350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( table )
352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Long   leak_count = 0;
354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_ULong  leaks      = 0;
355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* remove all blocks from the table, revealing leaked ones */
358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( i = 0; i < table->size; i++ )
359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_MemNode  *pnode = table->buckets + i, next, node = *pnode;
361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        while ( node )
364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          next       = node->link;
366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          node->link = 0;
367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( node->size > 0 )
369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            printf(
371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              "leaked memory block at address %p, size %8ld in (%s:%ld)\n",
372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              node->address, node->size,
373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              FT_FILENAME( node->source->file_name ),
374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              node->source->line_no );
375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            leak_count++;
377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            leaks += node->size;
378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            ft_mem_table_free( table, node->address );
380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          node->address = NULL;
383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          node->size    = 0;
384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          ft_mem_table_free( table, node );
386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          node = next;
387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        table->buckets[i] = 0;
389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ft_mem_table_free( table, table->buckets );
392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      table->buckets = NULL;
393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      table->size  = 0;
395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      table->nodes = 0;
396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* remove all sources */
398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( i = 0; i < FT_MEM_SOURCE_BUCKETS; i++ )
399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_MemSource  source, next;
401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        for ( source = table->sources[i]; source != NULL; source = next )
404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          next = source->link;
406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          ft_mem_table_free( table, source );
407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        table->sources[i] = NULL;
410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      printf(
413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        "FreeType: total memory allocations = %ld\n", table->alloc_total );
414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      printf(
415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        "FreeType: maximum memory footprint = %ld\n", table->alloc_max );
416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ft_mem_table_free( table, table );
418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( leak_count > 0 )
420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ft_mem_debug_panic(
421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          "FreeType: %ld bytes of memory leaked in %ld blocks\n",
422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          leaks, leak_count );
423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
424295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      printf( "FreeType: no memory leaks detected\n" );
425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_MemNode*
430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_mem_table_get_nodep( FT_MemTable  table,
431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          FT_Byte*     address )
432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
4337f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner    FT_PtrDist   hash;
434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_MemNode  *pnode, node;
435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    hash  = FT_MEM_VAL( address );
438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pnode = table->buckets + ( hash % table->size );
439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for (;;)
441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      node = pnode[0];
443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !node )
444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( node->address == address )
447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      pnode = &node->link;
450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return pnode;
452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_MemSource
456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_mem_table_get_source( FT_MemTable  table )
457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt32     hash;
459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_MemSource  node, *pnode;
460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* cast to FT_PtrDist first since void* can be larger */
463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* than FT_UInt32 and GCC 4.1.1 emits a warning       */
464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    hash  = (FT_UInt32)(FT_PtrDist)(void*)_ft_debug_file +
465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              (FT_UInt32)( 5 * _ft_debug_lineno );
466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pnode = &table->sources[hash % FT_MEM_SOURCE_BUCKETS];
467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( ;; )
469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      node = *pnode;
471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( node == NULL )
472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( node->file_name == _ft_debug_file &&
475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           node->line_no   == _ft_debug_lineno   )
476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      pnode = &node->link;
479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    node = (FT_MemSource)ft_mem_table_alloc( table, sizeof ( *node ) );
482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( node == NULL )
483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ft_mem_debug_panic(
484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        "not enough memory to perform memory debugging\n" );
485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    node->file_name = _ft_debug_file;
487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    node->line_no   = _ft_debug_lineno;
488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    node->cur_blocks = 0;
490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    node->max_blocks = 0;
491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    node->all_blocks = 0;
492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    node->cur_size   = 0;
494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    node->max_size   = 0;
495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    node->all_size   = 0;
496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    node->cur_max    = 0;
498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    node->link = NULL;
500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    node->hash = hash;
501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *pnode     = node;
502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return node;
505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_mem_table_set( FT_MemTable  table,
510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_Byte*     address,
511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_ULong     size,
512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_Long      delta )
513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_MemNode  *pnode, node;
515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( table )
518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_MemSource  source;
520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      pnode = ft_mem_table_get_nodep( table, address );
523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      node  = *pnode;
524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( node )
525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( node->size < 0 )
527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* This block was already freed.  Our memory is now completely */
529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* corrupted!                                                  */
530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* This can only happen in keep-alive mode.                    */
531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          ft_mem_debug_panic(
532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            "memory heap corrupted (allocating freed block)" );
533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        else
535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
536049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* This block was already allocated.  This means that our memory */
537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* is also corrupted!                                            */
538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          ft_mem_debug_panic(
539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            "memory heap corrupted (re-allocating allocated block at"
540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            " %p, of size %ld)\n"
541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            "org=%s:%d new=%s:%d\n",
542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            node->address, node->size,
543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_FILENAME( node->source->file_name ), node->source->line_no,
544049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_FILENAME( _ft_debug_file ), _ft_debug_lineno );
545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* we need to create a new node in this table */
549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      node = (FT_MemNode)ft_mem_table_alloc( table, sizeof ( *node ) );
550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( node == NULL )
551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ft_mem_debug_panic( "not enough memory to run memory tests" );
552049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
553049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      node->address = address;
554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      node->size    = size;
555049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      node->source  = source = ft_mem_table_get_source( table );
556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( delta == 0 )
558049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
559049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* this is an allocation */
560049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        source->all_blocks++;
561049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        source->cur_blocks++;
562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( source->cur_blocks > source->max_blocks )
563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          source->max_blocks = source->cur_blocks;
564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( size > (FT_ULong)source->cur_max )
567049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        source->cur_max = size;
568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( delta != 0 )
570049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
571049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* we are growing or shrinking a reallocated block */
572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        source->cur_size     += delta;
573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        table->alloc_current += delta;
574049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* we are allocating a new block */
578049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        source->cur_size     += size;
579049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        table->alloc_current += size;
580049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
582049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      source->all_size += size;
583049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
584049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( source->cur_size > source->max_size )
585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        source->max_size = source->cur_size;
586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      node->free_file_name = NULL;
588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      node->free_line_no   = 0;
589049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      node->link = pnode[0];
591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      pnode[0] = node;
593049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      table->nodes++;
594049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      table->alloc_total += size;
596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( table->alloc_current > table->alloc_max )
598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        table->alloc_max = table->alloc_current;
599049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
600049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( table->nodes * 3 < table->size  ||
601049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           table->size  * 3 < table->nodes )
602049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ft_mem_table_resize( table );
603049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
604049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
605049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
606049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
607049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
608049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_mem_table_remove( FT_MemTable  table,
609049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                       FT_Byte*     address,
610049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                       FT_Long      delta )
611049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
612049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( table )
613049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
614049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_MemNode  *pnode, node;
615049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
616049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
617049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      pnode = ft_mem_table_get_nodep( table, address );
618049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      node  = *pnode;
619049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( node )
620049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
621049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_MemSource  source;
622049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
623049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
624049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( node->size < 0 )
625049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          ft_mem_debug_panic(
626049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            "freeing memory block at %p more than once at (%s:%ld)\n"
627049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            "block allocated at (%s:%ld) and released at (%s:%ld)",
628049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            address,
629049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_FILENAME( _ft_debug_file ), _ft_debug_lineno,
630049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_FILENAME( node->source->file_name ), node->source->line_no,
631049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_FILENAME( node->free_file_name ), node->free_line_no );
632049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
633049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* scramble the node's content for additional safety */
634049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_MEM_SET( address, 0xF3, node->size );
635049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
636049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( delta == 0 )
637049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
638049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          source = node->source;
639049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
640049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          source->cur_blocks--;
641049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          source->cur_size -= node->size;
642049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
643049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          table->alloc_current -= node->size;
644049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
645049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
646049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( table->keep_alive )
647049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
648049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* we simply invert the node's size to indicate that the node */
649049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* was freed.                                                 */
650049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          node->size           = -node->size;
651049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          node->free_file_name = _ft_debug_file;
652049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          node->free_line_no   = _ft_debug_lineno;
653049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
654049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        else
655049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
656049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          table->nodes--;
657049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
658049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          *pnode = node->link;
659049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
660049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          node->size   = 0;
661049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          node->source = NULL;
662049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
663049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          ft_mem_table_free( table, node );
664049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
665049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( table->nodes * 3 < table->size  ||
666049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               table->size  * 3 < table->nodes )
667049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            ft_mem_table_resize( table );
668049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
669049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
670049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
671049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ft_mem_debug_panic(
672049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          "trying to free unknown block at %p in (%s:%ld)\n",
673049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          address,
674049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_FILENAME( _ft_debug_file ), _ft_debug_lineno );
675049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
676049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
677049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
678049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
679049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  extern FT_Pointer
680049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_mem_debug_alloc( FT_Memory  memory,
681049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Long    size )
682049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
683049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_MemTable  table = (FT_MemTable)memory->user;
684049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*     block;
685049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
686049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
687049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( size <= 0 )
688049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ft_mem_debug_panic( "negative block size allocation (%ld)", size );
689049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
690049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* return NULL if the maximum number of allocations was reached */
691049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( table->bound_count                           &&
692049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         table->alloc_count >= table->alloc_count_max )
693049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return NULL;
694049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
695049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* return NULL if this allocation would overflow the maximum heap size */
696049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( table->bound_total                                             &&
697049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         table->alloc_total_max - table->alloc_current > (FT_ULong)size )
698049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return NULL;
699049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
700049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    block = (FT_Byte *)ft_mem_table_alloc( table, size );
701049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( block )
702049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
703049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ft_mem_table_set( table, block, (FT_ULong)size, 0 );
704049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
705049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      table->alloc_count++;
706049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
707049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
708049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    _ft_debug_file   = "<unknown>";
709049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    _ft_debug_lineno = 0;
710049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
711049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return (FT_Pointer)block;
712049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
713049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
714049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
715049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  extern void
716049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_mem_debug_free( FT_Memory   memory,
717049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Pointer  block )
718049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
719049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_MemTable  table = (FT_MemTable)memory->user;
720049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
721049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
722049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( block == NULL )
723049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ft_mem_debug_panic( "trying to free NULL in (%s:%ld)",
724049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          FT_FILENAME( _ft_debug_file ),
725049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          _ft_debug_lineno );
726049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
727049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ft_mem_table_remove( table, (FT_Byte*)block, 0 );
728049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
729049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !table->keep_alive )
730049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ft_mem_table_free( table, block );
731049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
732049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    table->alloc_count--;
733049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
734049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    _ft_debug_file   = "<unknown>";
735049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    _ft_debug_lineno = 0;
736049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
737049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
738049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
739049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  extern FT_Pointer
740049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_mem_debug_realloc( FT_Memory   memory,
741049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_Long     cur_size,
742049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_Long     new_size,
743049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_Pointer  block )
744049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
745049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_MemTable  table = (FT_MemTable)memory->user;
746049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_MemNode   node, *pnode;
747049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Pointer   new_block;
748049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long      delta;
749049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
750049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    const char*  file_name = FT_FILENAME( _ft_debug_file );
751049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long      line_no   = _ft_debug_lineno;
752049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
753049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
754049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* unlikely, but possible */
755049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( new_size == cur_size )
756049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return block;
757049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
758049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* the following is valid according to ANSI C */
759049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#if 0
760049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( block == NULL || cur_size == 0 )
761049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ft_mem_debug_panic( "trying to reallocate NULL in (%s:%ld)",
762049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          file_name, line_no );
763049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
764049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
765049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* while the following is allowed in ANSI C also, we abort since */
766049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* such case should be handled by FreeType.                      */
767049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( new_size <= 0 )
768049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ft_mem_debug_panic(
769049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        "trying to reallocate %p to size 0 (current is %ld) in (%s:%ld)",
770049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        block, cur_size, file_name, line_no );
771049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
772049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* check `cur_size' value */
773049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pnode = ft_mem_table_get_nodep( table, (FT_Byte*)block );
774049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    node  = *pnode;
775049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !node )
776049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ft_mem_debug_panic(
777049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        "trying to reallocate unknown block at %p in (%s:%ld)",
778049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        block, file_name, line_no );
779049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
780049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( node->size <= 0 )
781049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ft_mem_debug_panic(
782049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        "trying to reallocate freed block at %p in (%s:%ld)",
783049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        block, file_name, line_no );
784049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
785049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( node->size != cur_size )
786049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ft_mem_debug_panic( "invalid ft_realloc request for %p. cur_size is "
787049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          "%ld instead of %ld in (%s:%ld)",
788049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          block, cur_size, node->size, file_name, line_no );
789049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
790049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* return NULL if the maximum number of allocations was reached */
791049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( table->bound_count                           &&
792049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         table->alloc_count >= table->alloc_count_max )
793049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return NULL;
794049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
795049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    delta = (FT_Long)( new_size - cur_size );
796049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
797049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* return NULL if this allocation would overflow the maximum heap size */
798049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( delta > 0                                                       &&
799049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         table->bound_total                                              &&
800049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         table->alloc_current + (FT_ULong)delta > table->alloc_total_max )
801049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return NULL;
802049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
803049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    new_block = (FT_Byte *)ft_mem_table_alloc( table, new_size );
804049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( new_block == NULL )
805049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return NULL;
806049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
807049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ft_mem_table_set( table, (FT_Byte*)new_block, new_size, delta );
808049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
809049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ft_memcpy( new_block, block, cur_size < new_size ? cur_size : new_size );
810049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
811049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ft_mem_table_remove( table, (FT_Byte*)block, delta );
812049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
813049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    _ft_debug_file   = "<unknown>";
814049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    _ft_debug_lineno = 0;
815049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
816049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !table->keep_alive )
817049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ft_mem_table_free( table, block );
818049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
819049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return new_block;
820049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
821049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
822049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
823049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  extern FT_Int
824049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_mem_debug_init( FT_Memory  memory )
825049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
826049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_MemTable  table;
827049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int       result = 0;
828049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
829049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
830049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( getenv( "FT2_DEBUG_MEMORY" ) )
831049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
832049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      table = ft_mem_table_new( memory );
833049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( table )
834049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
835049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        const char*  p;
836049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
837049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
838049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        memory->user    = table;
839049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        memory->alloc   = ft_mem_debug_alloc;
840049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        memory->realloc = ft_mem_debug_realloc;
841049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        memory->free    = ft_mem_debug_free;
842049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
843049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        p = getenv( "FT2_ALLOC_TOTAL_MAX" );
844049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( p != NULL )
845049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
846049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_Long   total_max = ft_atol( p );
847049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
848049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
849049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( total_max > 0 )
850049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
851049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            table->bound_total     = 1;
852049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            table->alloc_total_max = (FT_ULong)total_max;
853049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
854049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
855049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
856049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        p = getenv( "FT2_ALLOC_COUNT_MAX" );
857049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( p != NULL )
858049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
859049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_Long  total_count = ft_atol( p );
860049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
861049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
862049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( total_count > 0 )
863049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
864049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            table->bound_count     = 1;
865049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            table->alloc_count_max = (FT_ULong)total_count;
866049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
867049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
868049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
869049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        p = getenv( "FT2_KEEP_ALIVE" );
870049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( p != NULL )
871049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
872049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_Long  keep_alive = ft_atol( p );
873049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
874049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
875049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( keep_alive > 0 )
876049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            table->keep_alive = 1;
877049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
878049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
879049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = 1;
880049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
881049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
882049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
883049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
884049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
885049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
886049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  extern void
887049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_mem_debug_done( FT_Memory  memory )
888049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
889049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_MemTable  table = (FT_MemTable)memory->user;
890049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
891049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
892049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( table )
893049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
894049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      memory->free    = table->free;
895049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      memory->realloc = table->realloc;
896049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      memory->alloc   = table->alloc;
897049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
898049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ft_mem_table_destroy( table );
899049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      memory->user = NULL;
900049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
901049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
902049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
903049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
904049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
905049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static int
906049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_mem_source_compare( const void*  p1,
907049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         const void*  p2 )
908049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
909049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_MemSource  s1 = *(FT_MemSource*)p1;
910049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_MemSource  s2 = *(FT_MemSource*)p2;
911049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
912049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
913049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( s2->max_size > s1->max_size )
914049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return 1;
915049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( s2->max_size < s1->max_size )
916049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return -1;
917049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
918049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return 0;
919049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
920049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
921049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
922049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  extern void
923049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_DumpMemory( FT_Memory  memory )
924049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
925049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_MemTable  table = (FT_MemTable)memory->user;
926049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
927049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
928049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( table )
929049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
930049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_MemSource*  bucket = table->sources;
931049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_MemSource*  limit  = bucket + FT_MEM_SOURCE_BUCKETS;
932049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_MemSource*  sources;
933049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_UInt        nn, count;
934049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      const char*    fmt;
935049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
936049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
937049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      count = 0;
938049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( ; bucket < limit; bucket++ )
939049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
940049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_MemSource  source = *bucket;
941049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
942049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
943049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        for ( ; source; source = source->link )
944049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          count++;
945049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
946049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
947049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      sources = (FT_MemSource*)ft_mem_table_alloc(
948049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                 table, sizeof ( *sources ) * count );
949049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
950049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      count = 0;
951049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( bucket = table->sources; bucket < limit; bucket++ )
952049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
953049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_MemSource  source = *bucket;
954049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
955049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
956049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        for ( ; source; source = source->link )
957049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          sources[count++] = source;
958049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
959049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
960049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ft_qsort( sources, count, sizeof ( *sources ), ft_mem_source_compare );
961049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
962049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      printf( "FreeType Memory Dump: "
963049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              "current=%ld max=%ld total=%ld count=%ld\n",
964049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              table->alloc_current, table->alloc_max,
965049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              table->alloc_total, table->alloc_count );
966049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      printf( " block  block    sizes    sizes    sizes   source\n" );
967049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      printf( " count   high      sum  highsum      max   location\n" );
968049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      printf( "-------------------------------------------------\n" );
969049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
970049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      fmt = "%6ld %6ld %8ld %8ld %8ld %s:%d\n";
971049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
972049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( nn = 0; nn < count; nn++ )
973049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
974049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_MemSource  source = sources[nn];
975049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
976049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
977049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        printf( fmt,
978049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                source->cur_blocks, source->max_blocks,
979049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                source->cur_size, source->max_size, source->cur_max,
980049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                FT_FILENAME( source->file_name ),
981049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                source->line_no );
982049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
983049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      printf( "------------------------------------------------\n" );
984049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
985049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ft_mem_table_free( table, sources );
986049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
987049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
988049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
989049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else  /* !FT_DEBUG_MEMORY */
990049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
991049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* ANSI C doesn't like empty source files */
992295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner  typedef int  _debug_mem_dummy;
993049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
994049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* !FT_DEBUG_MEMORY */
995049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
996049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
997049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* END */
998