ggc.h (ggc_push_context): Fix comment.
authorMark Mitchell <mark@codesourcery.com>
Mon, 11 Oct 1999 02:11:21 +0000 (02:11 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Mon, 11 Oct 1999 02:11:21 +0000 (02:11 +0000)
* ggc.h (ggc_push_context): Fix comment.
(ggc_pop_context): Likewise.
(mark_string_if_gcable): Likewise.
* ggc-common.c (ggc_mark_rtx_children): Use
ggc_mark_string_if_gcable.
* ggc-page.c (ggc_lookup_page_table): New function.
(ggc_allocated_p): Likewise.
(mark_obj): Fix formatting.
(ggc_mark_string_if_gcable): New function.
* ggc-simple.c (ggc_allocated_strings): New variable.
(ggc_strings_used): Likewise.
(ggc_compare_addresses): New function.
(ggc_pop_context): Pop the `any' memory too.
(ggc_mark_string_if_gcable): New function.
(ggc_collect): Initialize and tear down ggc_allocated_strings.

From-SVN: r29897

gcc/ChangeLog
gcc/ggc-common.c
gcc/ggc-page.c
gcc/ggc-simple.c
gcc/ggc.h

index ef282fe9cd6840e01d84cc2905f874e00a5b0a5c..0386a21f848c2d91521833c5d1e86a86a33d54f8 100644 (file)
@@ -1,3 +1,21 @@
+Sun Oct 10 18:27:27 1999  Mark Mitchell  <mark@codesourcery.com>
+
+       * ggc.h (ggc_push_context): Fix comment.
+       (ggc_pop_context): Likewise.
+       (mark_string_if_gcable): Likewise.
+       * ggc-common.c (ggc_mark_rtx_children): Use
+       ggc_mark_string_if_gcable.
+       * ggc-page.c (ggc_lookup_page_table): New function.
+       (ggc_allocated_p): Likewise.
+       (mark_obj): Fix formatting.
+       (ggc_mark_string_if_gcable): New function.
+       * ggc-simple.c (ggc_allocated_strings): New variable.
+       (ggc_strings_used): Likewise.
+       (ggc_compare_addresses): New function.
+       (ggc_pop_context): Pop the `any' memory too.
+       (ggc_mark_string_if_gcable): New function.
+       (ggc_collect): Initialize and tear down ggc_allocated_strings.
+       
 Sun Oct 10 20:05:21 1999  David Edelsohn  <edelsohn@gnu.org>
 
        * rs6000.md (movstrsi_?reg): Use preferred rD/rS = r5 form.
index 5acde492d1767b169958d33cfdf823a6b3fe9ca3..6df622e8e04df44efddee2b1332c7194308e33be 100644 (file)
@@ -268,7 +268,7 @@ ggc_mark_rtx_children (r)
          ggc_mark_rtvec (XVEC (r, i));
          break;
        case 'S': case 's':
-         ggc_mark_string (XSTR (r, i));
+         ggc_mark_string_if_gcable (XSTR (r, i));
          break;
        }
     }
index 6b8e46846645780696805d60576d31c6d24593bd..1b643e6fa032ae48b85dafb258a440133d79b65b 100644 (file)
@@ -258,6 +258,8 @@ static struct globals
 #define GGC_MIN_LAST_ALLOCATED (4 * 1024 * 1024)
 
 \f
+static page_entry *** ggc_lookup_page_table PROTO ((void));
+static int ggc_allocated_p PROTO ((const void *));
 static page_entry *lookup_page_table_entry PROTO ((void *));
 static void set_page_table_entry PROTO ((void *, page_entry *));
 static char *alloc_anon PROTO ((char *, size_t));
@@ -276,15 +278,12 @@ static void poison_pages PROTO ((void));
 
 void debug_print_page_list PROTO ((int));
 \f
-/* Traverse the page table and find the entry for a page. 
-   Die (probably) if the object wasn't allocated via GC.  */
+/* Returns the lookup table appropriate for looking up P.  */
 
-static inline page_entry *
-lookup_page_table_entry(p)
-     void *p;
+static inline page_entry ***
+ggc_lookup_page_table ()
 {
   page_entry ***base;
-  size_t L1, L2;
 
 #if HOST_BITS_PER_PTR <= 32
   base = &G.lookup[0];
@@ -296,6 +295,39 @@ lookup_page_table_entry(p)
   base = &table->table[0];
 #endif
 
+  return base;
+}
+
+/* Returns non-zero if P was allocated in GC'able memory.  */
+
+static inline int
+ggc_allocated_p (p)
+     const void *p;
+{
+  page_entry ***base;
+  size_t L1, L2;
+
+  base = ggc_lookup_page_table ();
+
+  /* Extract the level 1 and 2 indicies.  */
+  L1 = LOOKUP_L1 (p);
+  L2 = LOOKUP_L2 (p);
+
+  return base[L1] && base[L1][L2];
+}
+
+/* Traverse the page table and find the entry for a page. 
+   Die (probably) if the object wasn't allocated via GC.  */
+
+static inline page_entry *
+lookup_page_table_entry(p)
+     void *p;
+{
+  page_entry ***base;
+  size_t L1, L2;
+
+  base = ggc_lookup_page_table ();
+
   /* Extract the level 1 and 2 indicies.  */
   L1 = LOOKUP_L1 (p);
   L2 = LOOKUP_L2 (p);
@@ -678,7 +710,7 @@ mark_obj (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);
+  entry = lookup_page_table_entry (p);
 #ifdef ENABLE_CHECKING
   if (entry == NULL)
     abort ();
@@ -1076,6 +1108,14 @@ ggc_mark_string (s)
     mark_obj (s);
 }
 
+void
+ggc_mark_string_if_gcable (s)
+     char *s;
+{
+  if (s && ggc_allocated_p (s))
+    mark_obj (s);
+}
+
 void 
 ggc_mark (p)
      void *p;
index 74a4d5ad5f29fc72f2982af820a27fdb40c95908..d8ed4a15a530e53392377c8a2cece8f5cc856077 100644 (file)
@@ -114,6 +114,10 @@ struct ggc_status
    front of the chain.  */
 static struct ggc_status *ggc_chain;
 
+/* The table of all allocated strings.  Only valid during collection.  */
+static varray_type ggc_allocated_strings;
+static size_t ggc_strings_used;
+
 /* Some statistics.  */
 
 static int n_rtxs_collected;
@@ -134,6 +138,7 @@ static void ggc_free_rtvec PROTO ((struct ggc_rtvec *v));
 static void ggc_free_tree PROTO ((struct ggc_tree *t));
 static void ggc_free_string PROTO ((struct ggc_string *s));
 static void ggc_free_any PROTO ((struct ggc_any *a));
+static int ggc_compare_addresses PROTO ((const void *, const void *));
 
 /* Called once to initialize the garbage collector.  */
 
@@ -173,6 +178,7 @@ ggc_pop_context PROTO ((void))
   struct ggc_rtvec *v;
   struct ggc_tree *t;
   struct ggc_string *s;
+  struct ggc_any *a;
   struct ggc_status *gs;
 
   gs = ggc_chain;
@@ -213,6 +219,15 @@ ggc_pop_context PROTO ((void))
       gs->next->strings = gs->strings;
     }
 
+  a = gs->anys;
+  if (a)
+    {
+     while (a->chain)
+       a = a->chain;
+      a->chain = gs->next->anys;
+      gs->next->anys = gs->anys;
+    }
+
   gs->next->bytes_alloced_since_gc += gs->bytes_alloced_since_gc;
 
   ggc_chain = gs->next;
@@ -455,6 +470,25 @@ ggc_set_mark_tree (t)
   return marked;
 }
 
+/* Compare the pointers pointed to by A1 and A2.  Used as a callback
+   for qsort/bsearch.  */
+
+static int
+ggc_compare_addresses (a1, a2)
+     const void *a1;
+     const void *a2;
+{
+  const char *c1 = *((const char **) a1);
+  const char *c2 = *((const char **) a2);
+
+  if (c1 < c2)
+    return -1;
+  else if (c1 > c2)
+    return 1;
+  else
+    return 0;
+}
+
 void
 ggc_mark_string (s)
      char *s;
@@ -471,6 +505,21 @@ ggc_mark_string (s)
   gs->magic_mark = GGC_STRING_MAGIC_MARK;
 }
 
+
+void
+ggc_mark_string_if_gcable (s)
+     char *s;
+{
+  if (s && !bsearch (&s, 
+                    &VARRAY_CHAR_PTR (ggc_allocated_strings, 0),
+                    ggc_strings_used, sizeof (char *),
+                    ggc_compare_addresses))
+    return;
+
+  ggc_mark_string (s);
+}
+
+
 /* Mark P, allocated with ggc_alloc.  */
 
 void
@@ -513,6 +562,10 @@ ggc_collect ()
 
   time = get_run_time ();
 
+  /* Set up the table of allocated strings.  */
+  VARRAY_CHAR_PTR_INIT (ggc_allocated_strings, 1024, "allocated strings");
+  ggc_strings_used = 0;
+
   /* Clean out all of the GC marks.  */
   for (gs = ggc_chain; gs; gs = gs->next)
     {
@@ -523,13 +576,28 @@ ggc_collect ()
       for (t = gs->trees; t != NULL; t = t->chain)
        t->tree.common.gc_mark = 0;
       for (s = gs->strings; s != NULL; s = s->chain)
-       s->magic_mark = GGC_STRING_MAGIC;
+       {
+         s->magic_mark = GGC_STRING_MAGIC;
+         if (ggc_strings_used == ggc_allocated_strings->num_elements)
+           VARRAY_GROW (ggc_allocated_strings, 2 * ggc_strings_used);
+         VARRAY_CHAR_PTR (ggc_allocated_strings, ggc_strings_used)
+           = &s->string[0];
+         ++ggc_strings_used;
+       }
       for (a = gs->anys; a != NULL; a = a->chain)
        a->magic_mark = GGC_ANY_MAGIC;
     }
 
+  /* Sort the allocated string table.  */
+  qsort (&VARRAY_CHAR_PTR (ggc_allocated_strings, 0),
+        ggc_strings_used, sizeof (char *),
+        ggc_compare_addresses);
+
   ggc_mark_roots ();
 
+  /* Free the string table.  */
+  VARRAY_FREE (ggc_allocated_strings);
+
   /* Sweep the resulting dead nodes.  */
 
   /* The RTXs.  */
index 49a8df007492984002f504e4907d82311d1f37e2..92b29f1f0e7b749b54f7775c05d3441b4d78310e 100644 (file)
--- a/gcc/ggc.h
+++ b/gcc/ggc.h
@@ -66,6 +66,10 @@ extern void ggc_mark_roots PROTO((void));
 extern void ggc_mark_rtx_children PROTO ((struct rtx_def *));
 extern void ggc_mark_tree_children PROTO ((union tree_node *));
 
+/* Mark the string, but only if it was allocated in collectable
+   memory.  */
+extern void ggc_mark_string_if_gcable PROTO ((char *));
+
 #define ggc_mark_rtx(RTX_EXPR)                         \
   do {                                                 \
     rtx r__ = (RTX_EXPR);                              \
@@ -87,11 +91,11 @@ extern void init_ggc PROTO ((void));
 
 /* Start a new GGC context.  Memory allocated in previous contexts
    will not be collected while the new context is active.  */
-extern void ggc_pop_context PROTO ((void));
+extern void ggc_push_context PROTO ((void));
 
 /* Finish a GC context.  Any uncollected memory in the new context
    will be merged with the old context.  */
-extern void ggc_push_context PROTO ((void));
+extern void ggc_pop_context PROTO ((void));
 
 /* Allocation.  */
 struct rtx_def *ggc_alloc_rtx PROTO ((int nslots));
@@ -113,7 +117,6 @@ int ggc_set_mark_rtx PROTO ((struct rtx_def *));
 int ggc_set_mark_rtvec PROTO ((struct rtvec_def *));
 int ggc_set_mark_tree PROTO ((union tree_node *));
 
-
 /* Callbacks to the languages.  */
 
 /* This is the language's opportunity to mark nodes held through