OSDN Git Service

* tree.c (max_int_size_in_bytes): New function, inspired from
[pf3gnuchains/gcc-fork.git] / gcc / ggc-page.c
index dadc124..ae671db 100644 (file)
@@ -1,5 +1,5 @@
 /* "Bag-of-pages" garbage collector for the GNU compiler.
-   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
+   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -16,8 +16,8 @@ for more details.
 
 You should have received a copy of the GNU General Public License
 along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.  */
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.  */
 
 #include "config.h"
 #include "system.h"
@@ -31,6 +31,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "ggc.h"
 #include "timevar.h"
 #include "params.h"
+#include "tree-flow.h"
 #ifdef ENABLE_VALGRIND_CHECKING
 # ifdef HAVE_VALGRIND_MEMCHECK_H
 #  include <valgrind/memcheck.h>
@@ -74,7 +75,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #define USING_MALLOC_PAGE_GROUPS
 #endif
 
-/* Stategy:
+/* Strategy:
 
    This garbage-collecting allocator allocates objects on one of a set
    of pages.  Each page can allocate objects of a single size only;
@@ -184,8 +185,22 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
    thing you need to do to add a new special allocation size.  */
 
 static const size_t extra_order_size_table[] = {
-  sizeof (struct tree_decl),
+  sizeof (struct stmt_ann_d),
+  sizeof (struct var_ann_d),
+  sizeof (struct tree_decl_non_common),
+  sizeof (struct tree_field_decl),
+  sizeof (struct tree_parm_decl),
+  sizeof (struct tree_var_decl),
   sizeof (struct tree_list),
+  sizeof (struct tree_ssa_name),
+  sizeof (struct tree_function_decl),
+  sizeof (struct tree_binfo),
+  sizeof (struct function),
+  sizeof (struct basic_block_def),
+  sizeof (bitmap_element),
+  /* PHI nodes with one to three arguments are already covered by the
+     above sizes.  */
+  sizeof (struct tree_phi_node) + sizeof (struct phi_arg_d) * 3,
   TREE_EXP_SIZE (2),
   RTL_SIZE (2),                        /* MEM, PLUS, etc.  */
   RTL_SIZE (9),                        /* INSN */
@@ -249,7 +264,7 @@ typedef struct page_entry
 
   /* The previous page-entry with objects of the same size, or NULL if
      this is the first page-entry.   The PREV pointer exists solely to
-     keep the cost of ggc_free managable.  */
+     keep the cost of ggc_free manageable.  */
   struct page_entry *prev;
 
   /* The number of bytes allocated.  (This will always be a multiple
@@ -456,8 +471,15 @@ static struct globals
 /* Allocate pages in chunks of this size, to throttle calls to memory
    allocation routines.  The first page is used, the rest go onto the
    free list.  This cannot be larger than HOST_BITS_PER_INT for the
-   in_use bitmask for page_group.  */
-#define GGC_QUIRE_SIZE 16
+   in_use bitmask for page_group.  Hosts that need a different value
+   can override this by defining GGC_QUIRE_SIZE explicitly.  */
+#ifndef GGC_QUIRE_SIZE
+# ifdef USING_MMAP
+#  define GGC_QUIRE_SIZE 256
+# else
+#  define GGC_QUIRE_SIZE 16
+# endif
+#endif
 
 /* Initial guess as to how many page table entries we might need.  */
 #define INITIAL_PTE_COUNT 128
@@ -486,9 +508,6 @@ static void move_ptes_to_front (int, int);
 void debug_print_page_list (int);
 static void push_depth (unsigned int);
 static void push_by_depth (page_entry *, unsigned long *);
-struct alloc_zone *rtl_zone = NULL;
-struct alloc_zone *tree_zone = NULL;
-struct alloc_zone *garbage_zone = NULL;
 
 /* Push an entry onto G.depth.  */
 
@@ -619,7 +638,7 @@ found:
   L2 = LOOKUP_L2 (p);
 
   if (base[L1] == NULL)
-    base[L1] = xcalloc (PAGE_L2_SIZE, sizeof (page_entry *));
+    base[L1] = XCNEWVEC (page_entry *, PAGE_L2_SIZE);
 
   base[L1][L2] = entry;
 }
@@ -652,12 +671,12 @@ static inline char *
 alloc_anon (char *pref ATTRIBUTE_UNUSED, size_t size)
 {
 #ifdef HAVE_MMAP_ANON
-  char *page = (char *) mmap (pref, size, PROT_READ | PROT_WRITE,
-                             MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+  char *page = mmap (pref, size, PROT_READ | PROT_WRITE,
+                    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
 #endif
 #ifdef HAVE_MMAP_DEV_ZERO
-  char *page = (char *) mmap (pref, size, PROT_READ | PROT_WRITE,
-                             MAP_PRIVATE, G.dev_zero_fd, 0);
+  char *page = mmap (pref, size, PROT_READ | PROT_WRITE,
+                    MAP_PRIVATE, G.dev_zero_fd, 0);
 #endif
 
   if (page == (char *) MAP_FAILED)
@@ -819,8 +838,7 @@ alloc_page (unsigned order)
              enda -= G.pagesize;
              tail_slop += G.pagesize;
            }
-         if (tail_slop < sizeof (page_group))
-           abort ();
+         gcc_assert (tail_slop >= sizeof (page_group));
          group = (page_group *)enda;
          tail_slop -= sizeof (page_group);
        }
@@ -928,22 +946,16 @@ free_page (page_entry *entry)
   if (G.by_depth_in_use > 1)
     {
       page_entry *top = G.by_depth[G.by_depth_in_use-1];
-
-      /* If they are at the same depth, put top element into freed
-        slot.  */
-      if (entry->context_depth == top->context_depth)
-       {
-         int i = entry->index_by_depth;
-         G.by_depth[i] = top;
-         G.save_in_use[i] = G.save_in_use[G.by_depth_in_use-1];
-         top->index_by_depth = i;
-       }
-      else
-       {
-         /* We cannot free a page from a context deeper than the
-            current one.  */
-         abort ();
-       }
+      int i = entry->index_by_depth;
+
+      /* We cannot free a page from a context deeper than the current
+        one.  */
+      gcc_assert (entry->context_depth == top->context_depth);
+      
+      /* Put top element into freed slot.  */
+      G.by_depth[i] = top;
+      G.save_in_use[i] = G.save_in_use[G.by_depth_in_use-1];
+      top->index_by_depth = i;
     }
   --G.by_depth_in_use;
 
@@ -1020,7 +1032,7 @@ release_pages (void)
 /* This table provides a fast way to determine ceil(log_2(size)) for
    allocation requests.  The minimum allocation size is eight bytes.  */
 
-static unsigned char size_lookup[257] =
+static unsigned char size_lookup[512] =
 {
   3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4,
   4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
@@ -1038,7 +1050,22 @@ static unsigned char size_lookup[257] =
   8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
   8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
   8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-  8
+  8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+  9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+  9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+  9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+  9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+  9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+  9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+  9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+  9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+  9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+  9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+  9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+  9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+  9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+  9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+  9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9
 };
 
 /* Typed allocation function.  Does nothing special in this collector.  */
@@ -1050,15 +1077,6 @@ ggc_alloc_typed_stat (enum gt_types_enum type ATTRIBUTE_UNUSED, size_t size
   return ggc_alloc_stat (size PASS_MEM_STAT);
 }
 
-/* Zone allocation function.  Does nothing special in this collector.  */
-
-void *
-ggc_alloc_zone_stat (size_t size, struct alloc_zone *zone ATTRIBUTE_UNUSED
-                    MEM_STAT_DECL)
-{
-  return ggc_alloc_stat (size PASS_MEM_STAT);
-}
-
 /* Allocate a chunk of memory of SIZE bytes.  Its contents are undefined.  */
 
 void *
@@ -1068,14 +1086,14 @@ ggc_alloc_stat (size_t size MEM_STAT_DECL)
   struct page_entry *entry;
   void *result;
 
-  if (size <= 256)
+  if (size < 512)
     {
       order = size_lookup[size];
       object_size = OBJECT_SIZE (order);
     }
   else
     {
-      order = 9;
+      order = 10;
       while (size > (object_size = OBJECT_SIZE (order)))
        order++;
     }
@@ -1137,8 +1155,14 @@ ggc_alloc_stat (size_t size MEM_STAT_DECL)
          word = bit = 0;
          while (~entry->in_use_p[word] == 0)
            ++word;
+
+#if GCC_VERSION >= 3004
+         bit = __builtin_ctzl (~entry->in_use_p[word]);
+#else
          while ((entry->in_use_p[word] >> bit) & 1)
            ++bit;
+#endif
+
          hint = word * HOST_BITS_PER_LONG + bit;
        }
 
@@ -1173,12 +1197,13 @@ ggc_alloc_stat (size_t size MEM_STAT_DECL)
       G.page_tails[order]->next = entry;
       G.page_tails[order] = entry;
     }
-#ifdef GATHER_STATISTICS
-  ggc_record_overhead (OBJECT_SIZE (order), OBJECT_SIZE (order) - size PASS_MEM_STAT);
-#endif
 
   /* Calculate the object's address.  */
   result = entry->page + object_offset;
+#ifdef GATHER_STATISTICS
+  ggc_record_overhead (OBJECT_SIZE (order), OBJECT_SIZE (order) - size,
+                      result PASS_MEM_STAT);
+#endif
 
 #ifdef ENABLE_GC_CHECKING
   /* Keep poisoning-by-writing-0xaf the object, in an attempt to keep the
@@ -1206,6 +1231,9 @@ ggc_alloc_stat (size_t size MEM_STAT_DECL)
      information is used in deciding when to collect.  */
   G.allocated += object_size;
 
+  /* For timevar statistics.  */
+  timevar_ggc_mem_total += object_size;
+
 #ifdef GATHER_STATISTICS
   {
     size_t overhead = object_size - size;
@@ -1256,10 +1284,7 @@ ggc_set_mark (const void *p)
   /* Look up the page on which the object is alloced.  If the object
      wasn't allocated by the collector, we'll probably die.  */
   entry = lookup_page_table_entry (p);
-#ifdef ENABLE_CHECKING
-  if (entry == NULL)
-    abort ();
-#endif
+  gcc_assert (entry);
 
   /* Calculate the index of the object on the page; this is its bit
      position in the in_use_p bitmap.  */
@@ -1295,10 +1320,7 @@ ggc_marked_p (const void *p)
   /* Look up the page on which the object is alloced.  If the object
      wasn't allocated by the collector, we'll probably die.  */
   entry = lookup_page_table_entry (p);
-#ifdef ENABLE_CHECKING
-  if (entry == NULL)
-    abort ();
-#endif
+  gcc_assert (entry);
 
   /* Calculate the index of the object on the page; this is its bit
      position in the in_use_p bitmap.  */
@@ -1327,6 +1349,10 @@ ggc_free (void *p)
   size_t order = pe->order;
   size_t size = OBJECT_SIZE (order);
 
+#ifdef GATHER_STATISTICS
+  ggc_free_overhead (p);
+#endif
+
   if (GGC_DEBUG_LEVEL >= 3)
     fprintf (G.debug_file,
             "Freeing object, actual size=%lu, at %p on %p\n",
@@ -1345,7 +1371,7 @@ ggc_free (void *p)
      the data, but instead verify that the data is *actually* not 
      reachable the next time we collect.  */
   {
-    struct free_object *fo = xmalloc (sizeof (struct free_object));
+    struct free_object *fo = XNEW (struct free_object);
     fo->object = p;
     fo->next = G.free_object_list;
     G.free_object_list = fo;
@@ -1467,12 +1493,11 @@ init_ggc (void)
           can't get something useful, give up.  */
 
        p = alloc_anon (NULL, G.pagesize);
-       if ((size_t)p & (G.pagesize - 1))
-         abort ();
+       gcc_assert (!((size_t)p & (G.pagesize - 1)));
       }
 
     /* We have a good page, might as well hold onto it...  */
-    e = xcalloc (1, sizeof (struct page_entry));
+    e = XCNEW (struct page_entry);
     e->bytes = G.pagesize;
     e->page = p;
     e->next = G.free_pages;
@@ -1486,10 +1511,6 @@ init_ggc (void)
   for (order = HOST_BITS_PER_PTR; order < NUM_ORDERS; ++order)
     {
       size_t s = extra_order_size_table[order - HOST_BITS_PER_PTR];
-
-      /* If S is not a multiple of the MAX_ALIGNMENT, then round it up
-        so that we're sure of getting aligned memory.  */
-      s = ROUND_UP (s, MAX_ALIGNMENT);
       object_size_table[order] = s;
     }
 
@@ -1505,25 +1526,65 @@ init_ggc (void)
   /* Reset the size_lookup array to put appropriately sized objects in
      the special orders.  All objects bigger than the previous power
      of two, but no greater than the special size, should go in the
-     new order.  */
+     new order.
+     Enforce alignment during lookup.  The resulting bin size must
+     have the same or bigger alignment than the apparent alignment
+     requirement from the size request (but not bigger alignment
+     than MAX_ALIGNMENT).  Consider an extra bin of size 76 (in
+     addition to the 64 and 128 byte sized bins).  A request of
+     allocation size of 72 bytes must be served from the 128 bytes
+     bin, because 72 bytes looks like a request for 8 byte aligned
+     memory, while the 76 byte bin can only serve chunks with a
+     guaranteed alignment of 4 bytes.  */
   for (order = HOST_BITS_PER_PTR; order < NUM_ORDERS; ++order)
     {
-      int o;
-      int i;
-
-      o = size_lookup[OBJECT_SIZE (order)];
-      for (i = OBJECT_SIZE (order); size_lookup [i] == o; --i)
-       size_lookup[i] = order;
+      int i, mask;
+
+      /* Build an alignment mask that can be used for testing
+         size % 2*align.  If (size | MAX_ALIGNMENT) & mask is non-zero
+        then the requested size apparent alignment requirement 
+        (which is at most MAX_ALIGNMENT) is less or equal than what
+        the OBJECT_SIZE bin can guarantee.  */
+      mask = ~(((unsigned)-1) << ffs (OBJECT_SIZE (order)));
+      mask &= 2 * MAX_ALIGNMENT - 1;
+
+      /* All objects smaller than the OBJECT_SIZE for this ORDER could go
+        into ORDER.  Determine the cases for which that is profitable
+        and fulfilling the alignment requirements.  Stop searching
+        once a smaller bin with same or better alignment guarantee is
+        found.  */
+      for (i = OBJECT_SIZE (order); ; --i)
+       {
+         unsigned int old_sz = OBJECT_SIZE (size_lookup [i]);
+         if (!(old_sz & (mask >> 1))
+             && old_sz < OBJECT_SIZE (order))
+           break;
+
+         /* If object of size I are presently using a larger bin, we would
+            like to move them to ORDER.  However, we can only do that if we
+            can be sure they will be properly aligned.  They will be properly
+            aligned if either the ORDER bin is maximally aligned, or if
+            objects of size I cannot be more strictly aligned than the
+            alignment of this order.  */
+         if ((i | MAX_ALIGNMENT) & mask
+             && old_sz > OBJECT_SIZE (order))
+           size_lookup[i] = order;
+       }
     }
 
+  /* Verify we got everything right with respect to alignment requests.  */
+  for (order = 1; order < 512; ++order)
+    gcc_assert (ffs (OBJECT_SIZE (size_lookup [order]))
+               >= ffs (order | MAX_ALIGNMENT));
+
   G.depth_in_use = 0;
   G.depth_max = 10;
-  G.depth = xmalloc (G.depth_max * sizeof (unsigned int));
+  G.depth = XNEWVEC (unsigned int, G.depth_max);
 
   G.by_depth_in_use = 0;
   G.by_depth_max = INITIAL_PTE_COUNT;
-  G.by_depth = xmalloc (G.by_depth_max * sizeof (page_entry *));
-  G.save_in_use = xmalloc (G.by_depth_max * sizeof (unsigned long *));
+  G.by_depth = XNEWVEC (page_entry *, G.by_depth_max);
+  G.save_in_use = XNEWVEC (unsigned long *, G.by_depth_max);
 }
 
 /* Start a new GGC zone.  */
@@ -1540,19 +1601,6 @@ destroy_ggc_zone (struct alloc_zone *zone ATTRIBUTE_UNUSED)
 {
 }
 
-/* Increment the `GC context'.  Objects allocated in an outer context
-   are never freed, eliminating the need to register their roots.  */
-
-void
-ggc_push_context (void)
-{
-  ++G.context_depth;
-
-  /* Die on wrap.  */
-  if (G.context_depth >= HOST_BITS_PER_LONG)
-    abort ();
-}
-
 /* Merge the SAVE_IN_USE_P and IN_USE_P arrays in P so that IN_USE_P
    reflects reality.  Recalculate NUM_FREE_OBJECTS as well.  */
 
@@ -1586,105 +1634,7 @@ ggc_recalculate_in_use_p (page_entry *p)
        p->num_free_objects -= (j & 1);
     }
 
-  if (p->num_free_objects >= num_objects)
-    abort ();
-}
-
-/* Decrement the `GC context'.  All objects allocated since the
-   previous ggc_push_context are migrated to the outer context.  */
-
-void
-ggc_pop_context (void)
-{
-  unsigned long omask;
-  unsigned int depth, i, e;
-#ifdef ENABLE_CHECKING
-  unsigned int order;
-#endif
-
-  depth = --G.context_depth;
-  omask = (unsigned long)1 << (depth + 1);
-
-  if (!((G.context_depth_allocations | G.context_depth_collections) & omask))
-    return;
-
-  G.context_depth_allocations |= (G.context_depth_allocations & omask) >> 1;
-  G.context_depth_allocations &= omask - 1;
-  G.context_depth_collections &= omask - 1;
-
-  /* The G.depth array is shortened so that the last index is the
-     context_depth of the top element of by_depth.  */
-  if (depth+1 < G.depth_in_use)
-    e = G.depth[depth+1];
-  else
-    e = G.by_depth_in_use;
-
-  /* We might not have any PTEs of depth depth.  */
-  if (depth < G.depth_in_use)
-    {
-
-      /* First we go through all the pages at depth depth to
-        recalculate the in use bits.  */
-      for (i = G.depth[depth]; i < e; ++i)
-       {
-         page_entry *p;
-
-#ifdef ENABLE_CHECKING
-         p = G.by_depth[i];
-
-         /* Check that all of the pages really are at the depth that
-            we expect.  */
-         if (p->context_depth != depth)
-           abort ();
-         if (p->index_by_depth != i)
-           abort ();
-#endif
-
-         prefetch (&save_in_use_p_i (i+8));
-         prefetch (&save_in_use_p_i (i+16));
-         if (save_in_use_p_i (i))
-           {
-             p = G.by_depth[i];
-             ggc_recalculate_in_use_p (p);
-             free (save_in_use_p_i (i));
-             save_in_use_p_i (i) = 0;
-           }
-       }
-    }
-
-  /* Then, we reset all page_entries with a depth greater than depth
-     to be at depth.  */
-  for (i = e; i < G.by_depth_in_use; ++i)
-    {
-      page_entry *p = G.by_depth[i];
-
-      /* Check that all of the pages really are at the depth we
-        expect.  */
-#ifdef ENABLE_CHECKING
-      if (p->context_depth <= depth)
-       abort ();
-      if (p->index_by_depth != i)
-       abort ();
-#endif
-      p->context_depth = depth;
-    }
-
-  adjust_depth ();
-
-#ifdef ENABLE_CHECKING
-  for (order = 2; order < NUM_ORDERS; order++)
-    {
-      page_entry *p;
-
-      for (p = G.pages[order]; p != NULL; p = p->next)
-       {
-         if (p->context_depth > depth)
-           abort ();
-         else if (p->context_depth == depth && save_in_use_p (p))
-           abort ();
-       }
-    }
-#endif
+  gcc_assert (p->num_free_objects < num_objects);
 }
 \f
 /* Unmark all objects.  */
@@ -1703,11 +1653,8 @@ clear_marks (void)
          size_t num_objects = OBJECTS_IN_PAGE (p);
          size_t bitmap_size = BITMAP_SIZE (num_objects + 1);
 
-#ifdef ENABLE_CHECKING
          /* The data should be page-aligned.  */
-         if ((size_t) p->page & (G.pagesize - 1))
-           abort ();
-#endif
+         gcc_assert (!((size_t) p->page & (G.pagesize - 1)));
 
          /* Pages that aren't in the topmost context are not collected;
             nevertheless, we need their in-use bit vectors to store GC
@@ -1937,8 +1884,7 @@ validate_free_objects (void)
 
       /* Make certain it isn't visible from any root.  Notice that we
         do this check before sweep_pages merges save_in_use_p.  */
-      if (pe->in_use_p[word] & (1UL << bit))
-       abort ();
+      gcc_assert (!(pe->in_use_p[word] & (1UL << bit)));
 
       /* If the object comes from an outer context, then retain the
         free_object entry, so that we can verify that the address
@@ -1971,7 +1917,7 @@ ggc_collect (void)
 
   float min_expand = allocated_last_gc * PARAM_VALUE (GGC_MIN_EXPAND) / 100;
 
-  if (G.allocated < allocated_last_gc + min_expand)
+  if (G.allocated < allocated_last_gc + min_expand && !ggc_force_collect)
     return;
 
   timevar_push (TV_GC);
@@ -1993,6 +1939,9 @@ ggc_collect (void)
 
   clear_marks ();
   ggc_mark_roots ();
+#ifdef GATHER_STATISTICS
+  ggc_prune_overhead_list ();
+#endif
   poison_pages ();
   validate_free_objects ();
   sweep_pages ();
@@ -2013,7 +1962,7 @@ ggc_collect (void)
                  : ((x) < 1024*1024*10 \
                     ? (x) / 1024 \
                     : (x) / (1024*1024))))
-#define LABEL(x) ((x) < 1024*10 ? ' ' : ((x) < 1024*1024*10 ? 'k' : 'M'))
+#define STAT_LABEL(x) ((x) < 1024*10 ? ' ' : ((x) < 1024*1024*10 ? 'k' : 'M'))
 
 void
 ggc_print_statistics (void)
@@ -2068,15 +2017,15 @@ ggc_print_statistics (void)
        }
       fprintf (stderr, "%-5lu %10lu%c %10lu%c %10lu%c\n",
               (unsigned long) OBJECT_SIZE (i),
-              SCALE (allocated), LABEL (allocated),
-              SCALE (in_use), LABEL (in_use),
-              SCALE (overhead), LABEL (overhead));
+              SCALE (allocated), STAT_LABEL (allocated),
+              SCALE (in_use), STAT_LABEL (in_use),
+              SCALE (overhead), STAT_LABEL (overhead));
       total_overhead += overhead;
     }
   fprintf (stderr, "%-5s %10lu%c %10lu%c %10lu%c\n", "Total",
-          SCALE (G.bytes_mapped), LABEL (G.bytes_mapped),
-          SCALE (G.allocated), LABEL(G.allocated),
-          SCALE (total_overhead), LABEL (total_overhead));
+          SCALE (G.bytes_mapped), STAT_LABEL (G.bytes_mapped),
+          SCALE (G.allocated), STAT_LABEL(G.allocated),
+          SCALE (total_overhead), STAT_LABEL (total_overhead));
 
 #ifdef GATHER_STATISTICS  
   {
@@ -2125,20 +2074,21 @@ struct ggc_pch_data
 struct ggc_pch_data *
 init_ggc_pch (void)
 {
-  return xcalloc (sizeof (struct ggc_pch_data), 1);
+  return XCNEW (struct ggc_pch_data);
 }
 
 void
 ggc_pch_count_object (struct ggc_pch_data *d, void *x ATTRIBUTE_UNUSED,
-                     size_t size, bool is_string ATTRIBUTE_UNUSED)
+                     size_t size, bool is_string ATTRIBUTE_UNUSED,
+                     enum gt_types_enum type ATTRIBUTE_UNUSED)
 {
   unsigned order;
 
-  if (size <= 256)
+  if (size < 512)
     order = size_lookup[size];
   else
     {
-      order = 9;
+      order = 10;
       while (size > OBJECT_SIZE (order))
        order++;
     }
@@ -2173,16 +2123,17 @@ ggc_pch_this_base (struct ggc_pch_data *d, void *base)
 
 char *
 ggc_pch_alloc_object (struct ggc_pch_data *d, void *x ATTRIBUTE_UNUSED,
-                     size_t size, bool is_string ATTRIBUTE_UNUSED)
+                     size_t size, bool is_string ATTRIBUTE_UNUSED,
+                     enum gt_types_enum type ATTRIBUTE_UNUSED)
 {
   unsigned order;
   char *result;
 
-  if (size <= 256)
+  if (size < 512)
     order = size_lookup[size];
   else
     {
-      order = 9;
+      order = 10;
       while (size > OBJECT_SIZE (order))
        order++;
     }
@@ -2207,11 +2158,11 @@ ggc_pch_write_object (struct ggc_pch_data *d ATTRIBUTE_UNUSED,
   unsigned order;
   static const char emptyBytes[256];
 
-  if (size <= 256)
+  if (size < 512)
     order = size_lookup[size];
   else
     {
-      order = 9;
+      order = 10;
       while (size > OBJECT_SIZE (order))
        order++;
     }
@@ -2229,8 +2180,7 @@ ggc_pch_write_object (struct ggc_pch_data *d ATTRIBUTE_UNUSED,
       /* To speed small writes, we use a nulled-out array that's larger
          than most padding requests as the source for our null bytes.  This
          permits us to do the padding with fwrite() rather than fseek(), and
-         limits the chance the the OS may try to flush any outstanding
-         writes.  */
+         limits the chance the OS may try to flush any outstanding writes.  */
       if (padding <= sizeof(emptyBytes))
         {
           if (fwrite (emptyBytes, 1, padding, f) != padding)
@@ -2272,8 +2222,8 @@ move_ptes_to_front (int count_old_page_tables, int count_new_page_tables)
   page_entry **new_by_depth;
   unsigned long **new_save_in_use;
 
-  new_by_depth = xmalloc (G.by_depth_max * sizeof (page_entry *));
-  new_save_in_use = xmalloc (G.by_depth_max * sizeof (unsigned long *));
+  new_by_depth = XNEWVEC (page_entry *, G.by_depth_max);
+  new_save_in_use = XNEWVEC (unsigned long *, G.by_depth_max);
 
   memcpy (&new_by_depth[0],
          &G.by_depth[count_old_page_tables],
@@ -2331,8 +2281,7 @@ ggc_pch_read (FILE *f, void *addr)
   /* No object read from a PCH file should ever be freed.  So, set the
      context depth to 1, and set the depth of all the currently-allocated
      pages to be 1 too.  PCH pages will have depth 0.  */
-  if (G.context_depth != 0)
-    abort ();
+  gcc_assert (!G.context_depth);
   G.context_depth = 1;
   for (i = 0; i < NUM_ORDERS; i++)
     {