This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Better checking in alloc-pool.c
- From: Josef Zlomek <zlomj9am at artax dot karlin dot mff dot cuni dot cz>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 7 May 2003 16:09:43 +0200
- Subject: 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;