diff options
author | kenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-09-20 15:12:54 +0000 |
---|---|---|
committer | kenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-09-20 15:12:54 +0000 |
commit | 15d769aab42c4ea8a8863b8b37dee46c77155be0 (patch) | |
tree | 9f82325d87e923ce9de88e1e1f44c7643f7d9c53 /gcc/ggc-common.c | |
parent | 41f4d177c8884f82b1a6f3cf74af02cfd7e1c15c (diff) | |
download | gcc-15d769aab42c4ea8a8863b8b37dee46c77155be0.tar.gz |
* fold-const.c (hashtab.h): Include.
(int_const_binop): Remove FORSIZE arg and compute from type; all
callers changed.
Call size_int_type_wide for all single-word constants.
(size_htab_hash, size_htab_eq): New functions.
(size_int_type_wide): Rework to use hash table.
* ggc-common.c (hashtab.h): Include.
(struct d_htab_root): New struct.
(d_htab_roots): New variable.
(ggc_add_deletable_htab, ggc_htab_delete): New functions
(ggc_mark_roots): Handle deletable htabs.
* ggc-page.c (ggc_marked_p): New function.
* ggc-simple.c (ggc_marked_p): Likewise.
* ggc.h: Reformatting throughout.
(ggc_marked_p, ggc_add_deletable_htab): New declarations.
* tree.c (init_obstacks): Make type_hash_table a deletable root.
(type_hash_add): Allocate struct type_hash from GC memory.
(mark_hash_entry, mark_type_hash): Deleted.
(type_hash_marked_p, type_hash_mark): New functions.
* Makefile.in (ggc-common.o, fold-const.o): Include hashtab.h.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@45710 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ggc-common.c')
-rw-r--r-- | gcc/ggc-common.c | 85 |
1 files changed, 82 insertions, 3 deletions
diff --git a/gcc/ggc-common.c b/gcc/ggc-common.c index fe7cbe51d20..154d47b3f48 100644 --- a/gcc/ggc-common.c +++ b/gcc/ggc-common.c @@ -27,6 +27,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "tree.h" #include "tm_p.h" #include "hash.h" +#include "hashtab.h" #include "varray.h" #include "ggc.h" @@ -47,9 +48,10 @@ static void ggc_mark_tree_ptr PARAMS ((void *)); static void ggc_mark_rtx_varray_ptr PARAMS ((void *)); static void ggc_mark_tree_varray_ptr PARAMS ((void *)); static void ggc_mark_tree_hash_table_ptr PARAMS ((void *)); +static int ggc_htab_delete PARAMS ((void **, void *)); static void ggc_mark_trees PARAMS ((void)); static bool ggc_mark_tree_hash_table_entry PARAMS ((struct hash_entry *, - hash_table_key)); + hash_table_key)); /* Maintain global roots that are preserved during GC. */ @@ -166,12 +168,79 @@ ggc_del_root (base) abort(); } +/* Add a hash table to be scanned when all roots have been processed. We + delete any entry in the table that has not been marked. */ + +struct d_htab_root +{ + struct d_htab_root *next; + htab_t htab; + ggc_htab_marked_p marked_p; + ggc_htab_mark mark; +}; + +static struct d_htab_root *d_htab_roots; + +/* Add X, an htab, to a list of htabs that contain objects which are allocated + from GC memory. Once all other roots are marked, we check each object in + the htab to see if it has already been marked. If not, it is deleted. + + MARKED_P, if specified, is a function that returns 1 if the entry is to + be considered as "marked". If not present, the data structure pointed to + by the htab slot is tested. This function should be supplied if some + other object (such as something pointed to by that object) should be tested + in which case the function tests whether that object (or objects) are + marked (using ggc_marked_p) and returns nonzero if it is. + + MARK, if specified, is a function that is passed the contents of a slot + that has been determined to have been "marked" (via the above function) + and marks any other objects pointed to by that object. For example, + we might have a hash table of memory attribute blocks, which are pointed + to by a MEM RTL but have a pointer to a DECL. MARKED_P in that case will + not be specified because we want to know if the attribute block is pointed + to by the MEM, but MARK must be specified because if the block has been + marked, we need to mark the DECL. */ + +void +ggc_add_deletable_htab (x, marked_p, mark) + PTR x; + ggc_htab_marked_p marked_p; + ggc_htab_mark mark; +{ + struct d_htab_root *r + = (struct d_htab_root *) xmalloc (sizeof (struct d_htab_root)); + + r->next = d_htab_roots; + r->htab = (htab_t) x; + r->marked_p = marked_p ? marked_p : ggc_marked_p; + r->mark = mark; + d_htab_roots = r; +} + +/* Process a slot of an htab by deleting it if it has not been marked. */ + +static int +ggc_htab_delete (slot, info) + void **slot; + void *info; +{ + struct d_htab_root *r = (struct d_htab_root *) info; + + if (! (*r->marked_p) (*slot)) + htab_clear_slot (r->htab, slot); + else if (r->mark) + (*r->mark) (*slot); + + return 1; +} + /* Iterate through all registered roots and mark each element. */ void ggc_mark_roots () { - struct ggc_root* x; + struct ggc_root *x; + struct d_htab_root *y; VARRAY_TREE_INIT (ggc_pending_trees, 4096, "ggc_pending_trees"); @@ -189,6 +258,16 @@ ggc_mark_roots () /* Mark all the queued up trees, and their children. */ ggc_mark_trees (); VARRAY_FREE (ggc_pending_trees); + + /* Now scan all hash tables that have objects which are to be deleted if + they are not already marked. Since these may mark more trees, we need + to reinitialize that varray. */ + VARRAY_TREE_INIT (ggc_pending_trees, 1024, "ggc_pending_trees"); + + for (y = d_htab_roots; y != NULL; y = y->next) + htab_traverse (y->htab, ggc_htab_delete, (PTR) y); + ggc_mark_trees (); + VARRAY_FREE (ggc_pending_trees); } /* R had not been previously marked, but has now been marked via @@ -463,7 +542,7 @@ ggc_mark_tree_varray (v) ggc_mark_tree (VARRAY_TREE (v, i)); } -/* Mark the hash table-entry HE. It's key field is really a tree. */ +/* Mark the hash table-entry HE. Its key field is really a tree. */ static bool ggc_mark_tree_hash_table_entry (he, k) |