diff options
author | mmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4> | 1999-10-11 02:11:21 +0000 |
---|---|---|
committer | mmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4> | 1999-10-11 02:11:21 +0000 |
commit | e3691812c0f20274df52d34b0621d77309cffd75 (patch) | |
tree | 5036f98758c484314588bc1a1893a4651f5f4190 | |
parent | 8b16d5f984981430b5b95d6886bd411c1989ecfc (diff) | |
download | gcc-e3691812c0f20274df52d34b0621d77309cffd75.tar.gz |
* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@29897 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 18 | ||||
-rw-r--r-- | gcc/ggc-common.c | 2 | ||||
-rw-r--r-- | gcc/ggc-page.c | 54 | ||||
-rw-r--r-- | gcc/ggc-simple.c | 70 | ||||
-rw-r--r-- | gcc/ggc.h | 9 |
5 files changed, 141 insertions, 12 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ef282fe9cd6..0386a21f848 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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. diff --git a/gcc/ggc-common.c b/gcc/ggc-common.c index 5acde492d17..6df622e8e04 100644 --- a/gcc/ggc-common.c +++ b/gcc/ggc-common.c @@ -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; } } diff --git a/gcc/ggc-page.c b/gcc/ggc-page.c index 6b8e4684664..1b643e6fa03 100644 --- a/gcc/ggc-page.c +++ b/gcc/ggc-page.c @@ -258,6 +258,8 @@ static struct globals #define GGC_MIN_LAST_ALLOCATED (4 * 1024 * 1024) +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)); -/* 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; diff --git a/gcc/ggc-simple.c b/gcc/ggc-simple.c index 74a4d5ad5f2..d8ed4a15a53 100644 --- a/gcc/ggc-simple.c +++ b/gcc/ggc-simple.c @@ -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. */ diff --git a/gcc/ggc.h b/gcc/ggc.h index 49a8df00749..92b29f1f0e7 100644 --- 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 |