X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gas%2Fhash.c;h=655ddfcc5264d6dfad5dd34b98319fafdbc7976a;hb=c88960d081f0b37ec03c66a13115e2a68e40d1ad;hp=0f4742a5b02ead3cd967334b3ba67d0f1a70f31f;hpb=4b4da1607aeed19ac399963a3aa12b0417e477ae;p=deliverable%2Fbinutils-gdb.git diff --git a/gas/hash.c b/gas/hash.c index 0f4742a5b0..655ddfcc52 100644 --- a/gas/hash.c +++ b/gas/hash.c @@ -1,13 +1,11 @@ /* hash.c -- gas hash table code - Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, - 2000, 2001, 2002, 2003, 2005 - Free Software Foundation, Inc. + Copyright (C) 1987-2016 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. GAS is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) + the Free Software Foundation; either version 3, or (at your option) any later version. GAS is distributed in the hope that it will be useful, @@ -44,7 +42,7 @@ struct hash_entry { table. */ unsigned long hash; /* Pointer being stored in the hash table. */ - PTR data; + void *data; }; /* A hash table. */ @@ -78,45 +76,21 @@ static unsigned long gas_hash_table_size = 65537; void set_gas_hash_table_size (unsigned long size) { - gas_hash_table_size = size; -} - -/* FIXME: This function should be amalgmated with bfd/hash.c:bfd_hash_set_default_size(). */ -static unsigned long -get_gas_hash_table_size (void) -{ - /* Extend this prime list if you want more granularity of hash table size. */ - static const unsigned long hash_size_primes[] = - { - 1021, 4051, 8599, 16699, 65537 - }; - unsigned int index; - - /* Work out the best prime number near the hash_size. - FIXME: This could be a more sophisticated algorithm, - but is it really worth implementing it ? */ - for (index = 0; index < ARRAY_SIZE (hash_size_primes) - 1; ++index) - if (gas_hash_table_size <= hash_size_primes[index]) - break; - - return hash_size_primes[index]; + gas_hash_table_size = bfd_hash_set_default_size (size); } /* Create a hash table. This return a control block. */ struct hash_control * -hash_new (void) +hash_new_sized (unsigned long size) { - unsigned long size; unsigned long alloc; struct hash_control *ret; - size = get_gas_hash_table_size (); - - ret = xmalloc (sizeof *ret); + ret = XNEW (struct hash_control); obstack_begin (&ret->memory, chunksize); alloc = size * sizeof (struct hash_entry *); - ret->table = obstack_alloc (&ret->memory, alloc); + ret->table = (struct hash_entry **) obstack_alloc (&ret->memory, alloc); memset (ret->table, 0, alloc); ret->size = size; @@ -132,6 +106,12 @@ hash_new (void) return ret; } +struct hash_control * +hash_new (void) +{ + return hash_new_sized (gas_hash_table_size); +} + /* Delete a hash table, freeing all allocated memory. */ void @@ -150,20 +130,14 @@ hash_die (struct hash_control *table) Each time we look up a string, we move it to the start of the list for its hash code, to take advantage of referential locality. */ -static struct hash_entry *hash_lookup (struct hash_control *, - const char *, - struct hash_entry ***, - unsigned long *); - static struct hash_entry * -hash_lookup (struct hash_control *table, const char *key, +hash_lookup (struct hash_control *table, const char *key, size_t len, struct hash_entry ***plist, unsigned long *phash) { - register unsigned long hash; - unsigned int len; - register const unsigned char *s; - register unsigned int c; - unsigned int index; + unsigned long hash; + size_t n; + unsigned int c; + unsigned int hindex; struct hash_entry **list; struct hash_entry *p; struct hash_entry *prev; @@ -173,13 +147,11 @@ hash_lookup (struct hash_control *table, const char *key, #endif hash = 0; - len = 0; - s = (const unsigned char *) key; - while ((c = *s++) != '\0') + for (n = 0; n < len; n++) { + c = key[n]; hash += c + (c << 17); hash ^= hash >> 2; - ++len; } hash += len + (len << 17); hash ^= hash >> 2; @@ -187,8 +159,8 @@ hash_lookup (struct hash_control *table, const char *key, if (phash != NULL) *phash = hash; - index = hash % table->size; - list = table->table + index; + hindex = hash % table->size; + list = table->table + hindex; if (plist != NULL) *plist = list; @@ -206,7 +178,7 @@ hash_lookup (struct hash_control *table, const char *key, ++table->string_compares; #endif - if (strcmp (p->string, key) == 0) + if (strncmp (p->string, key, len) == 0 && p->string[len] == '\0') { if (prev != NULL) { @@ -231,13 +203,13 @@ hash_lookup (struct hash_control *table, const char *key, hash table. */ const char * -hash_insert (struct hash_control *table, const char *key, PTR value) +hash_insert (struct hash_control *table, const char *key, void *val) { struct hash_entry *p; struct hash_entry **list; unsigned long hash; - p = hash_lookup (table, key, &list, &hash); + p = hash_lookup (table, key, strlen (key), &list, &hash); if (p != NULL) return "exists"; @@ -248,7 +220,7 @@ hash_insert (struct hash_control *table, const char *key, PTR value) p = (struct hash_entry *) obstack_alloc (&table->memory, sizeof (*p)); p->string = key; p->hash = hash; - p->data = value; + p->data = val; p->next = *list; *list = p; @@ -261,20 +233,20 @@ hash_insert (struct hash_control *table, const char *key, PTR value) error. If an entry already exists, its value is replaced. */ const char * -hash_jam (struct hash_control *table, const char *key, PTR value) +hash_jam (struct hash_control *table, const char *key, void *val) { struct hash_entry *p; struct hash_entry **list; unsigned long hash; - p = hash_lookup (table, key, &list, &hash); + p = hash_lookup (table, key, strlen (key), &list, &hash); if (p != NULL) { #ifdef HASH_STATISTICS ++table->replacements; #endif - p->data = value; + p->data = val; } else { @@ -285,7 +257,7 @@ hash_jam (struct hash_control *table, const char *key, PTR value) p = (struct hash_entry *) obstack_alloc (&table->memory, sizeof (*p)); p->string = key; p->hash = hash; - p->data = value; + p->data = val; p->next = *list; *list = p; @@ -298,13 +270,13 @@ hash_jam (struct hash_control *table, const char *key, PTR value) value stored for the entry. If the entry is not found in the hash table, this does nothing and returns NULL. */ -PTR -hash_replace (struct hash_control *table, const char *key, PTR value) +void * +hash_replace (struct hash_control *table, const char *key, void *value) { struct hash_entry *p; - PTR ret; + void *ret; - p = hash_lookup (table, key, NULL, NULL); + p = hash_lookup (table, key, strlen (key), NULL, NULL); if (p == NULL) return NULL; @@ -322,12 +294,27 @@ hash_replace (struct hash_control *table, const char *key, PTR value) /* Find an entry in a hash table, returning its value. Returns NULL if the entry is not found. */ -PTR +void * hash_find (struct hash_control *table, const char *key) { struct hash_entry *p; - p = hash_lookup (table, key, NULL, NULL); + p = hash_lookup (table, key, strlen (key), NULL, NULL); + if (p == NULL) + return NULL; + + return p->data; +} + +/* As hash_find, but KEY is of length LEN and is not guaranteed to be + NUL-terminated. */ + +void * +hash_find_n (struct hash_control *table, const char *key, size_t len) +{ + struct hash_entry *p; + + p = hash_lookup (table, key, len, NULL, NULL); if (p == NULL) return NULL; @@ -337,13 +324,13 @@ hash_find (struct hash_control *table, const char *key) /* Delete an entry from a hash table. This returns the value stored for that entry, or NULL if there is no such entry. */ -PTR -hash_delete (struct hash_control *table, const char *key) +void * +hash_delete (struct hash_control *table, const char *key, int freeme) { struct hash_entry *p; struct hash_entry **list; - p = hash_lookup (table, key, &list, NULL); + p = hash_lookup (table, key, strlen (key), &list, NULL); if (p == NULL) return NULL; @@ -356,9 +343,8 @@ hash_delete (struct hash_control *table, const char *key) *list = p->next; - /* Note that we never reclaim the memory for this entry. If gas - ever starts deleting hash table entries in a big way, this will - have to change. */ + if (freeme) + obstack_free (&table->memory, p); return p->data; } @@ -368,7 +354,7 @@ hash_delete (struct hash_control *table, const char *key) void hash_traverse (struct hash_control *table, - void (*pfn) (const char *key, PTR value)) + void (*pfn) (const char *key, void *value)) { unsigned int i;