From 9b1b9cc9100dc238f7ad0e1efd87e08bbe7b2957 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Thu, 9 Sep 1999 03:43:57 -0700 Subject: [PATCH] ggc-simple.c (IS_MARKED, [...]): New. * 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 | 14 ++++++++ gcc/ggc-simple.c | 84 ++++++++++++++++++++++++++++++++++++------------ 2 files changed, 77 insertions(+), 21 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c8a600c846f..f08ad94e7c6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +Thu Sep 9 03:37:31 1999 Richard Henderson + + * 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 * config/arm/linux-elf.h: define NO_IMPLICIT_EXTERN_C diff --git a/gcc/ggc-simple.c b/gcc/ggc-simple.c index e4064a8140b..df5c0cde5e0 100644 --- a/gcc/ggc-simple.c +++ b/gcc/ggc-simple.c @@ -36,6 +36,18 @@ 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++; } -- 2.30.2