]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/hash-table.h
cgraph.h (asmname_hasher): Inherit from ggc_ptr_hash.
[thirdparty/gcc.git] / gcc / hash-table.h
CommitLineData
0823efed 1/* A type-safe hash table template.
5624e564 2 Copyright (C) 2012-2015 Free Software Foundation, Inc.
0823efed
DN
3 Contributed by Lawrence Crowl <crowl@google.com>
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 3, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
20
21
22/* This file implements a typed hash table.
5831a5f0
LC
23 The implementation borrows from libiberty's htab_t in hashtab.h.
24
25
26 INTRODUCTION TO TYPES
27
28 Users of the hash table generally need to be aware of three types.
29
30 1. The type being placed into the hash table. This type is called
31 the value type.
32
33 2. The type used to describe how to handle the value type within
34 the hash table. This descriptor type provides the hash table with
35 several things.
36
37 - A typedef named 'value_type' to the value type (from above).
38
39 - A static member function named 'hash' that takes a value_type
40 pointer and returns a hashval_t value.
41
42 - A typedef named 'compare_type' that is used to test when an value
43 is found. This type is the comparison type. Usually, it will be the
44 same as value_type. If it is not the same type, you must generally
45 explicitly compute hash values and pass them to the hash table.
46
47 - A static member function named 'equal' that takes a value_type
48 pointer and a compare_type pointer, and returns a bool.
49
50 - A static function named 'remove' that takes an value_type pointer
51 and frees the memory allocated by it. This function is used when
52 individual elements of the table need to be disposed of (e.g.,
53 when deleting a hash table, removing elements from the table, etc).
54
08ec2754
RS
55 - An optional static function named 'keep_cache_entry'. This
56 function is provided only for garbage-collected elements that
57 are not marked by the normal gc mark pass. It describes what
58 what should happen to the element at the end of the gc mark phase.
59 The return value should be:
60 - 0 if the element should be deleted
61 - 1 if the element should be kept and needs to be marked
62 - -1 if the element should be kept and is already marked.
63 Returning -1 rather than 1 is purely an optimization.
64
5831a5f0
LC
65 3. The type of the hash table itself. (More later.)
66
67 In very special circumstances, users may need to know about a fourth type.
68
69 4. The template type used to describe how hash table memory
70 is allocated. This type is called the allocator type. It is
71 parameterized on the value type. It provides four functions.
72
5831a5f0
LC
73 - A static member function named 'data_alloc'. This function
74 allocates the data elements in the table.
75
76 - A static member function named 'data_free'. This function
77 deallocates the data elements in the table.
78
79 Hash table are instantiated with two type arguments.
80
81 * The descriptor type, (2) above.
82
83 * The allocator type, (4) above. In general, you will not need to
84 provide your own allocator type. By default, hash tables will use
85 the class template xcallocator, which uses malloc/free for allocation.
86
87
88 DEFINING A DESCRIPTOR TYPE
89
90 The first task in using the hash table is to describe the element type.
91 We compose this into a few steps.
92
93 1. Decide on a removal policy for values stored in the table.
6c907cff 94 hash-traits.h provides class templates for the four most common
ca752f39 95 policies:
5831a5f0
LC
96
97 * typed_free_remove implements the static 'remove' member function
98 by calling free().
99
100 * typed_noop_remove implements the static 'remove' member function
101 by doing nothing.
102
ca752f39
RS
103 * ggc_remove implements the static 'remove' member by doing nothing,
104 but instead provides routines for gc marking and for PCH streaming.
105 Use this for garbage-collected data that needs to be preserved across
106 collections.
107
6c907cff
RS
108 * ggc_cache_remove is like ggc_remove, except that it does not
109 mark the entries during the normal gc mark phase. Instead it
110 uses 'keep_cache_entry' (described above) to keep elements that
111 were not collected and delete those that were. Use this for
112 garbage-collected caches that should not in themselves stop
113 the data from being collected.
114
5831a5f0
LC
115 You can use these policies by simply deriving the descriptor type
116 from one of those class template, with the appropriate argument.
117
118 Otherwise, you need to write the static 'remove' member function
119 in the descriptor class.
120
121 2. Choose a hash function. Write the static 'hash' member function.
122
123 3. Choose an equality testing function. In most cases, its two
124 arguments will be value_type pointers. If not, the first argument must
125 be a value_type pointer, and the second argument a compare_type pointer.
126
127
128 AN EXAMPLE DESCRIPTOR TYPE
129
130 Suppose you want to put some_type into the hash table. You could define
131 the descriptor type as follows.
132
8d67ee55
RS
133 struct some_type_hasher : nofree_ptr_hash <some_type>
134 // Deriving from nofree_ptr_hash means that we get a 'remove' that does
5831a5f0
LC
135 // nothing. This choice is good for raw values.
136 {
5831a5f0
LC
137 static inline hashval_t hash (const value_type *);
138 static inline bool equal (const value_type *, const compare_type *);
139 };
140
141 inline hashval_t
142 some_type_hasher::hash (const value_type *e)
143 { ... compute and return a hash value for E ... }
144
145 inline bool
146 some_type_hasher::equal (const value_type *p1, const compare_type *p2)
147 { ... compare P1 vs P2. Return true if they are the 'same' ... }
148
149
150 AN EXAMPLE HASH_TABLE DECLARATION
151
152 To instantiate a hash table for some_type:
153
154 hash_table <some_type_hasher> some_type_hash_table;
155
156 There is no need to mention some_type directly, as the hash table will
157 obtain it using some_type_hasher::value_type.
158
159 You can then used any of the functions in hash_table's public interface.
160 See hash_table for details. The interface is very similar to libiberty's
161 htab_t.
162
163
164 EASY DESCRIPTORS FOR POINTERS
165
166 The class template pointer_hash provides everything you need to hash
167 pointers (as opposed to what they point to). So, to instantiate a hash
168 table over pointers to whatever_type,
169
170 hash_table <pointer_hash <whatever_type>> whatever_type_hash_table;
171
bf190e8d
LC
172
173 HASH TABLE ITERATORS
174
175 The hash table provides standard C++ iterators. For example, consider a
176 hash table of some_info. We wish to consume each element of the table:
177
178 extern void consume (some_info *);
179
180 We define a convenience typedef and the hash table:
181
182 typedef hash_table <some_info_hasher> info_table_type;
183 info_table_type info_table;
184
185 Then we write the loop in typical C++ style:
186
187 for (info_table_type::iterator iter = info_table.begin ();
188 iter != info_table.end ();
189 ++iter)
190 if ((*iter).status == INFO_READY)
191 consume (&*iter);
192
193 Or with common sub-expression elimination:
194
195 for (info_table_type::iterator iter = info_table.begin ();
196 iter != info_table.end ();
197 ++iter)
198 {
199 some_info &elem = *iter;
200 if (elem.status == INFO_READY)
201 consume (&elem);
202 }
203
204 One can also use a more typical GCC style:
205
206 typedef some_info *some_info_p;
207 some_info *elem_ptr;
208 info_table_type::iterator iter;
209 FOR_EACH_HASH_TABLE_ELEMENT (info_table, elem_ptr, some_info_p, iter)
210 if (elem_ptr->status == INFO_READY)
211 consume (elem_ptr);
212
5831a5f0 213*/
0823efed
DN
214
215
216#ifndef TYPED_HASHTAB_H
217#define TYPED_HASHTAB_H
218
13fdf2e2 219#include "statistics.h"
b086d530 220#include "ggc.h"
13fdf2e2 221#include "vec.h"
0823efed 222#include "hashtab.h"
13fdf2e2 223#include "inchash.h"
2d44c7de 224#include "mem-stats-traits.h"
f11c3779 225#include "hash-traits.h"
13fdf2e2 226#include "hash-map-traits.h"
0823efed 227
b086d530
TS
228template<typename, typename, typename> class hash_map;
229template<typename, typename> class hash_set;
0823efed
DN
230
231/* The ordinary memory allocator. */
232/* FIXME (crowl): This allocator may be extracted for wider sharing later. */
233
234template <typename Type>
235struct xcallocator
236{
0823efed 237 static Type *data_alloc (size_t count);
0823efed
DN
238 static void data_free (Type *memory);
239};
240
241
5831a5f0 242/* Allocate memory for COUNT data blocks. */
0823efed
DN
243
244template <typename Type>
245inline Type *
246xcallocator <Type>::data_alloc (size_t count)
247{
248 return static_cast <Type *> (xcalloc (count, sizeof (Type)));
249}
250
251
0823efed
DN
252/* Free memory for data blocks. */
253
254template <typename Type>
255inline void
256xcallocator <Type>::data_free (Type *memory)
257{
258 return ::free (memory);
259}
260
261
0823efed
DN
262/* Table of primes and their inversion information. */
263
264struct prime_ent
265{
266 hashval_t prime;
267 hashval_t inv;
268 hashval_t inv_m2; /* inverse of prime-2 */
269 hashval_t shift;
270};
271
272extern struct prime_ent const prime_tab[];
273
274
275/* Functions for computing hash table indexes. */
276
6db4bc6e
JH
277extern unsigned int hash_table_higher_prime_index (unsigned long n)
278 ATTRIBUTE_PURE;
279
280/* Return X % Y using multiplicative inverse values INV and SHIFT.
281
282 The multiplicative inverses computed above are for 32-bit types,
283 and requires that we be able to compute a highpart multiply.
284
285 FIX: I am not at all convinced that
286 3 loads, 2 multiplications, 3 shifts, and 3 additions
287 will be faster than
288 1 load and 1 modulus
289 on modern systems running a compiler. */
290
291inline hashval_t
292mul_mod (hashval_t x, hashval_t y, hashval_t inv, int shift)
293{
294 hashval_t t1, t2, t3, t4, q, r;
295
296 t1 = ((uint64_t)x * inv) >> 32;
297 t2 = x - t1;
298 t3 = t2 >> 1;
299 t4 = t1 + t3;
300 q = t4 >> shift;
301 r = x - (q * y);
302
303 return r;
304}
305
306/* Compute the primary table index for HASH given current prime index. */
307
308inline hashval_t
309hash_table_mod1 (hashval_t hash, unsigned int index)
310{
311 const struct prime_ent *p = &prime_tab[index];
312 gcc_checking_assert (sizeof (hashval_t) * CHAR_BIT <= 32);
313 return mul_mod (hash, p->prime, p->inv, p->shift);
314}
315
316/* Compute the secondary table index for HASH given current prime index. */
317
318inline hashval_t
319hash_table_mod2 (hashval_t hash, unsigned int index)
320{
321 const struct prime_ent *p = &prime_tab[index];
322 gcc_checking_assert (sizeof (hashval_t) * CHAR_BIT <= 32);
323 return 1 + mul_mod (hash, p->prime - 2, p->inv_m2, p->shift);
324}
0823efed 325
84baa4b9
TS
326 template<typename Traits>
327 struct has_is_deleted
328{
329 template<typename U, bool (*)(U &)> struct helper {};
330 template<typename U> static char test (helper<U, U::is_deleted> *);
331 template<typename U> static int test (...);
332 static const bool value = sizeof (test<Traits> (0)) == sizeof (char);
333};
334
335template<typename Type, typename Traits, bool = has_is_deleted<Traits>::value>
336struct is_deleted_helper
337{
338 static inline bool
339 call (Type &v)
340 {
341 return Traits::is_deleted (v);
342 }
343};
344
345template<typename Type, typename Traits>
346struct is_deleted_helper<Type *, Traits, false>
347{
348 static inline bool
349 call (Type *v)
350 {
351 return v == HTAB_DELETED_ENTRY;
352 }
353};
354
355 template<typename Traits>
356 struct has_is_empty
357{
358 template<typename U, bool (*)(U &)> struct helper {};
359 template<typename U> static char test (helper<U, U::is_empty> *);
360 template<typename U> static int test (...);
361 static const bool value = sizeof (test<Traits> (0)) == sizeof (char);
362};
363
364template<typename Type, typename Traits, bool = has_is_deleted<Traits>::value>
365struct is_empty_helper
366{
367 static inline bool
368 call (Type &v)
369 {
370 return Traits::is_empty (v);
371 }
372};
373
374template<typename Type, typename Traits>
375struct is_empty_helper<Type *, Traits, false>
376{
377 static inline bool
378 call (Type *v)
379 {
380 return v == HTAB_EMPTY_ENTRY;
381 }
382};
383
384 template<typename Traits>
385 struct has_mark_deleted
386{
387 template<typename U, void (*)(U &)> struct helper {};
388 template<typename U> static char test (helper<U, U::mark_deleted> *);
389 template<typename U> static int test (...);
390 static const bool value = sizeof (test<Traits> (0)) == sizeof (char);
391};
392
393template<typename Type, typename Traits, bool = has_is_deleted<Traits>::value>
394struct mark_deleted_helper
395{
396 static inline void
397 call (Type &v)
398 {
399 Traits::mark_deleted (v);
400 }
401};
402
403template<typename Type, typename Traits>
404struct mark_deleted_helper<Type *, Traits, false>
405{
406 static inline void
407 call (Type *&v)
408 {
409 v = static_cast<Type *> (HTAB_DELETED_ENTRY);
410 }
411};
412
413 template<typename Traits>
414 struct has_mark_empty
415{
416 template<typename U, void (*)(U &)> struct helper {};
417 template<typename U> static char test (helper<U, U::mark_empty> *);
418 template<typename U> static int test (...);
419 static const bool value = sizeof (test<Traits> (0)) == sizeof (char);
420};
421
422template<typename Type, typename Traits, bool = has_is_deleted<Traits>::value>
423struct mark_empty_helper
424{
425 static inline void
426 call (Type &v)
427 {
428 Traits::mark_empty (v);
429 }
430};
431
432template<typename Type, typename Traits>
433struct mark_empty_helper<Type *, Traits, false>
434{
435 static inline void
436 call (Type *&v)
437 {
438 v = static_cast<Type *> (HTAB_EMPTY_ENTRY);
439 }
440};
0823efed 441
2d44c7de
ML
442class mem_usage;
443
0823efed
DN
444/* User-facing hash table type.
445
67f58944 446 The table stores elements of type Descriptor::value_type.
0823efed 447
5831a5f0 448 It hashes values with the hash member function.
0823efed 449 The table currently works with relatively weak hash functions.
5831a5f0 450 Use typed_pointer_hash <Value> when hashing pointers instead of objects.
0823efed 451
5831a5f0 452 It compares elements with the equal member function.
0823efed 453 Two elements with the same hash may not be equal.
5831a5f0 454 Use typed_pointer_equal <Value> when hashing pointers instead of objects.
0823efed 455
5831a5f0 456 It removes elements with the remove member function.
0823efed 457 This feature is useful for freeing memory.
5831a5f0
LC
458 Derive from typed_null_remove <Value> when not freeing objects.
459 Derive from typed_free_remove <Value> when doing a simple object free.
0823efed 460
5831a5f0 461 Specify the template Allocator to allocate and free memory.
0823efed
DN
462 The default is xcallocator.
463
84baa4b9
TS
464 Storage is an implementation detail and should not be used outside the
465 hash table code.
466
0823efed 467*/
5831a5f0 468template <typename Descriptor,
67f58944 469 template<typename Type> class Allocator = xcallocator>
0823efed 470class hash_table
84baa4b9
TS
471{
472 typedef typename Descriptor::value_type value_type;
473 typedef typename Descriptor::compare_type compare_type;
474
475public:
2d44c7de 476 explicit hash_table (size_t, bool ggc = false, bool gather_mem_stats = true,
643e0a30 477 mem_alloc_origin origin = HASH_TABLE_ORIGIN
2d44c7de 478 CXX_MEM_STAT_INFO);
84baa4b9
TS
479 ~hash_table ();
480
2a22f99c
TS
481 /* Create a hash_table in gc memory. */
482
483 static hash_table *
2d44c7de 484 create_ggc (size_t n CXX_MEM_STAT_INFO)
2a22f99c
TS
485 {
486 hash_table *table = ggc_alloc<hash_table> ();
643e0a30 487 new (table) hash_table (n, true, true, HASH_TABLE_ORIGIN PASS_MEM_STAT);
2a22f99c
TS
488 return table;
489 }
490
84baa4b9
TS
491 /* Current size (in entries) of the hash table. */
492 size_t size () const { return m_size; }
493
494 /* Return the current number of elements in this hash table. */
495 size_t elements () const { return m_n_elements - m_n_deleted; }
496
497 /* Return the current number of elements in this hash table. */
498 size_t elements_with_deleted () const { return m_n_elements; }
499
500 /* This function clears all entries in the given hash table. */
501 void empty ();
502
503 /* This function clears a specified SLOT in a hash table. It is
504 useful when you've already done the lookup and don't want to do it
505 again. */
506
507 void clear_slot (value_type *);
508
509 /* This function searches for a hash table entry equal to the given
510 COMPARABLE element starting with the given HASH value. It cannot
511 be used to insert or delete an element. */
512 value_type &find_with_hash (const compare_type &, hashval_t);
513
514/* Like find_slot_with_hash, but compute the hash value from the element. */
515 value_type &find (const value_type &value)
516 {
517 return find_with_hash (value, Descriptor::hash (value));
518 }
519
520 value_type *find_slot (const value_type &value, insert_option insert)
521 {
522 return find_slot_with_hash (value, Descriptor::hash (value), insert);
523 }
524
525 /* This function searches for a hash table slot containing an entry
526 equal to the given COMPARABLE element and starting with the given
527 HASH. To delete an entry, call this with insert=NO_INSERT, then
528 call clear_slot on the slot returned (possibly after doing some
529 checks). To insert an entry, call this with insert=INSERT, then
530 write the value you want into the returned slot. When inserting an
531 entry, NULL may be returned if memory allocation fails. */
532 value_type *find_slot_with_hash (const compare_type &comparable,
533 hashval_t hash, enum insert_option insert);
534
535 /* This function deletes an element with the given COMPARABLE value
536 from hash table starting with the given HASH. If there is no
537 matching element in the hash table, this function does nothing. */
538 void remove_elt_with_hash (const compare_type &, hashval_t);
539
540/* Like remove_elt_with_hash, but compute the hash value from the element. */
541 void remove_elt (const value_type &value)
542 {
543 remove_elt_with_hash (value, Descriptor::hash (value));
544 }
545
546 /* This function scans over the entire hash table calling CALLBACK for
547 each live entry. If CALLBACK returns false, the iteration stops.
548 ARGUMENT is passed as CALLBACK's second argument. */
549 template <typename Argument,
550 int (*Callback) (value_type *slot, Argument argument)>
551 void traverse_noresize (Argument argument);
552
553 /* Like traverse_noresize, but does resize the table when it is too empty
554 to improve effectivity of subsequent calls. */
555 template <typename Argument,
556 int (*Callback) (value_type *slot, Argument argument)>
557 void traverse (Argument argument);
558
559 class iterator
560 {
561 public:
562 iterator () : m_slot (NULL), m_limit (NULL) {}
563
564 iterator (value_type *slot, value_type *limit) :
565 m_slot (slot), m_limit (limit) {}
566
567 inline value_type &operator * () { return *m_slot; }
568 void slide ();
569 inline iterator &operator ++ ();
570 bool operator != (const iterator &other) const
571 {
572 return m_slot != other.m_slot || m_limit != other.m_limit;
573 }
574
575 private:
576 value_type *m_slot;
577 value_type *m_limit;
578 };
579
580 iterator begin () const
581 {
582 iterator iter (m_entries, m_entries + m_size);
583 iter.slide ();
584 return iter;
585 }
586
587 iterator end () const { return iterator (); }
588
589 double collisions () const
590 {
591 return m_searches ? static_cast <double> (m_collisions) / m_searches : 0;
592 }
593
594private:
b086d530
TS
595 template<typename T> friend void gt_ggc_mx (hash_table<T> *);
596 template<typename T> friend void gt_pch_nx (hash_table<T> *);
2a22f99c
TS
597 template<typename T> friend void
598 hashtab_entry_note_pointers (void *, void *, gt_pointer_operator, void *);
599 template<typename T, typename U, typename V> friend void
600 gt_pch_nx (hash_map<T, U, V> *, gt_pointer_operator, void *);
601 template<typename T, typename U> friend void gt_pch_nx (hash_set<T, U> *,
602 gt_pointer_operator,
603 void *);
604 template<typename T> friend void gt_pch_nx (hash_table<T> *,
605 gt_pointer_operator, void *);
84baa4b9 606
08ec2754
RS
607 template<typename T> friend void gt_cleare_cache (hash_table<T> *);
608
61ebff31 609 value_type *alloc_entries (size_t n CXX_MEM_STAT_INFO) const;
84baa4b9
TS
610 value_type *find_empty_slot_for_expand (hashval_t);
611 void expand ();
612 static bool is_deleted (value_type &v)
613 {
614 return is_deleted_helper<value_type, Descriptor>::call (v);
615 }
616 static bool is_empty (value_type &v)
617 {
618 return is_empty_helper<value_type, Descriptor>::call (v);
619 }
620
621 static void mark_deleted (value_type &v)
622 {
623 return mark_deleted_helper<value_type, Descriptor>::call (v);
624 }
625
626 static void mark_empty (value_type &v)
627 {
628 return mark_empty_helper<value_type, Descriptor>::call (v);
629 }
630
631 /* Table itself. */
632 typename Descriptor::value_type *m_entries;
633
634 size_t m_size;
635
636 /* Current number of elements including also deleted elements. */
637 size_t m_n_elements;
638
639 /* Current number of deleted elements in the table. */
640 size_t m_n_deleted;
641
642 /* The following member is used for debugging. Its value is number
643 of all calls of `htab_find_slot' for the hash table. */
644 unsigned int m_searches;
645
646 /* The following member is used for debugging. Its value is number
647 of collisions fixed for time of work with the hash table. */
648 unsigned int m_collisions;
649
650 /* Current size (in entries) of the hash table, as an index into the
651 table of primes. */
652 unsigned int m_size_prime_index;
b086d530
TS
653
654 /* if m_entries is stored in ggc memory. */
655 bool m_ggc;
2d44c7de
ML
656
657 /* If we should gather memory statistics for the table. */
658 bool m_gather_mem_stats;
84baa4b9
TS
659};
660
2d44c7de
ML
661/* As mem-stats.h heavily utilizes hash maps (hash tables), we have to include
662 mem-stats.h after hash_table declaration. */
663
664#include "mem-stats.h"
665#include "hash-map.h"
2d44c7de
ML
666
667extern mem_alloc_description<mem_usage> hash_table_usage;
668
669/* Support function for statistics. */
670extern void dump_hash_table_loc_statistics (void);
671
84baa4b9 672template<typename Descriptor, template<typename Type> class Allocator>
2d44c7de
ML
673hash_table<Descriptor, Allocator>::hash_table (size_t size, bool ggc, bool
674 gather_mem_stats,
675 mem_alloc_origin origin
676 MEM_STAT_DECL) :
b086d530 677 m_n_elements (0), m_n_deleted (0), m_searches (0), m_collisions (0),
2d44c7de 678 m_ggc (ggc), m_gather_mem_stats (gather_mem_stats)
84baa4b9
TS
679{
680 unsigned int size_prime_index;
681
682 size_prime_index = hash_table_higher_prime_index (size);
683 size = prime_tab[size_prime_index].prime;
684
2d44c7de
ML
685 if (m_gather_mem_stats)
686 hash_table_usage.register_descriptor (this, origin, ggc
687 FINAL_PASS_MEM_STAT);
688
61ebff31 689 m_entries = alloc_entries (size PASS_MEM_STAT);
84baa4b9
TS
690 m_size = size;
691 m_size_prime_index = size_prime_index;
692}
693
694template<typename Descriptor, template<typename Type> class Allocator>
67f58944 695hash_table<Descriptor, Allocator>::~hash_table ()
84baa4b9
TS
696{
697 for (size_t i = m_size - 1; i < m_size; i--)
698 if (!is_empty (m_entries[i]) && !is_deleted (m_entries[i]))
699 Descriptor::remove (m_entries[i]);
700
b086d530
TS
701 if (!m_ggc)
702 Allocator <value_type> ::data_free (m_entries);
703 else
704 ggc_free (m_entries);
2d44c7de
ML
705
706 if (m_gather_mem_stats)
707 hash_table_usage.release_instance_overhead (this,
708 sizeof (value_type) * m_size,
709 true);
84baa4b9
TS
710}
711
1f012f56
TS
712/* This function returns an array of empty hash table elements. */
713
714template<typename Descriptor, template<typename Type> class Allocator>
67f58944
TS
715inline typename hash_table<Descriptor, Allocator>::value_type *
716hash_table<Descriptor, Allocator>::alloc_entries (size_t n MEM_STAT_DECL) const
1f012f56
TS
717{
718 value_type *nentries;
719
2d44c7de
ML
720 if (m_gather_mem_stats)
721 hash_table_usage.register_instance_overhead (sizeof (value_type) * n, this);
722
1f012f56
TS
723 if (!m_ggc)
724 nentries = Allocator <value_type> ::data_alloc (n);
725 else
61ebff31 726 nentries = ::ggc_cleared_vec_alloc<value_type> (n PASS_MEM_STAT);
1f012f56
TS
727
728 gcc_assert (nentries != NULL);
729 for (size_t i = 0; i < n; i++)
730 mark_empty (nentries[i]);
731
732 return nentries;
733}
734
84baa4b9
TS
735/* Similar to find_slot, but without several unwanted side effects:
736 - Does not call equal when it finds an existing entry.
737 - Does not change the count of elements/searches/collisions in the
738 hash table.
739 This function also assumes there are no deleted entries in the table.
740 HASH is the hash value for the element to be inserted. */
741
742template<typename Descriptor, template<typename Type> class Allocator>
67f58944
TS
743typename hash_table<Descriptor, Allocator>::value_type *
744hash_table<Descriptor, Allocator>::find_empty_slot_for_expand (hashval_t hash)
84baa4b9
TS
745{
746 hashval_t index = hash_table_mod1 (hash, m_size_prime_index);
747 size_t size = m_size;
748 value_type *slot = m_entries + index;
749 hashval_t hash2;
750
751 if (is_empty (*slot))
752 return slot;
6db4bc6e
JH
753#ifdef ENABLE_CHECKING
754 gcc_checking_assert (!is_deleted (*slot));
755#endif
84baa4b9
TS
756
757 hash2 = hash_table_mod2 (hash, m_size_prime_index);
758 for (;;)
759 {
760 index += hash2;
761 if (index >= size)
762 index -= size;
763
764 slot = m_entries + index;
765 if (is_empty (*slot))
766 return slot;
6db4bc6e
JH
767#ifdef ENABLE_CHECKING
768 gcc_checking_assert (!is_deleted (*slot));
769#endif
84baa4b9
TS
770 }
771}
772
773/* The following function changes size of memory allocated for the
774 entries and repeatedly inserts the table elements. The occupancy
775 of the table after the call will be about 50%. Naturally the hash
776 table must already exist. Remember also that the place of the
777 table entries is changed. If memory allocation fails, this function
778 will abort. */
779
780 template<typename Descriptor, template<typename Type> class Allocator>
781void
67f58944 782hash_table<Descriptor, Allocator>::expand ()
84baa4b9
TS
783{
784 value_type *oentries = m_entries;
785 unsigned int oindex = m_size_prime_index;
786 size_t osize = size ();
787 value_type *olimit = oentries + osize;
788 size_t elts = elements ();
789
790 /* Resize only when table after removal of unused elements is either
791 too full or too empty. */
792 unsigned int nindex;
793 size_t nsize;
794 if (elts * 2 > osize || (elts * 8 < osize && osize > 32))
795 {
796 nindex = hash_table_higher_prime_index (elts * 2);
797 nsize = prime_tab[nindex].prime;
798 }
799 else
800 {
801 nindex = oindex;
802 nsize = osize;
803 }
804
1f012f56 805 value_type *nentries = alloc_entries (nsize);
2d44c7de
ML
806
807 if (m_gather_mem_stats)
808 hash_table_usage.release_instance_overhead (this, sizeof (value_type)
809 * osize);
810
84baa4b9
TS
811 m_entries = nentries;
812 m_size = nsize;
813 m_size_prime_index = nindex;
814 m_n_elements -= m_n_deleted;
815 m_n_deleted = 0;
816
817 value_type *p = oentries;
818 do
819 {
820 value_type &x = *p;
821
822 if (!is_empty (x) && !is_deleted (x))
823 {
824 value_type *q = find_empty_slot_for_expand (Descriptor::hash (x));
825
826 *q = x;
827 }
828
829 p++;
830 }
831 while (p < olimit);
832
b086d530
TS
833 if (!m_ggc)
834 Allocator <value_type> ::data_free (oentries);
835 else
836 ggc_free (oentries);
84baa4b9
TS
837}
838
839template<typename Descriptor, template<typename Type> class Allocator>
840void
67f58944 841hash_table<Descriptor, Allocator>::empty ()
84baa4b9
TS
842{
843 size_t size = m_size;
844 value_type *entries = m_entries;
845 int i;
846
847 for (i = size - 1; i >= 0; i--)
848 if (!is_empty (entries[i]) && !is_deleted (entries[i]))
849 Descriptor::remove (entries[i]);
850
851 /* Instead of clearing megabyte, downsize the table. */
852 if (size > 1024*1024 / sizeof (PTR))
853 {
854 int nindex = hash_table_higher_prime_index (1024 / sizeof (PTR));
855 int nsize = prime_tab[nindex].prime;
856
b086d530 857 if (!m_ggc)
1f012f56 858 Allocator <value_type> ::data_free (m_entries);
b086d530 859 else
1f012f56 860 ggc_free (m_entries);
b086d530 861
1f012f56 862 m_entries = alloc_entries (nsize);
84baa4b9
TS
863 m_size = nsize;
864 m_size_prime_index = nindex;
865 }
866 else
867 memset (entries, 0, size * sizeof (value_type));
868 m_n_deleted = 0;
869 m_n_elements = 0;
870}
871
872/* This function clears a specified SLOT in a hash table. It is
873 useful when you've already done the lookup and don't want to do it
874 again. */
875
876template<typename Descriptor, template<typename Type> class Allocator>
877void
67f58944 878hash_table<Descriptor, Allocator>::clear_slot (value_type *slot)
84baa4b9 879{
6db4bc6e
JH
880 gcc_checking_assert (!(slot < m_entries || slot >= m_entries + size ()
881 || is_empty (*slot) || is_deleted (*slot)));
84baa4b9
TS
882
883 Descriptor::remove (*slot);
884
885 mark_deleted (*slot);
886 m_n_deleted++;
887}
888
889/* This function searches for a hash table entry equal to the given
890 COMPARABLE element starting with the given HASH value. It cannot
891 be used to insert or delete an element. */
892
893template<typename Descriptor, template<typename Type> class Allocator>
67f58944
TS
894typename hash_table<Descriptor, Allocator>::value_type &
895hash_table<Descriptor, Allocator>
84baa4b9
TS
896::find_with_hash (const compare_type &comparable, hashval_t hash)
897{
898 m_searches++;
899 size_t size = m_size;
900 hashval_t index = hash_table_mod1 (hash, m_size_prime_index);
901
902 value_type *entry = &m_entries[index];
903 if (is_empty (*entry)
904 || (!is_deleted (*entry) && Descriptor::equal (*entry, comparable)))
905 return *entry;
906
907 hashval_t hash2 = hash_table_mod2 (hash, m_size_prime_index);
908 for (;;)
909 {
910 m_collisions++;
911 index += hash2;
912 if (index >= size)
913 index -= size;
914
915 entry = &m_entries[index];
916 if (is_empty (*entry)
917 || (!is_deleted (*entry) && Descriptor::equal (*entry, comparable)))
918 return *entry;
919 }
920}
921
922/* This function searches for a hash table slot containing an entry
923 equal to the given COMPARABLE element and starting with the given
924 HASH. To delete an entry, call this with insert=NO_INSERT, then
925 call clear_slot on the slot returned (possibly after doing some
926 checks). To insert an entry, call this with insert=INSERT, then
927 write the value you want into the returned slot. When inserting an
928 entry, NULL may be returned if memory allocation fails. */
929
930template<typename Descriptor, template<typename Type> class Allocator>
67f58944
TS
931typename hash_table<Descriptor, Allocator>::value_type *
932hash_table<Descriptor, Allocator>
84baa4b9
TS
933::find_slot_with_hash (const compare_type &comparable, hashval_t hash,
934 enum insert_option insert)
935{
936 if (insert == INSERT && m_size * 3 <= m_n_elements * 4)
937 expand ();
938
939 m_searches++;
940
941 value_type *first_deleted_slot = NULL;
942 hashval_t index = hash_table_mod1 (hash, m_size_prime_index);
943 hashval_t hash2 = hash_table_mod2 (hash, m_size_prime_index);
944 value_type *entry = &m_entries[index];
945 size_t size = m_size;
946 if (is_empty (*entry))
947 goto empty_entry;
948 else if (is_deleted (*entry))
949 first_deleted_slot = &m_entries[index];
950 else if (Descriptor::equal (*entry, comparable))
951 return &m_entries[index];
952
953 for (;;)
954 {
955 m_collisions++;
956 index += hash2;
957 if (index >= size)
958 index -= size;
959
960 entry = &m_entries[index];
961 if (is_empty (*entry))
962 goto empty_entry;
963 else if (is_deleted (*entry))
964 {
965 if (!first_deleted_slot)
966 first_deleted_slot = &m_entries[index];
967 }
968 else if (Descriptor::equal (*entry, comparable))
969 return &m_entries[index];
970 }
971
972 empty_entry:
973 if (insert == NO_INSERT)
974 return NULL;
975
976 if (first_deleted_slot)
977 {
978 m_n_deleted--;
979 mark_empty (*first_deleted_slot);
980 return first_deleted_slot;
981 }
982
983 m_n_elements++;
984 return &m_entries[index];
985}
986
987/* This function deletes an element with the given COMPARABLE value
988 from hash table starting with the given HASH. If there is no
989 matching element in the hash table, this function does nothing. */
990
991template<typename Descriptor, template<typename Type> class Allocator>
992void
67f58944 993hash_table<Descriptor, Allocator>
84baa4b9
TS
994::remove_elt_with_hash (const compare_type &comparable, hashval_t hash)
995{
996 value_type *slot = find_slot_with_hash (comparable, hash, NO_INSERT);
997 if (is_empty (*slot))
998 return;
999
1000 Descriptor::remove (*slot);
1001
1002 mark_deleted (*slot);
1003 m_n_deleted++;
1004}
1005
1006/* This function scans over the entire hash table calling CALLBACK for
1007 each live entry. If CALLBACK returns false, the iteration stops.
1008 ARGUMENT is passed as CALLBACK's second argument. */
1009
1010template<typename Descriptor,
1011 template<typename Type> class Allocator>
1012template<typename Argument,
67f58944
TS
1013 int (*Callback)
1014 (typename hash_table<Descriptor, Allocator>::value_type *slot,
1015 Argument argument)>
84baa4b9 1016void
67f58944 1017hash_table<Descriptor, Allocator>::traverse_noresize (Argument argument)
84baa4b9
TS
1018{
1019 value_type *slot = m_entries;
1020 value_type *limit = slot + size ();
1021
1022 do
1023 {
1024 value_type &x = *slot;
1025
1026 if (!is_empty (x) && !is_deleted (x))
1027 if (! Callback (slot, argument))
1028 break;
1029 }
1030 while (++slot < limit);
1031}
1032
1033/* Like traverse_noresize, but does resize the table when it is too empty
1034 to improve effectivity of subsequent calls. */
1035
1036template <typename Descriptor,
1037 template <typename Type> class Allocator>
1038template <typename Argument,
67f58944
TS
1039 int (*Callback)
1040 (typename hash_table<Descriptor, Allocator>::value_type *slot,
1041 Argument argument)>
84baa4b9 1042void
67f58944 1043hash_table<Descriptor, Allocator>::traverse (Argument argument)
84baa4b9
TS
1044{
1045 size_t size = m_size;
1046 if (elements () * 8 < size && size > 32)
1047 expand ();
1048
1049 traverse_noresize <Argument, Callback> (argument);
1050}
1051
1052/* Slide down the iterator slots until an active entry is found. */
1053
1054template<typename Descriptor, template<typename Type> class Allocator>
1055void
67f58944 1056hash_table<Descriptor, Allocator>::iterator::slide ()
84baa4b9
TS
1057{
1058 for ( ; m_slot < m_limit; ++m_slot )
1059 {
1060 value_type &x = *m_slot;
1061 if (!is_empty (x) && !is_deleted (x))
1062 return;
1063 }
1064 m_slot = NULL;
1065 m_limit = NULL;
1066}
1067
1068/* Bump the iterator. */
1069
1070template<typename Descriptor, template<typename Type> class Allocator>
67f58944
TS
1071inline typename hash_table<Descriptor, Allocator>::iterator &
1072hash_table<Descriptor, Allocator>::iterator::operator ++ ()
bf190e8d 1073{
65d3284b 1074 ++m_slot;
bf190e8d
LC
1075 slide ();
1076 return *this;
1077}
1078
bf190e8d
LC
1079
1080/* Iterate through the elements of hash_table HTAB,
1081 using hash_table <....>::iterator ITER,
3fadf78a 1082 storing each element in RESULT, which is of type TYPE. */
bf190e8d
LC
1083
1084#define FOR_EACH_HASH_TABLE_ELEMENT(HTAB, RESULT, TYPE, ITER) \
1085 for ((ITER) = (HTAB).begin (); \
84baa4b9 1086 (ITER) != (HTAB).end () ? (RESULT = *(ITER) , true) : false; \
bf190e8d
LC
1087 ++(ITER))
1088
b086d530
TS
1089/* ggc walking routines. */
1090
1091template<typename E>
1092static inline void
1093gt_ggc_mx (hash_table<E> *h)
1094{
1095 typedef hash_table<E> table;
1096
1097 if (!ggc_test_and_set_mark (h->m_entries))
1098 return;
1099
1100 for (size_t i = 0; i < h->m_size; i++)
1101 {
1102 if (table::is_empty (h->m_entries[i])
1103 || table::is_deleted (h->m_entries[i]))
1104 continue;
1105
1106 E::ggc_mx (h->m_entries[i]);
1107 }
1108}
1109
1110template<typename D>
1111static inline void
1112hashtab_entry_note_pointers (void *obj, void *h, gt_pointer_operator op,
1113 void *cookie)
1114{
1115 hash_table<D> *map = static_cast<hash_table<D> *> (h);
1116 gcc_checking_assert (map->m_entries == obj);
1117 for (size_t i = 0; i < map->m_size; i++)
1118 {
1119 typedef hash_table<D> table;
1120 if (table::is_empty (map->m_entries[i])
1121 || table::is_deleted (map->m_entries[i]))
1122 continue;
1123
1124 D::pch_nx (map->m_entries[i], op, cookie);
1125 }
1126}
1127
1128template<typename D>
1129static void
1130gt_pch_nx (hash_table<D> *h)
1131{
2a22f99c 1132 bool success
4b49af15
TS
1133 = gt_pch_note_object (h->m_entries, h, hashtab_entry_note_pointers<D>);
1134 gcc_checking_assert (success);
b086d530
TS
1135 for (size_t i = 0; i < h->m_size; i++)
1136 {
1137 if (hash_table<D>::is_empty (h->m_entries[i])
1138 || hash_table<D>::is_deleted (h->m_entries[i]))
1139 continue;
1140
1141 D::pch_nx (h->m_entries[i]);
1142 }
1143}
1144
2a22f99c
TS
1145template<typename D>
1146static inline void
1147gt_pch_nx (hash_table<D> *h, gt_pointer_operator op, void *cookie)
1148{
1149 op (&h->m_entries, cookie);
1150}
1151
aebf76a2
TS
1152template<typename H>
1153inline void
1154gt_cleare_cache (hash_table<H> *h)
1155{
08ec2754
RS
1156 extern void gt_ggc_mx (typename H::value_type &t);
1157 typedef hash_table<H> table;
aebf76a2
TS
1158 if (!h)
1159 return;
1160
08ec2754
RS
1161 for (typename table::iterator iter = h->begin (); iter != h->end (); ++iter)
1162 if (!table::is_empty (*iter) && !table::is_deleted (*iter))
1163 {
1164 int res = H::keep_cache_entry (*iter);
1165 if (res == 0)
1166 h->clear_slot (&*iter);
1167 else if (res != -1)
1168 gt_ggc_mx (*iter);
1169 }
aebf76a2
TS
1170}
1171
0823efed 1172#endif /* TYPED_HASHTAB_H */