This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: EH_ALLOC_SIZE is not large enough
Nathan Sidwell wrote:
> 224 bytes
Following up on my own post - why do these ideas occur 5 seconds after
pressing the 'go' button?
It is the padding after the 16byte allocation that I forgot about. If we
removed that, then we'd be back to 192 bytes required and the entire
eh_context struct would be 192+40 -> 232 bytes which when malloced
will fit nicely in a 256byte allocation. That extra padding is needed
because the fallback allocator uses a bit mask to indicate which blocks
have been allocated, and each allocation consists of 1 or more contiguous
set bits followed by a zero bit (so the size of the allocation is known).
the block size is set at 16bytes, as that's the conservative alignment.
We could change the allocator in libgcc2 to use 2bits per block, and thereby
eliminate the extra padding. Does the attached patch work for you Alex?
nathan
--
Dr Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery LLC
'But that's a lie.' - 'Yes it is. What's your point?'
nathan@codesourcery.com : http://www.cs.bris.ac.uk/~nathan/ : nathan@acm.org
Index: ChangeLog
===================================================================
RCS file: /cvs/gcc/egcs/gcc/ChangeLog,v
retrieving revision 1.9635
diff -c -3 -p -r1.9635 ChangeLog
*** ChangeLog 2001/03/27 06:03:35 1.9635
--- ChangeLog 2001/03/27 09:11:10
***************
*** 1,3 ****
--- 1,8 ----
+ 2001-03-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ * libgcc2.c (__eh_alloc): Use two bits per block.
+ * libgcc2.c (__eh_free): Adjust.
+
2001-03-27 Alan Modra <alan@linuxcare.com.au>
* c-typeck.c (digest_init): Fold init expression.
Index: libgcc2.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/libgcc2.c,v
retrieving revision 1.115
diff -c -3 -p -r1.115 libgcc2.c
*** libgcc2.c 2001/02/08 12:39:14 1.115
--- libgcc2.c 2001/03/27 09:11:13
*************** __eh_alloc (size_t size)
*** 3379,3399 ****
{
struct eh_context *eh = __get_eh_context ();
unsigned blocks = (size + EH_ALLOC_ALIGN - 1) / EH_ALLOC_ALIGN;
- unsigned real_mask = eh->alloc_mask | (eh->alloc_mask << 1);
unsigned our_mask;
unsigned ix;
if (blocks > EH_ALLOC_SIZE / EH_ALLOC_ALIGN)
__terminate ();
! blocks += blocks == 1;
! our_mask = (1 << blocks) - 1;
for (ix = EH_ALLOC_SIZE / EH_ALLOC_ALIGN - blocks; ix; ix--)
! if (! ((real_mask >> ix) & our_mask))
{
/* found some space */
p = &eh->alloc_buffer[ix * EH_ALLOC_ALIGN];
! eh->alloc_mask |= (our_mask >> 1) << ix;
return p;
}
__terminate ();
--- 3379,3397 ----
{
struct eh_context *eh = __get_eh_context ();
unsigned blocks = (size + EH_ALLOC_ALIGN - 1) / EH_ALLOC_ALIGN;
unsigned our_mask;
unsigned ix;
if (blocks > EH_ALLOC_SIZE / EH_ALLOC_ALIGN)
__terminate ();
! our_mask = (1 << (blocks * 2 - 1)) - 1;
for (ix = EH_ALLOC_SIZE / EH_ALLOC_ALIGN - blocks; ix; ix--)
! if (! ((eh->alloc_mask >> ix * 2) & our_mask))
{
/* found some space */
p = &eh->alloc_buffer[ix * EH_ALLOC_ALIGN];
! eh->alloc_mask |= our_mask << ix * 2;
return p;
}
__terminate ();
*************** void
*** 3407,3418 ****
__eh_free (void *p)
{
struct eh_context *eh = __get_eh_context ();
!
! ptrdiff_t diff = (char *)p - &eh->alloc_buffer[0];
if (diff >= 0 && diff < EH_ALLOC_SIZE)
{
unsigned mask = eh->alloc_mask;
! unsigned bit = 1 << (diff / EH_ALLOC_ALIGN);
do
{
--- 3405,3416 ----
__eh_free (void *p)
{
struct eh_context *eh = __get_eh_context ();
! ptrdiff_t diff = (char *)p - &eh->alloc_buffer[0];
!
if (diff >= 0 && diff < EH_ALLOC_SIZE)
{
unsigned mask = eh->alloc_mask;
! unsigned bit = 1 << (diff / EH_ALLOC_ALIGN) * 2;
do
{