gas/
[deliverable/binutils-gdb.git] / gas / hash.c
CommitLineData
54d22525 1/* hash.c -- gas hash table code
f7e42eb4 2 Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999,
4c665b71 3 2000, 2001, 2002, 2003, 2005, 2007, 2008, 2009, 2011, 2013
252b5132
RH
4 Free Software Foundation, Inc.
5
6 This file is part of GAS, the GNU Assembler.
7
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
ec2655a6 10 the Free Software Foundation; either version 3, or (at your option)
252b5132
RH
11 any later version.
12
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
54d22525 19 along with GAS; see the file COPYING. If not, write to the Free
4b4da160
NC
20 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
21 02110-1301, USA. */
54d22525
ILT
22
23/* This version of the hash table code is a wholescale replacement of
24 the old hash table code, which was fairly bad. This is based on
25 the hash table code in BFD, but optimized slightly for the
436d9e46 26 assembler. The assembler does not need to derive structures that
54d22525
ILT
27 are stored in the hash table. Instead, it always stores a pointer.
28 The assembler uses the hash table mostly to store symbols, and we
29 don't need to confuse the symbol structure with a hash table
30 structure. */
252b5132
RH
31
32#include "as.h"
3882b010 33#include "safe-ctype.h"
54d22525 34#include "obstack.h"
252b5132 35
54d22525 36/* An entry in a hash table. */
252b5132 37
b041f888 38struct hash_entry {
54d22525
ILT
39 /* Next entry for this hash code. */
40 struct hash_entry *next;
41 /* String being hashed. */
42 const char *string;
43 /* Hash code. This is the full hash code, not the index into the
44 table. */
45 unsigned long hash;
46 /* Pointer being stored in the hash table. */
818236e5 47 void *data;
252b5132
RH
48};
49
54d22525
ILT
50/* A hash table. */
51
b041f888 52struct hash_control {
54d22525
ILT
53 /* The hash array. */
54 struct hash_entry **table;
55 /* The number of slots in the hash table. */
56 unsigned int size;
57 /* An obstack for this hash table. */
58 struct obstack memory;
59
60#ifdef HASH_STATISTICS
61 /* Statistics. */
62 unsigned long lookups;
63 unsigned long hash_compares;
64 unsigned long string_compares;
65 unsigned long insertions;
66 unsigned long replacements;
67 unsigned long deletions;
68#endif /* HASH_STATISTICS */
252b5132 69};
54d22525 70
4bdd3565
NC
71/* The default number of entries to use when creating a hash table.
72 Note this value can be reduced to 4051 by using the command line
73 switch --reduce-memory-overheads, or set to other values by using
74 the --hash-size=<NUMBER> switch. */
75
f7a568ea 76static unsigned long gas_hash_table_size = 65537;
4bdd3565
NC
77
78void
f7a568ea 79set_gas_hash_table_size (unsigned long size)
4bdd3565 80{
8ad17b3a 81 gas_hash_table_size = bfd_hash_set_default_size (size);
4bdd3565
NC
82}
83
54d22525
ILT
84/* Create a hash table. This return a control block. */
85
4c665b71 86struct hash_control *
8ad17b3a 87hash_new_sized (unsigned long size)
252b5132 88{
f7a568ea 89 unsigned long alloc;
54d22525 90 struct hash_control *ret;
54d22525 91
1e9cc1c2 92 ret = (struct hash_control *) xmalloc (sizeof *ret);
54d22525
ILT
93 obstack_begin (&ret->memory, chunksize);
94 alloc = size * sizeof (struct hash_entry *);
1e9cc1c2 95 ret->table = (struct hash_entry **) obstack_alloc (&ret->memory, alloc);
54d22525
ILT
96 memset (ret->table, 0, alloc);
97 ret->size = size;
98
99#ifdef HASH_STATISTICS
100 ret->lookups = 0;
101 ret->hash_compares = 0;
102 ret->string_compares = 0;
103 ret->insertions = 0;
104 ret->replacements = 0;
105 ret->deletions = 0;
106#endif
107
8fc2faa7 108 return ret;
252b5132
RH
109}
110
8ad17b3a
AM
111struct hash_control *
112hash_new (void)
113{
114 return hash_new_sized (gas_hash_table_size);
115}
116
54d22525
ILT
117/* Delete a hash table, freeing all allocated memory. */
118
252b5132 119void
b1f1fa96 120hash_die (struct hash_control *table)
252b5132 121{
54d22525
ILT
122 obstack_free (&table->memory, 0);
123 free (table);
252b5132 124}
54d22525
ILT
125
126/* Look up a string in a hash table. This returns a pointer to the
127 hash_entry, or NULL if the string is not in the table. If PLIST is
128 not NULL, this sets *PLIST to point to the start of the list which
129 would hold this hash entry. If PHASH is not NULL, this sets *PHASH
130 to the hash code for KEY.
131
132 Each time we look up a string, we move it to the start of the list
133 for its hash code, to take advantage of referential locality. */
134
54d22525 135static struct hash_entry *
c19d1205 136hash_lookup (struct hash_control *table, const char *key, size_t len,
b1f1fa96 137 struct hash_entry ***plist, unsigned long *phash)
252b5132 138{
c19d1205
ZW
139 unsigned long hash;
140 size_t n;
141 unsigned int c;
91d6fa6a 142 unsigned int hindex;
54d22525
ILT
143 struct hash_entry **list;
144 struct hash_entry *p;
145 struct hash_entry *prev;
146
147#ifdef HASH_STATISTICS
148 ++table->lookups;
149#endif
252b5132 150
54d22525 151 hash = 0;
c19d1205 152 for (n = 0; n < len; n++)
252b5132 153 {
c19d1205 154 c = key[n];
54d22525
ILT
155 hash += c + (c << 17);
156 hash ^= hash >> 2;
252b5132 157 }
54d22525
ILT
158 hash += len + (len << 17);
159 hash ^= hash >> 2;
160
161 if (phash != NULL)
162 *phash = hash;
163
91d6fa6a
NC
164 hindex = hash % table->size;
165 list = table->table + hindex;
252b5132 166
54d22525
ILT
167 if (plist != NULL)
168 *plist = list;
169
170 prev = NULL;
171 for (p = *list; p != NULL; p = p->next)
252b5132 172 {
54d22525
ILT
173#ifdef HASH_STATISTICS
174 ++table->hash_compares;
175#endif
176
177 if (p->hash == hash)
252b5132 178 {
54d22525
ILT
179#ifdef HASH_STATISTICS
180 ++table->string_compares;
181#endif
182
c19d1205 183 if (strncmp (p->string, key, len) == 0 && p->string[len] == '\0')
54d22525
ILT
184 {
185 if (prev != NULL)
186 {
187 prev->next = p->next;
188 p->next = *list;
189 *list = p;
190 }
191
192 return p;
193 }
252b5132 194 }
252b5132 195
54d22525 196 prev = p;
252b5132 197 }
54d22525
ILT
198
199 return NULL;
252b5132 200}
54d22525
ILT
201
202/* Insert an entry into a hash table. This returns NULL on success.
203 On error, it returns a printable string indicating the error. It
204 is considered to be an error if the entry already exists in the
205 hash table. */
206
207const char *
91d6fa6a 208hash_insert (struct hash_control *table, const char *key, void *val)
252b5132 209{
54d22525
ILT
210 struct hash_entry *p;
211 struct hash_entry **list;
212 unsigned long hash;
252b5132 213
c19d1205 214 p = hash_lookup (table, key, strlen (key), &list, &hash);
54d22525
ILT
215 if (p != NULL)
216 return "exists";
217
218#ifdef HASH_STATISTICS
219 ++table->insertions;
220#endif
221
1e9cc1c2 222 p = (struct hash_entry *) obstack_alloc (&table->memory, sizeof (*p));
54d22525
ILT
223 p->string = key;
224 p->hash = hash;
91d6fa6a 225 p->data = val;
54d22525
ILT
226
227 p->next = *list;
228 *list = p;
229
230 return NULL;
252b5132 231}
54d22525
ILT
232
233/* Insert or replace an entry in a hash table. This returns NULL on
234 success. On error, it returns a printable string indicating the
235 error. If an entry already exists, its value is replaced. */
236
252b5132 237const char *
91d6fa6a 238hash_jam (struct hash_control *table, const char *key, void *val)
252b5132 239{
54d22525
ILT
240 struct hash_entry *p;
241 struct hash_entry **list;
242 unsigned long hash;
252b5132 243
c19d1205 244 p = hash_lookup (table, key, strlen (key), &list, &hash);
54d22525 245 if (p != NULL)
252b5132 246 {
54d22525
ILT
247#ifdef HASH_STATISTICS
248 ++table->replacements;
249#endif
250
91d6fa6a 251 p->data = val;
252b5132 252 }
54d22525 253 else
252b5132 254 {
54d22525
ILT
255#ifdef HASH_STATISTICS
256 ++table->insertions;
257#endif
258
1e9cc1c2 259 p = (struct hash_entry *) obstack_alloc (&table->memory, sizeof (*p));
54d22525
ILT
260 p->string = key;
261 p->hash = hash;
91d6fa6a 262 p->data = val;
54d22525
ILT
263
264 p->next = *list;
265 *list = p;
252b5132 266 }
54d22525
ILT
267
268 return NULL;
252b5132
RH
269}
270
7e70f1af
L
271/* Replace an existing entry in a hash table. This returns the old
272 value stored for the entry. If the entry is not found in the hash
273 table, this does nothing and returns NULL. */
274
5a49b8ac 275void *
818236e5 276hash_replace (struct hash_control *table, const char *key, void *value)
7e70f1af
L
277{
278 struct hash_entry *p;
818236e5 279 void *ret;
7e70f1af 280
c19d1205 281 p = hash_lookup (table, key, strlen (key), NULL, NULL);
7e70f1af
L
282 if (p == NULL)
283 return NULL;
284
285#ifdef HASH_STATISTICS
286 ++table->replacements;
287#endif
288
289 ret = p->data;
290
291 p->data = value;
292
293 return ret;
294}
295
54d22525
ILT
296/* Find an entry in a hash table, returning its value. Returns NULL
297 if the entry is not found. */
298
5a49b8ac 299void *
b1f1fa96 300hash_find (struct hash_control *table, const char *key)
252b5132 301{
54d22525 302 struct hash_entry *p;
252b5132 303
c19d1205
ZW
304 p = hash_lookup (table, key, strlen (key), NULL, NULL);
305 if (p == NULL)
306 return NULL;
307
308 return p->data;
309}
310
311/* As hash_find, but KEY is of length LEN and is not guaranteed to be
312 NUL-terminated. */
313
5a49b8ac 314void *
c19d1205
ZW
315hash_find_n (struct hash_control *table, const char *key, size_t len)
316{
317 struct hash_entry *p;
318
319 p = hash_lookup (table, key, len, NULL, NULL);
54d22525 320 if (p == NULL)
252b5132 321 return NULL;
54d22525
ILT
322
323 return p->data;
252b5132 324}
54d22525 325
7e70f1af
L
326/* Delete an entry from a hash table. This returns the value stored
327 for that entry, or NULL if there is no such entry. */
328
5a49b8ac 329void *
818236e5 330hash_delete (struct hash_control *table, const char *key, int freeme)
7e70f1af
L
331{
332 struct hash_entry *p;
333 struct hash_entry **list;
334
c19d1205 335 p = hash_lookup (table, key, strlen (key), &list, NULL);
7e70f1af
L
336 if (p == NULL)
337 return NULL;
338
339 if (p != *list)
340 abort ();
341
342#ifdef HASH_STATISTICS
343 ++table->deletions;
344#endif
345
346 *list = p->next;
347
818236e5
AM
348 if (freeme)
349 obstack_free (&table->memory, p);
7e70f1af
L
350
351 return p->data;
352}
353
54d22525
ILT
354/* Traverse a hash table. Call the function on every entry in the
355 hash table. */
356
252b5132 357void
b1f1fa96 358hash_traverse (struct hash_control *table,
818236e5 359 void (*pfn) (const char *key, void *value))
252b5132 360{
54d22525 361 unsigned int i;
252b5132 362
54d22525
ILT
363 for (i = 0; i < table->size; ++i)
364 {
365 struct hash_entry *p;
252b5132 366
54d22525
ILT
367 for (p = table->table[i]; p != NULL; p = p->next)
368 (*pfn) (p->string, p->data);
369 }
370}
252b5132 371
54d22525
ILT
372/* Print hash table statistics on the specified file. NAME is the
373 name of the hash table, used for printing a header. */
252b5132 374
54d22525 375void
b1f1fa96
KH
376hash_print_statistics (FILE *f ATTRIBUTE_UNUSED,
377 const char *name ATTRIBUTE_UNUSED,
378 struct hash_control *table ATTRIBUTE_UNUSED)
54d22525
ILT
379{
380#ifdef HASH_STATISTICS
381 unsigned int i;
382 unsigned long total;
383 unsigned long empty;
384
385 fprintf (f, "%s hash statistics:\n", name);
386 fprintf (f, "\t%lu lookups\n", table->lookups);
387 fprintf (f, "\t%lu hash comparisons\n", table->hash_compares);
388 fprintf (f, "\t%lu string comparisons\n", table->string_compares);
389 fprintf (f, "\t%lu insertions\n", table->insertions);
390 fprintf (f, "\t%lu replacements\n", table->replacements);
391 fprintf (f, "\t%lu deletions\n", table->deletions);
392
393 total = 0;
394 empty = 0;
395 for (i = 0; i < table->size; ++i)
396 {
397 struct hash_entry *p;
252b5132 398
54d22525
ILT
399 if (table->table[i] == NULL)
400 ++empty;
401 else
402 {
403 for (p = table->table[i]; p != NULL; p = p->next)
404 ++total;
405 }
406 }
252b5132 407
54d22525
ILT
408 fprintf (f, "\t%g average chain length\n", (double) total / table->size);
409 fprintf (f, "\t%lu empty slots\n", empty);
410#endif
252b5132
RH
411}
412\f
252b5132
RH
413#ifdef TEST
414
54d22525
ILT
415/* This test program is left over from the old hash table code. */
416
8fc2faa7
KH
417/* Number of hash tables to maintain (at once) in any testing. */
418#define TABLES (6)
419
420/* We can have 12 statistics. */
421#define STATBUFSIZE (12)
422
423/* Display statistics here. */
424int statbuf[STATBUFSIZE];
425
426/* Human farts here. */
427char answer[100];
428
429/* We test many hash tables at once. */
430char *hashtable[TABLES];
252b5132 431
47eebc20 432/* Points to current hash_control. */
8fc2faa7 433char *h;
252b5132
RH
434char **pp;
435char *p;
436char *name;
437char *value;
438int size;
439int used;
440char command;
8fc2faa7
KH
441
442/* Number 0:TABLES-1 of current hashed symbol table. */
443int number;
252b5132 444
54d22525 445int
252b5132
RH
446main ()
447{
448 void applicatee ();
449 void destroy ();
450 char *what ();
451 int *ip;
452
453 number = 0;
454 h = 0;
455 printf ("type h <RETURN> for help\n");
456 for (;;)
457 {
458 printf ("hash_test command: ");
459 gets (answer);
460 command = answer[0];
3882b010 461 command = TOLOWER (command); /* Ecch! */
252b5132
RH
462 switch (command)
463 {
464 case '#':
465 printf ("old hash table #=%d.\n", number);
466 whattable ();
467 break;
468 case '?':
469 for (pp = hashtable; pp < hashtable + TABLES; pp++)
470 {
8fc2faa7
KH
471 printf ("address of hash table #%d control block is %xx\n",
472 pp - hashtable, *pp);
252b5132
RH
473 }
474 break;
475 case 'a':
54d22525 476 hash_traverse (h, applicatee);
252b5132
RH
477 break;
478 case 'd':
54d22525 479 hash_traverse (h, destroy);
252b5132
RH
480 hash_die (h);
481 break;
482 case 'f':
483 p = hash_find (h, name = what ("symbol"));
484 printf ("value of \"%s\" is \"%s\"\n", name, p ? p : "NOT-PRESENT");
485 break;
486 case 'h':
487 printf ("# show old, select new default hash table number\n");
488 printf ("? display all hashtable control block addresses\n");
489 printf ("a apply a simple display-er to each symbol in table\n");
490 printf ("d die: destroy hashtable\n");
491 printf ("f find value of nominated symbol\n");
492 printf ("h this help\n");
493 printf ("i insert value into symbol\n");
494 printf ("j jam value into symbol\n");
495 printf ("n new hashtable\n");
496 printf ("r replace a value with another\n");
497 printf ("s say what %% of table is used\n");
498 printf ("q exit this program\n");
499 printf ("x delete a symbol from table, report its value\n");
500 break;
501 case 'i':
502 p = hash_insert (h, name = what ("symbol"), value = what ("value"));
503 if (p)
504 {
505 printf ("symbol=\"%s\" value=\"%s\" error=%s\n", name, value,
506 p);
507 }
508 break;
509 case 'j':
510 p = hash_jam (h, name = what ("symbol"), value = what ("value"));
511 if (p)
512 {
513 printf ("symbol=\"%s\" value=\"%s\" error=%s\n", name, value, p);
514 }
515 break;
516 case 'n':
517 h = hashtable[number] = (char *) hash_new ();
518 break;
519 case 'q':
520 exit (EXIT_SUCCESS);
521 case 'r':
522 p = hash_replace (h, name = what ("symbol"), value = what ("value"));
523 printf ("old value was \"%s\"\n", p ? p : "{}");
524 break;
525 case 's':
526 hash_say (h, statbuf, STATBUFSIZE);
527 for (ip = statbuf; ip < statbuf + STATBUFSIZE; ip++)
528 {
529 printf ("%d ", *ip);
530 }
531 printf ("\n");
532 break;
533 case 'x':
534 p = hash_delete (h, name = what ("symbol"));
535 printf ("old value was \"%s\"\n", p ? p : "{}");
536 break;
537 default:
538 printf ("I can't understand command \"%c\"\n", command);
539 break;
540 }
541 }
542}
543
544char *
545what (description)
546 char *description;
547{
252b5132
RH
548 printf (" %s : ", description);
549 gets (answer);
a2c36061 550 return xstrdup (answer);
252b5132
RH
551}
552
553void
554destroy (string, value)
555 char *string;
556 char *value;
557{
558 free (string);
559 free (value);
560}
561
252b5132
RH
562void
563applicatee (string, value)
564 char *string;
565 char *value;
566{
567 printf ("%.20s-%.20s\n", string, value);
568}
569
8fc2faa7
KH
570/* Determine number: what hash table to use.
571 Also determine h: points to hash_control. */
572
54d22525 573void
8fc2faa7 574whattable ()
252b5132 575{
252b5132
RH
576 for (;;)
577 {
578 printf (" what hash table (%d:%d) ? ", 0, TABLES - 1);
579 gets (answer);
580 sscanf (answer, "%d", &number);
581 if (number >= 0 && number < TABLES)
582 {
583 h = hashtable[number];
584 if (!h)
585 {
586 printf ("warning: current hash-table-#%d. has no hash-control\n", number);
587 }
588 return;
589 }
590 else
591 {
592 printf ("invalid hash table number: %d\n", number);
593 }
594 }
595}
596
8fc2faa7 597#endif /* TEST */
This page took 0.604516 seconds and 4 git commands to generate.