ggc-simple.c (IS_MARKED, [...]): New.
authorRichard Henderson <rth@cygnus.com>
Thu, 9 Sep 1999 10:43:57 +0000 (03:43 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Thu, 9 Sep 1999 10:43:57 +0000 (03:43 -0700)
        * ggc-simple.c (IS_MARKED, IGNORE_MARK): New.
        (GGC_ANY_MAGIC, GGC_ANY_MAGIC_MARK): New.
        (struct ggc_any): Replace `mark' with `magic_mark'.
        (ggc_alloc_string): Use memcpy, not bcopy.
        (ggc_alloc_any): Set magic_mark.  Update bytes_alloced_since_gc.
        (ggc_free_{rtx,rtvec,tree,string}): Mark inline.
        (ggc_free_any): New.
        (ggc_mark_string): Use IGNORE_MARK.  Calc back to struct gcc_string.
        (ggc_mark): Use IGNORE_MARK.  Abort if magic doesn't match.
        (ggc_collect): Re-enable collection avoidance.  Use GGC_ANY_MARK.
        Use IS_MARKED. Use ggc_free_any.

From-SVN: r29231

gcc/ChangeLog
gcc/ggc-simple.c

index c8a600c846f28dfa91a27933a4c84324f52e8579..f08ad94e7c6fcab75149030d08d52c1c018f6033 100644 (file)
@@ -1,3 +1,17 @@
+Thu Sep  9 03:37:31 1999  Richard Henderson  <rth@cygnus.com>
+
+       * ggc-simple.c (IS_MARKED, IGNORE_MARK): New.
+       (GGC_ANY_MAGIC, GGC_ANY_MAGIC_MARK): New.
+       (struct ggc_any): Replace `mark' with `magic_mark'.
+       (ggc_alloc_string): Use memcpy, not bcopy.
+       (ggc_alloc_any): Set magic_mark.  Update bytes_alloced_since_gc.
+       (ggc_free_{rtx,rtvec,tree,string}): Mark inline.
+       (ggc_free_any): New.
+       (ggc_mark_string): Use IGNORE_MARK.  Calc back to struct gcc_string.
+       (ggc_mark): Use IGNORE_MARK.  Abort if magic doesn't match.
+       (ggc_collect): Re-enable collection avoidance.  Use GGC_ANY_MARK.
+       Use IS_MARKED. Use ggc_free_any.
+
 1999-09-09  Scott Bambrough <scottb@netwinder.org>
  
        * config/arm/linux-elf.h: define NO_IMPLICIT_EXTERN_C
index e4064a8140b139c77a13d4cb06d12d46bfac912d..df5c0cde5e01ee5f9431db7eb912496f768043a5 100644 (file)
    really really lot of data.  */
 #undef GGC_DUMP
 
+/* Some magic tags for strings and anonymous memory, hoping to catch
+   certain errors wrt marking memory.  */
+
+#define IS_MARKED(X)           ((X) & 1)
+#define IGNORE_MARK(X)         ((X) & -2)
+
+#define GGC_STRING_MAGIC       ((unsigned int)0xa1b2c3d4)
+#define GGC_STRING_MAGIC_MARK  ((unsigned int)0xa1b2c3d4 | 1)
+
+#define GGC_ANY_MAGIC          ((unsigned int)0xa9bacbdc)
+#define GGC_ANY_MAGIC_MARK     ((unsigned int)0xa9bacbdc | 1)
+
 /* Global lists of roots, rtxs, and trees.  */
 
 struct ggc_root
@@ -70,7 +82,7 @@ struct ggc_tree
 struct ggc_string
 {
   struct ggc_string *chain;
-  int magic_mark;
+  unsigned int magic_mark;
   char string[1];
 };
 
@@ -79,7 +91,7 @@ struct ggc_string
 struct ggc_any
 {
   struct ggc_any *chain;
-  char mark;
+  unsigned int magic_mark;
 
   /* Make sure the data is reasonably aligned.  */
   union {
@@ -89,8 +101,6 @@ struct ggc_any
   } u;
 };
 
-#define GGC_STRING_MAGIC       ((unsigned int)0xa1b2c3d4)
-
 struct ggc_status
 {
   struct ggc_status *next;
@@ -122,7 +132,11 @@ static FILE *dump;
 /* Local function prototypes.  */
 
 static void ggc_free_rtx PROTO ((struct ggc_rtx *r));
+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 void ggc_mark_rtx_ptr PROTO ((void *elt));
 static void ggc_mark_tree_ptr PROTO ((void *elt));
 static void ggc_mark_string_ptr PROTO ((void *elt));
@@ -290,13 +304,14 @@ ggc_alloc_string (contents, length)
     }
 
   size = (s->string - (char *)s) + length + 1;
-  s = (struct ggc_string *) xmalloc(size);
+  s = (struct ggc_string *) xmalloc (size);
   s->chain = ggc_chain->strings;
   s->magic_mark = GGC_STRING_MAGIC;
+  ggc_chain->strings = s;
+
   if (contents)
-    bcopy (contents, s->string, length);
+    memcpy (s->string, contents, length);
   s->string[length] = 0;
-  ggc_chain->strings = s;
 
 #ifdef GGC_DUMP
   fprintf(dump, "alloc string %p\n", &s->string);
@@ -321,14 +336,17 @@ ggc_alloc (bytes)
 
   a = (struct ggc_any *) xmalloc (bytes);
   a->chain = ggc_chain->anys;
+  a->magic_mark = GGC_ANY_MAGIC;
   ggc_chain->anys = a;
 
+  ggc_chain->bytes_alloced_since_gc += bytes;
+
   return &a->u;
 }
 
 /* Freeing a bit of rtl is as simple as calling free.  */
 
-static void
+static inline void 
 ggc_free_rtx (r)
      struct ggc_rtx *r;
 {
@@ -345,7 +363,7 @@ ggc_free_rtx (r)
 
 /* Freeing an rtvec is as simple as calling free.  */
 
-static void
+static inline void
 ggc_free_rtvec (v)
      struct ggc_rtvec *v;
 {
@@ -363,7 +381,7 @@ ggc_free_rtvec (v)
 /* Freeing a tree node is almost, but not quite, as simple as calling free.
    Mostly we need to let the language clean up its lang_specific bits.  */
 
-static void
+static inline void
 ggc_free_tree (t)
      struct ggc_tree *t;
 {
@@ -387,7 +405,7 @@ ggc_free_tree (t)
 
 /* Freeing a string is as simple as calling free.  */
 
-static void
+static inline void
 ggc_free_string (s)
      struct ggc_string *s;
 {
@@ -402,6 +420,22 @@ ggc_free_string (s)
   free (s);
 }
 
+/* Freeing anonymous memory is as simple as calling free.  */
+
+static inline void
+ggc_free_any (a)
+     struct ggc_any *a;
+{
+#ifdef GGC_DUMP
+  fprintf(dump, "collect mem %p\n", &a->u);
+#endif
+#ifdef GGC_POISON
+  a->magic_mark = 0xEEEEEEEE;
+#endif
+
+  free (a);
+}
+
 /* Mark a node.  */
 
 void
@@ -656,14 +690,16 @@ void
 ggc_mark_string (s)
      char *s;
 {
-  unsigned int *magic = (unsigned int *)s - 1;
+  const ptrdiff_t d = (((struct ggc_string *) 0)->string - (char *) 0);
+  struct ggc_string *gs;
 
   if (s == NULL)
     return;
 
-  if ((*magic & ~(unsigned)1) != GGC_STRING_MAGIC)
+  gs = (struct ggc_string *)(s - d);
+  if (IGNORE_MARK (gs->magic_mark) != GGC_STRING_MAGIC)
     return;   /* abort? */
-  *magic = GGC_STRING_MAGIC | 1;
+  gs->magic_mark = GGC_STRING_MAGIC_MARK;
 }
 
 /* Mark P, allocated with ggc_alloc.  */
@@ -672,10 +708,16 @@ void
 ggc_mark (p)
      void *p;
 {
+  const ptrdiff_t d = (&((struct ggc_any *) 0)->u.c - (char *) 0);
   struct ggc_any *a;
-  ptrdiff_t d = (&((struct ggc_any *) 0)->u.c - (char *) 0);
+
+  if (p == NULL)
+    return;
+
   a = (struct ggc_any *) (((char*) p) - d);
-  a->mark = 1;
+  if (IGNORE_MARK (a->magic_mark) != GGC_ANY_MAGIC)
+    abort ();
+  a->magic_mark = GGC_ANY_MAGIC_MARK;
 }
 
 /* The top level mark-and-sweep routine.  */
@@ -692,7 +734,7 @@ ggc_collect ()
   struct ggc_any *a, **ap;
   int time, n_rtxs, n_trees, n_vecs, n_strings, n_anys;
 
-#if 0
+#ifndef ENABLE_CHECKING
   /* See if it's even worth our while.  */
   if (ggc_chain->bytes_alloced_since_gc < 64*1024)
     return;
@@ -715,7 +757,7 @@ ggc_collect ()
       for (s = gs->strings; s != NULL; s = s->chain)
        s->magic_mark = GGC_STRING_MAGIC;
       for (a = gs->anys; a != NULL; a = a->chain)
-       a->mark = 0;
+       a->magic_mark = GGC_ANY_MAGIC;
     }
 
   /* Mark through all the roots.  */
@@ -803,7 +845,7 @@ ggc_collect ()
   while (s != NULL)
     {
       struct ggc_string *chain = s->chain;
-      if (!(s->magic_mark & 1))
+      if (! IS_MARKED (s->magic_mark))
         {
          ggc_free_string (s);
          *sp = chain;
@@ -824,9 +866,9 @@ ggc_collect ()
   while (a != NULL)
     {
       struct ggc_any *chain = a->chain;
-      if (!a->mark)
+      if (! IS_MARKED (a->magic_mark))
        {
-         free (a);
+         ggc_free_any (a);
          *ap = chain;
          n_anys++;
        }