Exemplo n.º 1
0
Arquivo: ftdbgmem.c Projeto: 93i/godot
  static void
  ft_mem_table_remove( FT_MemTable  table,
                       FT_Byte*     address,
                       FT_Long      delta )
  {
    if ( table )
    {
      FT_MemNode  *pnode, node;


      pnode = ft_mem_table_get_nodep( table, address );
      node  = *pnode;
      if ( node )
      {
        FT_MemSource  source;


        if ( node->size < 0 )
          ft_mem_debug_panic(
            "freeing memory block at %p more than once at (%s:%ld)\n"
            "block allocated at (%s:%ld) and released at (%s:%ld)",
            address,
            FT_FILENAME( _ft_debug_file ), _ft_debug_lineno,
            FT_FILENAME( node->source->file_name ), node->source->line_no,
            FT_FILENAME( node->free_file_name ), node->free_line_no );

        /* scramble the node's content for additional safety */
        FT_MEM_SET( address, 0xF3, node->size );

        if ( delta == 0 )
        {
          source = node->source;

          source->cur_blocks--;
          source->cur_size -= node->size;

          table->alloc_current -= node->size;
        }

        if ( table->keep_alive )
        {
          /* we simply invert the node's size to indicate that the node */
          /* was freed.                                                 */
          node->size           = -node->size;
          node->free_file_name = _ft_debug_file;
          node->free_line_no   = _ft_debug_lineno;
        }
        else
        {
          table->nodes--;

          *pnode = node->link;

          node->size   = 0;
          node->source = NULL;

          ft_mem_table_free( table, node );

          if ( table->nodes * 3 < table->size  ||
               table->size  * 3 < table->nodes )
            ft_mem_table_resize( table );
        }
      }
      else
        ft_mem_debug_panic(
          "trying to free unknown block at %p in (%s:%ld)\n",
          address,
          FT_FILENAME( _ft_debug_file ), _ft_debug_lineno );
    }
  }
Exemplo n.º 2
0
Arquivo: ftdbgmem.c Projeto: 93i/godot
  static void
  ft_mem_table_destroy( FT_MemTable  table )
  {
    FT_Long  i;
    FT_Long  leak_count = 0;
    FT_Long  leaks      = 0;


    FT_DumpMemory( table->memory );

    /* remove all blocks from the table, revealing leaked ones */
    for ( i = 0; i < table->size; i++ )
    {
      FT_MemNode  *pnode = table->buckets + i, next, node = *pnode;


      while ( node )
      {
        next       = node->link;
        node->link = NULL;

        if ( node->size > 0 )
        {
          printf(
            "leaked memory block at address %p, size %8ld in (%s:%ld)\n",
            (void*)node->address,
            node->size,
            FT_FILENAME( node->source->file_name ),
            node->source->line_no );

          leak_count++;
          leaks += node->size;

          ft_mem_table_free( table, node->address );
        }

        node->address = NULL;
        node->size    = 0;

        ft_mem_table_free( table, node );
        node = next;
      }
      table->buckets[i] = NULL;
    }

    ft_mem_table_free( table, table->buckets );
    table->buckets = NULL;

    table->size  = 0;
    table->nodes = 0;

    /* remove all sources */
    for ( i = 0; i < FT_MEM_SOURCE_BUCKETS; i++ )
    {
      FT_MemSource  source, next;


      for ( source = table->sources[i]; source != NULL; source = next )
      {
        next = source->link;
        ft_mem_table_free( table, source );
      }

      table->sources[i] = NULL;
    }

    printf( "FreeType: total memory allocations = %ld\n",
            table->alloc_total );
    printf( "FreeType: maximum memory footprint = %ld\n",
            table->alloc_max );

    ft_mem_table_free( table, table );

    if ( leak_count > 0 )
      ft_mem_debug_panic(
        "FreeType: %ld bytes of memory leaked in %ld blocks\n",
        leaks, leak_count );

    printf( "FreeType: no memory leaks detected\n" );
  }
Exemplo n.º 3
0
  extern void
  FT_DumpMemory( FT_Memory  memory )
  {
    FT_MemTable  table = (FT_MemTable)memory->user;


    if ( table )
    {
      FT_MemSource*  bucket = table->sources;
      FT_MemSource*  limit  = bucket + FT_MEM_SOURCE_BUCKETS;
      FT_MemSource*  sources;
      FT_UInt        nn, count;
      const char*    fmt;


      count = 0;
      for ( ; bucket < limit; bucket++ )
      {
        FT_MemSource  source = *bucket;


        for ( ; source; source = source->link )
          count++;
      }

      sources = (FT_MemSource*)ft_mem_table_alloc(
                                 table, sizeof ( *sources ) * count );

      count = 0;
      for ( bucket = table->sources; bucket < limit; bucket++ )
      {
        FT_MemSource  source = *bucket;


        for ( ; source; source = source->link )
          sources[count++] = source;
      }

      ft_qsort( sources, count, sizeof ( *sources ), ft_mem_source_compare );

      printf( "FreeType Memory Dump: "
              "current=%ld max=%ld total=%ld count=%ld\n",
              table->alloc_current, table->alloc_max,
              table->alloc_total, table->alloc_count );
      printf( " block  block    sizes    sizes    sizes   source\n" );
      printf( " count   high      sum  highsum      max   location\n" );
      printf( "-------------------------------------------------\n" );

      fmt = "%6ld %6ld %8ld %8ld %8ld %s:%d\n";

      for ( nn = 0; nn < count; nn++ )
      {
        FT_MemSource  source = sources[nn];


        printf( fmt,
                source->cur_blocks, source->max_blocks,
                source->cur_size, source->max_size, source->cur_max,
                FT_FILENAME( source->file_name ),
                source->line_no );
      }
      printf( "------------------------------------------------\n" );

      ft_mem_table_free( table, sources );
    }
  }
Exemplo n.º 4
0
  static void
  ft_mem_table_destroy( FT_MemTable  table )
  {
    FT_ULong  i;


    if ( table )
    {
      FT_Long    leak_count = 0;
      FT_ULong   leaks = 0;


      for ( i = 0; i < table->size; i++ )
      {
        FT_MemNode  *pnode = table->buckets + i, next, node = *pnode;


        while ( node )
        {
          next       = node->link;
          node->link = 0;

          if ( node->size > 0 )
          {
            printf(
              "leaked memory block at address %p, size %8ld in (%s:%ld)\n",
              node->address, node->size,
              FT_FILENAME( node->alloc_file_name ),
              node->alloc_line_no );

            leak_count++;
            leaks += node->size;

            ft_mem_table_free( table, node->address );
          }

          node->address = NULL;
          node->size    = 0;

          free( node );
          node = next;
        }
        table->buckets[i] = 0;
      }
      ft_mem_table_free( table, table->buckets );
      table->buckets = NULL;

      table->size   = 0;
      table->nodes  = 0;

      printf(
        "FreeType: total memory allocations = %ld\n", table->alloc_total );
      printf(
        "FreeType: maximum memory footprint = %ld\n", table->alloc_max );

      free( table );

      if ( leak_count > 0 )
        ft_mem_debug_panic(
          "FreeType: %ld bytes of memory leaked in %ld blocks\n",
          leaks, leak_count );
      printf( "FreeType: No memory leaks detected!\n" );
    }
  }
Exemplo n.º 5
0
  extern FT_Pointer
  ft_mem_debug_realloc( FT_Memory   memory,
                        FT_Long     cur_size,
                        FT_Long     new_size,
                        FT_Pointer  block )
  {
    FT_MemTable  table = (FT_MemTable)memory->user;
    FT_MemNode   node, *pnode;
    FT_Pointer   new_block;
    FT_Long      delta;

    const char*  file_name = FT_FILENAME( _ft_debug_file );
    FT_Long      line_no   = _ft_debug_lineno;


    /* unlikely, but possible */
    if ( new_size == cur_size )
      return block;

    /* the following is valid according to ANSI C */
#if 0
    if ( block == NULL || cur_size == 0 )
      ft_mem_debug_panic( "trying to reallocate NULL in (%s:%ld)",
                          file_name, line_no );
#endif

    /* while the following is allowed in ANSI C also, we abort since */
    /* such case should be handled by FreeType.                      */
    if ( new_size <= 0 )
      ft_mem_debug_panic(
        "trying to reallocate %p to size 0 (current is %ld) in (%s:%ld)",
        block, cur_size, file_name, line_no );

    /* check `cur_size' value */
    pnode = ft_mem_table_get_nodep( table, (FT_Byte*)block );
    node  = *pnode;
    if ( !node )
      ft_mem_debug_panic(
        "trying to reallocate unknown block at %p in (%s:%ld)",
        block, file_name, line_no );

    if ( node->size <= 0 )
      ft_mem_debug_panic(
        "trying to reallocate freed block at %p in (%s:%ld)",
        block, file_name, line_no );

    if ( node->size != cur_size )
      ft_mem_debug_panic( "invalid ft_realloc request for %p. cur_size is "
                          "%ld instead of %ld in (%s:%ld)",
                          block, cur_size, node->size, file_name, line_no );

    /* return NULL if the maximum number of allocations was reached */
    if ( table->bound_count                           &&
         table->alloc_count >= table->alloc_count_max )
      return NULL;

    delta = (FT_Long)( new_size - cur_size );

    /* return NULL if this allocation would overflow the maximum heap size */
    if ( delta > 0                                                       &&
         table->bound_total                                              &&
         table->alloc_current + (FT_ULong)delta > table->alloc_total_max )
      return NULL;

    new_block = (FT_Byte *)ft_mem_table_alloc( table, new_size );
    if ( new_block == NULL )
      return NULL;

    ft_mem_table_set( table, (FT_Byte*)new_block, new_size, delta );

    ft_memcpy( new_block, block, cur_size < new_size ? cur_size : new_size );

    ft_mem_table_remove( table, (FT_Byte*)block, delta );

    _ft_debug_file   = "<unknown>";
    _ft_debug_lineno = 0;

    if ( !table->keep_alive )
      ft_mem_table_free( table, block );

    return new_block;
  }