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]

ggc-simple tweeks


Due to the padding involved, tagging ggc_any structs with magic
costs nothing and gains just the tinyest touch of sanity. 

Strings get tucked into rtl all over, and there are known places
in rtl and trees that we look to mark strings.  The new anonymous
gc memory, on the other hand, is never looked for automatically
in rtl or trees -- every place it gets marked, we're doing so 
explicitly.  (And there aren't so many of those yet.)  So I turned
on an abort if the ggc_any magic number doesn't match.

Status update -- for C, alpha now has no regressions gc or no,
and only one regression from 2.95, which has been in mainline for
about a week.

I think I'd have to do what's needed to make cc1obj work before we
could legitimately turn on gc in the C front end, since c-decl.c
is shared between the two.


r~

        * 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.

Index: ggc-simple.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/ggc-simple.c,v
retrieving revision 1.11
diff -c -p -d -r1.11 ggc-simple.c
*** ggc-simple.c	1999/09/09 07:07:38	1.11
--- ggc-simple.c	1999/09/09 10:36:27
***************
*** 36,41 ****
--- 36,53 ----
     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
*************** struct ggc_tree
*** 70,76 ****
  struct ggc_string
  {
    struct ggc_string *chain;
!   int magic_mark;
    char string[1];
  };
  
--- 82,88 ----
  struct ggc_string
  {
    struct ggc_string *chain;
!   unsigned int magic_mark;
    char string[1];
  };
  
*************** struct ggc_string
*** 79,85 ****
  struct ggc_any
  {
    struct ggc_any *chain;
!   char mark;
  
    /* Make sure the data is reasonably aligned.  */
    union {
--- 91,97 ----
  struct ggc_any
  {
    struct ggc_any *chain;
!   unsigned int magic_mark;
  
    /* Make sure the data is reasonably aligned.  */
    union {
*************** struct ggc_any
*** 89,96 ****
    } u;
  };
  
- #define GGC_STRING_MAGIC	((unsigned int)0xa1b2c3d4)
- 
  struct ggc_status
  {
    struct ggc_status *next;
--- 101,106 ----
*************** static FILE *dump;
*** 122,128 ****
--- 132,142 ----
  /* 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));
*************** ggc_alloc_string (contents, length)
*** 290,302 ****
      }
  
    size = (s->string - (char *)s) + length + 1;
!   s = (struct ggc_string *) xmalloc(size);
    s->chain = ggc_chain->strings;
    s->magic_mark = GGC_STRING_MAGIC;
    if (contents)
!     bcopy (contents, s->string, length);
    s->string[length] = 0;
-   ggc_chain->strings = s;
  
  #ifdef GGC_DUMP
    fprintf(dump, "alloc string %p\n", &s->string);
--- 304,317 ----
      }
  
    size = (s->string - (char *)s) + length + 1;
!   s = (struct ggc_string *) xmalloc (size);
    s->chain = ggc_chain->strings;
    s->magic_mark = GGC_STRING_MAGIC;
+   ggc_chain->strings = s;
+ 
    if (contents)
!     memcpy (s->string, contents, length);
    s->string[length] = 0;
  
  #ifdef GGC_DUMP
    fprintf(dump, "alloc string %p\n", &s->string);
*************** ggc_alloc (bytes)
*** 321,334 ****
  
    a = (struct ggc_any *) xmalloc (bytes);
    a->chain = ggc_chain->anys;
    ggc_chain->anys = a;
  
    return &a->u;
  }
  
  /* Freeing a bit of rtl is as simple as calling free.  */
  
! static void
  ggc_free_rtx (r)
       struct ggc_rtx *r;
  {
--- 336,352 ----
  
    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 inline void 
  ggc_free_rtx (r)
       struct ggc_rtx *r;
  {
*************** ggc_free_rtx (r)
*** 345,351 ****
  
  /* Freeing an rtvec is as simple as calling free.  */
  
! static void
  ggc_free_rtvec (v)
       struct ggc_rtvec *v;
  {
--- 363,369 ----
  
  /* Freeing an rtvec is as simple as calling free.  */
  
! static inline void
  ggc_free_rtvec (v)
       struct ggc_rtvec *v;
  {
*************** ggc_free_rtvec (v)
*** 363,369 ****
  /* 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
  ggc_free_tree (t)
       struct ggc_tree *t;
  {
--- 381,387 ----
  /* 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 inline void
  ggc_free_tree (t)
       struct ggc_tree *t;
  {
*************** ggc_free_tree (t)
*** 387,393 ****
  
  /* Freeing a string is as simple as calling free.  */
  
! static void
  ggc_free_string (s)
       struct ggc_string *s;
  {
--- 405,411 ----
  
  /* Freeing a string is as simple as calling free.  */
  
! static inline void
  ggc_free_string (s)
       struct ggc_string *s;
  {
*************** ggc_free_string (s)
*** 402,407 ****
--- 420,441 ----
    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
*************** void
*** 656,669 ****
  ggc_mark_string (s)
       char *s;
  {
!   unsigned int *magic = (unsigned int *)s - 1;
  
    if (s == NULL)
      return;
  
!   if ((*magic & ~(unsigned)1) != GGC_STRING_MAGIC)
      return;   /* abort? */
!   *magic = GGC_STRING_MAGIC | 1;
  }
  
  /* Mark P, allocated with ggc_alloc.  */
--- 690,705 ----
  ggc_mark_string (s)
       char *s;
  {
!   const ptrdiff_t d = (((struct ggc_string *) 0)->string - (char *) 0);
!   struct ggc_string *gs;
  
    if (s == NULL)
      return;
  
!   gs = (struct ggc_string *)(s - d);
!   if (IGNORE_MARK (gs->magic_mark) != GGC_STRING_MAGIC)
      return;   /* abort? */
!   gs->magic_mark = GGC_STRING_MAGIC_MARK;
  }
  
  /* Mark P, allocated with ggc_alloc.  */
*************** void
*** 672,681 ****
  ggc_mark (p)
       void *p;
  {
    struct ggc_any *a;
!   ptrdiff_t d = (&((struct ggc_any *) 0)->u.c - (char *) 0);
    a = (struct ggc_any *) (((char*) p) - d);
!   a->mark = 1;
  }
  
  /* The top level mark-and-sweep routine.  */
--- 708,723 ----
  ggc_mark (p)
       void *p;
  {
+   const ptrdiff_t d = (&((struct ggc_any *) 0)->u.c - (char *) 0);
    struct ggc_any *a;
! 
!   if (p == NULL)
!     return;
! 
    a = (struct ggc_any *) (((char*) p) - d);
!   if (IGNORE_MARK (a->magic_mark) != GGC_ANY_MAGIC)
!     abort ();
!   a->magic_mark = GGC_ANY_MAGIC_MARK;
  }
  
  /* The top level mark-and-sweep routine.  */
*************** ggc_collect ()
*** 692,698 ****
    struct ggc_any *a, **ap;
    int time, n_rtxs, n_trees, n_vecs, n_strings, n_anys;
  
! #if 0
    /* See if it's even worth our while.  */
    if (ggc_chain->bytes_alloced_since_gc < 64*1024)
      return;
--- 734,740 ----
    struct ggc_any *a, **ap;
    int time, n_rtxs, n_trees, n_vecs, n_strings, n_anys;
  
! #ifndef ENABLE_CHECKING
    /* See if it's even worth our while.  */
    if (ggc_chain->bytes_alloced_since_gc < 64*1024)
      return;
*************** ggc_collect ()
*** 715,721 ****
        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;
      }
  
    /* Mark through all the roots.  */
--- 757,763 ----
        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->magic_mark = GGC_ANY_MAGIC;
      }
  
    /* Mark through all the roots.  */
*************** ggc_collect ()
*** 803,809 ****
    while (s != NULL)
      {
        struct ggc_string *chain = s->chain;
!       if (!(s->magic_mark & 1))
          {
  	  ggc_free_string (s);
  	  *sp = chain;
--- 845,851 ----
    while (s != NULL)
      {
        struct ggc_string *chain = s->chain;
!       if (! IS_MARKED (s->magic_mark))
          {
  	  ggc_free_string (s);
  	  *sp = chain;
*************** ggc_collect ()
*** 824,832 ****
    while (a != NULL)
      {
        struct ggc_any *chain = a->chain;
!       if (!a->mark)
  	{
! 	  free (a);
  	  *ap = chain;
  	  n_anys++;
  	}
--- 866,874 ----
    while (a != NULL)
      {
        struct ggc_any *chain = a->chain;
!       if (! IS_MARKED (a->magic_mark))
  	{
! 	  ggc_free_any (a);
  	  *ap = chain;
  	  n_anys++;
  	}


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