コード例 #1
0
ファイル: ftdbgmem.c プロジェクト: allanw1/Arianrhod
  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;

    const char*  file_name = FT_FILENAME( table->file_name );
    FT_Long      line_no   = table->line_no;


    /* 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 );

    new_block = ft_mem_debug_alloc( memory, new_size );
    if ( new_block == NULL )
      return NULL;

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

    table->file_name = file_name;
    table->line_no   = line_no;

    ft_mem_debug_free( memory, (FT_Byte*)block );

    return new_block;
  }
コード例 #2
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;

    const char*  file_name = FT_FILENAME( table->file_name );
    FT_Long      line_no   = table->line_no;


    if ( block == NULL || cur_size == 0 )
        ft_mem_debug_panic( "trying to reallocate NULL in (%s:%ld)",
                            file_name, line_no );

    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 );

    new_block = ft_mem_debug_alloc( memory, new_size );
    if ( new_block == NULL )
        return NULL;

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

    table->file_name = file_name;
    table->line_no   = line_no;

    ft_mem_debug_free( memory, (FT_Byte*)block );

    return new_block;
}
コード例 #3
0
static void
ft_mem_table_remove( FT_MemTable  table,
                     FT_Byte*     address )
{
    if ( table )
    {
        FT_MemNode  *pnode, node;


        pnode = ft_mem_table_get_nodep( table, address );
        node  = *pnode;
        if ( node )
        {
            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( table->file_name ), table->line_no,
                    FT_FILENAME( node->alloc_file_name ), node->alloc_line_no,
                    FT_FILENAME( node->free_file_name ), node->free_line_no );

            /* we simply invert the node's size to indicate that the node */
            /* was freed.  We also change its contents.                   */
            FT_MEM_SET( address, 0xF3, node->size );

            table->alloc_current -= node->size;
            node->size            = -node->size;
            node->free_file_name  = table->file_name;
            node->free_line_no    = table->line_no;
        }
        else
            ft_mem_debug_panic(
                "trying to free unknown block at %p in (%s:%ld)\n",
                address,
                FT_FILENAME( table->file_name ), table->line_no );
    }
}
コード例 #4
0
extern void
ft_mem_debug_free( FT_Memory   memory,
                   FT_Pointer  block )
{
    FT_MemTable  table = (FT_MemTable)memory->user;


    if ( block == NULL )
        ft_mem_debug_panic( "trying to free NULL in (%s:%ld)",
                            FT_FILENAME( table->file_name ),
                            table->line_no );

    ft_mem_table_remove( table, (FT_Byte*)block );

    /* we never really free the block */
    table->file_name = NULL;
    table->line_no   = 0;
}
コード例 #5
0
ファイル: ftdbgmem.c プロジェクト: Gin-Rye/duibrowser
  extern void
  ft_mem_debug_free( FT_Memory   memory,
                     FT_Pointer  block )
  {
    FT_MemTable  table = (FT_MemTable)memory->user;


    if ( block == NULL )
      ft_mem_debug_panic( "trying to free NULL in (%s:%ld)",
                          FT_FILENAME( _ft_debug_file ),
                          _ft_debug_lineno );

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

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

    table->alloc_count--;

    _ft_debug_file   = "<unknown>";
    _ft_debug_lineno = 0;
  }
コード例 #6
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" );
    }
}
コード例 #7
0
ファイル: ftdbgmem.c プロジェクト: Gin-Rye/duibrowser
  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 );

      FT_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 );
      FT_PRINTF( " block  block    sizes    sizes    sizes   source\n" );
      FT_PRINTF( " count   high      sum  highsum      max   location\n" );
      FT_PRINTF( "-------------------------------------------------\n" );

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

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


        FT_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 );
      }
      FT_PRINTF( "------------------------------------------------\n" );

      ft_mem_table_free( table, sources );
    }
  }
コード例 #8
0
ファイル: ftdbgmem.c プロジェクト: Gin-Rye/duibrowser
  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;
  }
コード例 #9
0
ファイル: ftdbgmem.c プロジェクト: Gin-Rye/duibrowser
  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 );
    }
  }
コード例 #10
0
ファイル: ftdbgmem.c プロジェクト: Gin-Rye/duibrowser
  static void
  ft_mem_table_set( FT_MemTable  table,
                    FT_Byte*     address,
                    FT_ULong     size,
                    FT_Long      delta )
  {
    FT_MemNode  *pnode, node;


    if ( table )
    {
      FT_MemSource  source;


      pnode = ft_mem_table_get_nodep( table, address );
      node  = *pnode;
      if ( node )
      {
        if ( node->size < 0 )
        {
          /* This block was already freed.  Our memory is now completely */
          /* corrupted!                                                  */
          /* This can only happen in keep-alive mode.                    */
          ft_mem_debug_panic(
            "memory heap corrupted (allocating freed block)" );
        }
        else
        {
          /* This block was already allocated.  This means that our memory */
          /* is also corrupted!                                            */
          ft_mem_debug_panic(
            "memory heap corrupted (re-allocating allocated block at"
            " %p, of size %ld)\n"
            "org=%s:%d new=%s:%d\n",
            node->address, node->size,
            FT_FILENAME( node->source->file_name ), node->source->line_no,
            FT_FILENAME( _ft_debug_file ), _ft_debug_lineno );
        }
      }

      /* we need to create a new node in this table */
      node = (FT_MemNode)ft_mem_table_alloc( table, sizeof ( *node ) );
      if ( node == NULL )
        ft_mem_debug_panic( "not enough memory to run memory tests" );

      node->address = address;
      node->size    = size;
      node->source  = source = ft_mem_table_get_source( table );

      if ( delta == 0 )
      {
        /* this is an allocation */
        source->all_blocks++;
        source->cur_blocks++;
        if ( source->cur_blocks > source->max_blocks )
          source->max_blocks = source->cur_blocks;
      }

      if ( size > (FT_ULong)source->cur_max )
        source->cur_max = size;

      if ( delta != 0 )
      {
        /* we are growing or shrinking a reallocated block */
        source->cur_size     += delta;
        table->alloc_current += delta;
      }
      else
      {
        /* we are allocating a new block */
        source->cur_size     += size;
        table->alloc_current += size;
      }

      source->all_size += size;

      if ( source->cur_size > source->max_size )
        source->max_size = source->cur_size;

      node->free_file_name = NULL;
      node->free_line_no   = 0;

      node->link = pnode[0];

      pnode[0] = node;
      table->nodes++;

      table->alloc_total += size;

      if ( table->alloc_current > table->alloc_max )
        table->alloc_max = table->alloc_current;

      if ( table->nodes * 3 < table->size  ||
           table->size  * 3 < table->nodes )
        ft_mem_table_resize( table );
    }
  }
コード例 #11
0
ファイル: ftdbgmem.c プロジェクト: Gin-Rye/duibrowser
  static void
  ft_mem_table_destroy( FT_MemTable  table )
  {
    FT_ULong  i;


    FT_DumpMemory( table->memory );

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


      /* 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 = 0;

          if ( node->size > 0 )
          {
            FT_PRINTF(
              "leaked memory block at address %p, size %8ld in (%s:%ld)\n",
              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] = 0;
      }

      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;
      }

      FT_PRINTF(
        "FreeType: total memory allocations = %ld\n", table->alloc_total );
      FT_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 );

      FT_PRINTF( "FreeType: No memory leaks detected!\n" );
    }
  }