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]

Re: Better checking in alloc-pool.c


Hi,

this patch adds better checking to alloc-pool.[ch] in a cleaner way
than my previous patch.
It checks whether we are freeing the blocks which have been allocated,
and whether we are not freeing them twice.

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

OK for mainline?

Josef

2003-05-11  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.
	(struct allocation_object_def): New structure.
	(ALLOCATION_OBJECT_PTR_FROM_USER_PTR): New macro.
	(USER_PTR_FROM_ALLOCATION_OBJECT_PTR): New macro.
	(last_id): New variable.
	(create_alloc_pool): Add the offset of u.data 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	11 May 2003 15:18: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,79 ----
  #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)
  
+ /* The internal allocation object.  */
+ typedef struct allocation_object_def
+ {
+ #ifdef ENABLE_CHECKING
+   /* The ID of alloc pool which the object was allocated from.  */
+   ALLOC_POOL_ID_TYPE id;
+ #endif
+ 
+   union
+     {
+       /* The data of the object.  */
+       char data[1];
+ 
+       /* Because we want any type of data to be well aligned after the ID,
+ 	 the following elements are here.  They are never accessed so
+ 	 the allocated object may be even smaller than this structure.  */
+       char *align_p;
+       double align_d;
+       HOST_WIDEST_INT align_i;
+ #ifdef HAVE_LONG_DOUBLE
+       long double align_ld;
+ #endif
+     } u;
+ } allocation_object;
+ 
+ /* Convert a pointer to allocation_object from a pointer to user data.  */
+ #define ALLOCATION_OBJECT_PTR_FROM_USER_PTR(X)				\
+    ((allocation_object *) (((char *) (X))				\
+ 			   - offsetof (allocation_object, u.data)))
+ 
+ /* Convert a pointer to user data from a pointer to allocation_object.  */
+ #define USER_PTR_FROM_ALLOCATION_OBJECT_PTR(X)				\
+    ((void *) (((allocation_object *) (X))->u.data))
+ 
+ /* Last used ID.  */
+ static ALLOC_POOL_ID_TYPE last_id;
+ 
  /* Create a pool of things of size SIZE, with NUM in each block we
     allocate.  */
  
*************** create_alloc_pool (name, size, num)
*** 48,53 ****
--- 96,106 ----
    /* Now align the size to a multiple of 4.  */
    size = align_four (size);
  
+ #ifdef ENABLE_CHECKING
+   /* Add the aligned size of ID.  */
+   size += offsetof (allocation_object, u.data);
+ #endif
+ 
    /* Um, we can't really allocate 0 elements per block.  */
    if (num == 0)
      abort ();
*************** create_alloc_pool (name, size, num)
*** 73,78 ****
--- 126,141 ----
    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 ****
--- 146,155 ----
  {
    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 ****
--- 170,179 ----
    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;
        }
--- 193,203 ----
        /* 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.  */
! 	((allocation_object *) block)->id = 0;
! #endif
!         header = (alloc_pool_list) USER_PTR_FROM_ALLOCATION_OBJECT_PTR (block);
          header->next = pool->free_list;
          pool->free_list = header;
        }
*************** pool_alloc (pool)
*** 141,146 ****
--- 212,223 ----
    header = pool->free_list;
    pool->free_list = header->next;
    pool->elts_free--;
+ 
+ #ifdef ENABLE_CHECKING
+   /* Set the ID for element.  */
+   ALLOCATION_OBJECT_PTR_FROM_USER_PTR (header)->id = pool->id;
+ #endif
+ 
    return ((void *) header);
  }
  
*************** pool_free (pool, ptr)
*** 152,163 ****
--- 229,250 ----
  {
    alloc_pool_list header;
  
+ #ifdef ENABLE_CHECKING
    if (!ptr)
      abort ();
  
+   /* Check whether the PTR was allocated from POOL.  */
+   if (pool->id != ALLOCATION_OBJECT_PTR_FROM_USER_PTR (ptr)->id)
+     abort ();
+ 
+   /* Mark the element to be free.  */
+   ALLOCATION_OBJECT_PTR_FROM_USER_PTR (ptr)->id = 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	11 May 2003 15:18: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]