From b086d5308de0d25444243f482f2f3d1dfd3a9a62 Mon Sep 17 00:00:00 2001 From: Trevor Saunders Date: Tue, 2 Sep 2014 22:46:00 +0000 Subject: support ggc hash_map and hash_set gcc/ChangeLog: * alloc-pool.c: Include coretypes.h. * cgraph.h, dbxout.c, dwarf2out.c, except.c, except.h, function.c, function.h, symtab.c, tree-cfg.c, tree-eh.c: Use hash_map and hash_set instead of htab. * ggc-page.c (in_gc): New variable. (ggc_free): Do nothing if a collection is taking place. (ggc_collect): Set in_gc appropriately. * ggc.h (gt_ggc_mx(const char *)): New function. (gt_pch_nx(const char *)): Likewise. (gt_ggc_mx(int)): Likewise. (gt_pch_nx(int)): Likewise. * hash-map.h (hash_map::hash_entry::ggc_mx): Likewise. (hash_map::hash_entry::pch_nx): Likewise. (hash_map::hash_entry::pch_nx_helper): Likewise. (hash_map::hash_map): Adjust. (hash_map::create_ggc): New function. (gt_ggc_mx): Likewise. (gt_pch_nx): Likewise. * hash-set.h (default_hashset_traits::ggc_mx): Likewise. (default_hashset_traits::pch_nx): Likewise. (hash_set::hash_entry::ggc_mx): Likewise. (hash_set::hash_entry::pch_nx): Likewise. (hash_set::hash_entry::pch_nx_helper): Likewise. (hash_set::hash_set): Adjust. (hash_set::create_ggc): New function. (hash_set::elements): Likewise. (gt_ggc_mx): Likewise. (gt_pch_nx): Likewise. * hash-table.h (hash_table::hash_table): Adjust. (hash_table::m_ggc): New member. (hash_table::~hash_table): Adjust. (hash_table::expand): Likewise. (hash_table::empty): Likewise. (gt_ggc_mx): New function. (hashtab_entry_note_pointers): Likewise. (gt_pch_nx): Likewise. From-SVN: r214834 --- gcc/hash-table.h | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 100 insertions(+), 9 deletions(-) (limited to 'gcc/hash-table.h') diff --git a/gcc/hash-table.h b/gcc/hash-table.h index 9c6a34a..c2a68fd 100644 --- a/gcc/hash-table.h +++ b/gcc/hash-table.h @@ -196,8 +196,11 @@ along with GCC; see the file COPYING3. If not see #ifndef TYPED_HASHTAB_H #define TYPED_HASHTAB_H +#include "ggc.h" #include "hashtab.h" +template class hash_map; +template class hash_set; /* The ordinary memory allocator. */ /* FIXME (crowl): This allocator may be extracted for wider sharing later. */ @@ -998,7 +1001,7 @@ class hash_table typedef typename Descriptor::compare_type compare_type; public: - hash_table (size_t); + explicit hash_table (size_t, bool ggc = false); ~hash_table (); /* Current size (in entries) of the hash table. */ @@ -1105,6 +1108,11 @@ public: } private: + template friend void gt_ggc_mx (hash_table *); + template friend void gt_pch_nx (hash_table *); + template friend void hashtab_entry_note_pointers (void *, void *, gt_pointer_operator, void *); + template friend void gt_pch_nx (hash_map *, gt_pointer_operator, void *); + template friend void gt_pch_nx (hash_set *, gt_pointer_operator, void *); value_type *find_empty_slot_for_expand (hashval_t); void expand (); @@ -1149,18 +1157,26 @@ private: /* Current size (in entries) of the hash table, as an index into the table of primes. */ unsigned int m_size_prime_index; + + /* if m_entries is stored in ggc memory. */ + bool m_ggc; }; template class Allocator> -hash_table::hash_table (size_t size) : - m_n_elements (0), m_n_deleted (0), m_searches (0), m_collisions (0) +hash_table::hash_table (size_t size, bool ggc) : + m_n_elements (0), m_n_deleted (0), m_searches (0), m_collisions (0), + m_ggc (ggc) { unsigned int size_prime_index; size_prime_index = hash_table_higher_prime_index (size); size = prime_tab[size_prime_index].prime; - m_entries = Allocator ::data_alloc (size); + if (!m_ggc) + m_entries = Allocator ::data_alloc (size); + else + m_entries = ggc_cleared_vec_alloc (size); + gcc_assert (m_entries != NULL); m_size = size; m_size_prime_index = size_prime_index; @@ -1173,7 +1189,10 @@ hash_table::~hash_table () if (!is_empty (m_entries[i]) && !is_deleted (m_entries[i])) Descriptor::remove (m_entries[i]); - Allocator ::data_free (m_entries); + if (!m_ggc) + Allocator ::data_free (m_entries); + else + ggc_free (m_entries); } /* Similar to find_slot, but without several unwanted side effects: @@ -1245,7 +1264,12 @@ hash_table::expand () nsize = osize; } - value_type *nentries = Allocator ::data_alloc (nsize); + value_type *nentries; + if (!m_ggc) + nentries = Allocator ::data_alloc (nsize); + else + nentries = ggc_cleared_vec_alloc (nsize); + gcc_assert (nentries != NULL); m_entries = nentries; m_size = nsize; @@ -1269,7 +1293,10 @@ hash_table::expand () } while (p < olimit); - Allocator ::data_free (oentries); + if (!m_ggc) + Allocator ::data_free (oentries); + else + ggc_free (oentries); } template class Allocator> @@ -1290,8 +1317,17 @@ hash_table::empty () int nindex = hash_table_higher_prime_index (1024 / sizeof (PTR)); int nsize = prime_tab[nindex].prime; - Allocator ::data_free (m_entries); - m_entries = Allocator ::data_alloc (nsize); + if (!m_ggc) + { + Allocator ::data_free (m_entries); + m_entries = Allocator ::data_alloc (nsize); + } + else + { + ggc_free (m_entries); + m_entries = ggc_cleared_vec_alloc (nsize); + } + m_size = nsize; m_size_prime_index = nindex; } @@ -1519,4 +1555,59 @@ hash_table::iterator::operator ++ () (ITER) != (HTAB).end () ? (RESULT = *(ITER) , true) : false; \ ++(ITER)) +/* ggc walking routines. */ + +template +static inline void +gt_ggc_mx (hash_table *h) +{ + typedef hash_table table; + + if (!ggc_test_and_set_mark (h->m_entries)) + return; + + for (size_t i = 0; i < h->m_size; i++) + { + if (table::is_empty (h->m_entries[i]) + || table::is_deleted (h->m_entries[i])) + continue; + + E::ggc_mx (h->m_entries[i]); + } +} + +template +static inline void +hashtab_entry_note_pointers (void *obj, void *h, gt_pointer_operator op, + void *cookie) +{ + hash_table *map = static_cast *> (h); + gcc_checking_assert (map->m_entries == obj); + for (size_t i = 0; i < map->m_size; i++) + { + typedef hash_table table; + if (table::is_empty (map->m_entries[i]) + || table::is_deleted (map->m_entries[i])) + continue; + + D::pch_nx (map->m_entries[i], op, cookie); + } +} + +template +static void +gt_pch_nx (hash_table *h) +{ + gcc_checking_assert (gt_pch_note_object (h->m_entries, h, + hashtab_entry_note_pointers)); + for (size_t i = 0; i < h->m_size; i++) + { + if (hash_table::is_empty (h->m_entries[i]) + || hash_table::is_deleted (h->m_entries[i])) + continue; + + D::pch_nx (h->m_entries[i]); + } +} + #endif /* TYPED_HASHTAB_H */ -- cgit v1.1