This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Better checking in alloc-pool.c


Hi,

this patch adds better checking to alloc-pool.[ch].
It checks whether we are freeing the blocks which have been allocated,
and whether we are not freeing them twice.
When abort()ing, it also calls fancy_abort which did not happen before.

It also does the checking only when ENABLE_CHECKING which should be a
minor speedup of GCC.

Bootstrapped/regtested x86-64 with --enable-checking.

OK for mainline?

Josef

2003-05-07  Josef Zlomek  <zlomekj@suse.cz>

	* alloc-pool.h (ALLOC_POOL_ID_TYPE): New type.
	(struct alloc_pool_def): New element 'id'.
	* alloc-pool.c (fancy_abort): Extern function prototype.
	(abort): Macro which uses fancy_abort.
	(last_id): New variable.
	(ID_SIZE): New macro.
	(create_alloc_pool): Add ID_SIZE to size of element, increase
	and use last_id.
	(free_alloc_pool): Do the checking only when ENABLE_CHECKING.
	(pool_alloc): Likewise. Set ID for elements.
	(pool_free): Check whether the PTR was allocated from POOL.

Index: alloc-pool.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/alloc-pool.c,v
retrieving revision 1.2
diff -c -3 -p -r1.2 alloc-pool.c
*** alloc-pool.c	5 Jan 2003 05:27:44 -0000	1.2
--- alloc-pool.c	7 May 2003 06:45:50 -0000
***************
*** 1,5 ****
  /* Functions to support a pool of allocatable objects.
!    Copyright (C) 1987, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
     Contributed by Daniel Berlin <dan@cgsoftware.com>
  
  This file is part of GCC.
--- 1,6 ----
  /* Functions to support a pool of allocatable objects.
!    Copyright (C) 1987, 1997, 1998, 1999, 2000, 2001, 2003
!    Free Software Foundation, Inc.
     Contributed by Daniel Berlin <dan@cgsoftware.com>
  
  This file is part of GCC.
*************** Software Foundation, 59 Temple Place - S
*** 23,31 ****
--- 24,57 ----
  #include "system.h"
  #include "alloc-pool.h"
  
+ /* Redefine abort to report an internal error w/o coredump, and
+    reporting the location of the error in the source file.  This logic
+    is duplicated in rtl.h and tree.h because every file that needs the
+    special abort includes one or both.  toplev.h gets too few files,
+    system.h gets too many.  */
+ 
+ extern void fancy_abort PARAMS ((const char *, int, const char *))
+     ATTRIBUTE_NORETURN;
+ #define abort() fancy_abort (__FILE__, __LINE__, __FUNCTION__)
+ 
  #define align_four(x) (((x+3) >> 2) << 2)
  #define align_eight(x) (((x+7) >> 3) << 3)
  
+ #ifdef ENABLE_CHECKING
+ 
+ /* Last used ID.  */
+ static ALLOC_POOL_ID_TYPE last_id;
+ 
+ /* The size of ID, aligned to be a multiple of eight.  */
+ #define ID_SIZE (align_eight (sizeof (ALLOC_POOL_ID_TYPE)))
+ 
+ #else
+ 
+ /* We do not use IDs when checking is disabled.  */
+ #define ID_SIZE 0
+ 
+ #endif
+ 
  /* Create a pool of things of size SIZE, with NUM in each block we
     allocate.  */
  
*************** create_alloc_pool (name, size, num)
*** 48,53 ****
--- 74,84 ----
    /* Now align the size to a multiple of 4.  */
    size = align_four (size);
  
+ #ifdef ENABLE_CHECKING
+   /* Add the size of ID aligned to a multiple of 8.  */
+   size += ID_SIZE;
+ #endif
+ 
    /* Um, we can't really allocate 0 elements per block.  */
    if (num == 0)
      abort ();
*************** create_alloc_pool (name, size, num)
*** 73,78 ****
--- 104,119 ----
    pool->blocks_allocated = 0;
    pool->block_list = NULL;
  
+ #ifdef ENABLE_CHECKING
+   /* Increase the last used ID and use it for this pool.
+      ID == 0 is used for free elements of pool so skip it.  */
+   last_id++;
+   if (last_id == 0)
+     last_id++;
+ 
+   pool->id = last_id;
+ #endif
+  
    return (pool);
  }
  
*************** free_alloc_pool (pool)
*** 83,90 ****
--- 124,133 ----
  {
    alloc_pool_list block, next_block;
  
+ #ifdef ENABLE_CHECKING
    if (!pool)
      abort ();
+ #endif
  
    /* Free each block allocated to the pool.  */
    for (block = pool->block_list; block != NULL; block = next_block)
*************** pool_alloc (pool)
*** 105,112 ****
--- 148,157 ----
    alloc_pool_list header;
    char *block;
  
+ #ifdef ENABLE_CHECKING
    if (!pool)
      abort ();
+ #endif
  
    /* If there are no more free elements, make some more!.  */
    if (!pool->free_list)
*************** pool_alloc (pool)
*** 126,132 ****
        /* Now put the actual block pieces onto the free list.  */
        for (i = 0; i < pool->elts_per_block; i++, block += pool->elt_size)
        {
!         header = (alloc_pool_list) block;
          header->next = pool->free_list;
          pool->free_list = header;
        }
--- 171,181 ----
        /* Now put the actual block pieces onto the free list.  */
        for (i = 0; i < pool->elts_per_block; i++, block += pool->elt_size)
        {
! #ifdef ENABLE_CHECKING
! 	/* Mark the element to be free.  */
! 	*((ALLOC_POOL_ID_TYPE *) block) = 0;
! #endif
!         header = (alloc_pool_list) (block + ID_SIZE);
          header->next = pool->free_list;
          pool->free_list = header;
        }
*************** pool_alloc (pool)
*** 141,146 ****
--- 190,201 ----
    header = pool->free_list;
    pool->free_list = header->next;
    pool->elts_free--;
+ 
+ #ifdef ENABLE_CHECKING
+   /* Set the ID for element.  */
+   *((ALLOC_POOL_ID_TYPE *) (((char *) header) - ID_SIZE)) = pool->id;
+ #endif
+ 
    return ((void *) header);
  }
  
*************** pool_free (pool, ptr)
*** 152,163 ****
--- 207,228 ----
  {
    alloc_pool_list header;
  
+ #ifdef ENABLE_CHECKING
    if (!ptr)
      abort ();
  
+   /* Check whether the PTR was allocated from POOL.  */
+   if (pool->id != *((ALLOC_POOL_ID_TYPE *) (((char *) ptr) - ID_SIZE)))
+     abort ();
+ 
+   /* Mark the element to be free.  */
+   *((ALLOC_POOL_ID_TYPE *) (((char *) ptr) - ID_SIZE)) = 0;
+ #else
    /* Check if we free more than we allocated, which is Bad (TM).  */
    if (pool->elts_free + 1 > pool->elts_allocated)
      abort ();
+ #endif
+ 
    header = (alloc_pool_list) ptr;
    header->next = pool->free_list;
    pool->free_list = header;
Index: alloc-pool.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/alloc-pool.h,v
retrieving revision 1.1
diff -c -3 -p -r1.1 alloc-pool.h
*** alloc-pool.h	19 Dec 2002 15:53:32 -0000	1.1
--- alloc-pool.h	7 May 2003 06:45:50 -0000
***************
*** 1,7 ****
- 
  /* Functions to support a pool of allocatable objects
!    Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
     Contributed by Daniel Berlin <dan@cgsoftware.com>
  This file is part of GCC.
  
  GCC is free software; you can redistribute it and/or modify
--- 1,8 ----
  /* Functions to support a pool of allocatable objects
!    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2003
!    Free Software Foundation, Inc.
     Contributed by Daniel Berlin <dan@cgsoftware.com>
+ 
  This file is part of GCC.
  
  GCC is free software; you can redistribute it and/or modify
*************** Boston, MA 02111-1307, USA.  */
*** 21,26 ****
--- 22,29 ----
  #ifndef ALLOC_POOL_H
  #define ALLOC_POOL_H
  
+ typedef unsigned long ALLOC_POOL_ID_TYPE;
+  
  typedef struct alloc_pool_list_def
  {
    struct alloc_pool_list_def *next;
*************** typedef struct alloc_pool_list_def
*** 30,35 ****
--- 33,41 ----
  typedef struct alloc_pool_def
  {
    char *name;
+ #ifdef ENABLE_CHECKING
+   ALLOC_POOL_ID_TYPE id;
+ #endif
    size_t elts_per_block;
    alloc_pool_list free_list;
    size_t elts_allocated;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]