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]

[PATCH] Re: Bootstrap failure due to GC / PCH memory corruption


While I didn't manage to change the PCH behaviour, I was able to
fix the compute_inverse logic to work with arbitrary sizes.
This problem was quite trivial: 'unsigned int' simply isn't big
enough to hold the sizes on 64-bit platforms.  Using size_t
instead fixes the problem.

Note that we should probably really use size_t anyway, as the
OFFSET_TO_BIT macro performs a multiplication in the type of
its OFFSET argument, which is always a pointer difference.
This means that computing the inverse modulo the size of
unsigned int could give wrong results anyway ...

In any case, the patch below fixes the bootstrap failures on
s390x, and doesn't appear to introduce any real overhead,
so I propose to apply it now; the matter of just how PCH ptes
are generated can be addressed independently.

Bootstrapped/regtested on s390-ibm-linux and s390x-ibm-linux.
OK?


ChangeLog:

	* ggc-page.c (inverse_table): Change type of mult to size_t.
	(compute_inverse): Compute inverse using size_t, not unsigned int.
	Compute inverse also for sizes larger than half a machine page.

Index: gcc/ggc-page.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ggc-page.c,v
retrieving revision 1.69
diff -c -p -r1.69 ggc-page.c
*** gcc/ggc-page.c	17 Jun 2003 14:09:54 -0000	1.69
--- gcc/ggc-page.c	26 Jun 2003 21:06:46 -0000
*************** static size_t object_size_table[NUM_ORDE
*** 231,237 ****
  
  static struct
  {
!   unsigned int mult;
    unsigned int shift;
  }
  inverse_table[NUM_ORDERS];
--- 231,237 ----
  
  static struct
  {
!   size_t mult;
    unsigned int shift;
  }
  inverse_table[NUM_ORDERS];
*************** ggc_get_size (const void *p)
*** 1219,1237 ****
  static void
  compute_inverse (unsigned order)
  {
!   unsigned size, inv, e;
! 
!   /* There can be only one object per "page" in a bucket for sizes
!      larger than half a machine page; it will always have offset zero.  */
!   if (OBJECT_SIZE (order) > G.pagesize/2)
!     {
!       if (OBJECTS_PER_PAGE (order) != 1)
! 	abort ();
! 
!       DIV_MULT (order) = 1;
!       DIV_SHIFT (order) = 0;
!       return;
!     }
  
    size = OBJECT_SIZE (order);
    e = 0;
--- 1219,1226 ----
  static void
  compute_inverse (unsigned order)
  {
!   size_t size, inv; 
!   unsigned int e;
  
    size = OBJECT_SIZE (order);
    e = 0;

-- 
  Dr. Ulrich Weigand
  weigand@informatik.uni-erlangen.de


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