OSDN Git Service

fortran/
[pf3gnuchains/gcc-fork.git] / gcc / ggc-page.c
index 578faf6..131731f 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.
@@ -458,8 +458,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
@@ -821,8 +828,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);
        }
@@ -930,22 +936,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;
 
@@ -1139,8 +1139,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;
        }
 
@@ -1259,10 +1265,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.  */
@@ -1298,10 +1301,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.  */
@@ -1474,8 +1474,7 @@ 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...  */
@@ -1556,8 +1555,7 @@ ggc_push_context (void)
   ++G.context_depth;
 
   /* Die on wrap.  */
-  if (G.context_depth >= HOST_BITS_PER_LONG)
-    abort ();
+  gcc_assert (G.context_depth < HOST_BITS_PER_LONG);
 }
 
 /* Merge the SAVE_IN_USE_P and IN_USE_P arrays in P so that IN_USE_P
@@ -1593,8 +1591,7 @@ ggc_recalculate_in_use_p (page_entry *p)
        p->num_free_objects -= (j & 1);
     }
 
-  if (p->num_free_objects >= num_objects)
-    abort ();
+  gcc_assert (p->num_free_objects < num_objects);
 }
 
 /* Decrement the `GC context'.  All objects allocated since the
@@ -1634,18 +1631,12 @@ ggc_pop_context (void)
         recalculate the in use bits.  */
       for (i = G.depth[depth]; i < e; ++i)
        {
-         page_entry *p;
-
-#ifdef ENABLE_CHECKING
-         p = G.by_depth[i];
+         page_entry *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
+         gcc_assert (p->context_depth == depth);
+         gcc_assert (p->index_by_depth == i);
 
          prefetch (&save_in_use_p_i (i+8));
          prefetch (&save_in_use_p_i (i+16));
@@ -1667,12 +1658,8 @@ ggc_pop_context (void)
 
       /* 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
+      gcc_assert (p->context_depth > depth);
+      gcc_assert (p->index_by_depth == i);
       p->context_depth = depth;
     }
 
@@ -1684,12 +1671,8 @@ ggc_pop_context (void)
       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 ();
-       }
+       gcc_assert (p->context_depth < depth ||
+                   (p->context_depth == depth && !save_in_use_p (p)));
     }
 #endif
 }
@@ -1710,11 +1693,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
@@ -1944,8 +1924,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
@@ -2341,8 +2320,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++)
     {