1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
|
/* Experimental Symbol Cache Module */
/* Copyright 1999 Free Software Foundation, Inc.
This file is part of GDB.
This program 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 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <string.h>
#include "defs.h"
#include "symtab.h"
#include "symfile.h"
#include "objfiles.h"
#define HASH_SIZE 1009
struct cache_entry {
const char* name;
namespace_enum namespace;
struct symbol* sym;
struct symtab* symtab;
struct block* block;
struct cache_entry* next;
};
static struct obstack cache_space;
static struct cache_entry* cache[HASH_SIZE];
static int
shash (const char* s)
{
int len = strlen (s);
unsigned int r;
const char* x;
for (r = 0, x = s; *x != '\000'; x += 1)
{
r = (r << 4) + *x;
if (r > 0x0fffffff) {
r ^= (r >> 24) & 0xf0;
r &= 0x0fffffff;
}
}
return r % HASH_SIZE;
}
/* Clear all entries from the symbol cache. */
void
clear_sym_cache ()
{
obstack_free (&cache_space, 0);
obstack_init (&cache_space);
memset (cache, '\000', sizeof (cache));
}
static struct cache_entry**
find_entry (const char* name, namespace_enum namespace)
{
int h = shash (name);
struct cache_entry** e;
for (e = &cache[h]; *e != NULL; e = &(*e)->next)
{
if (namespace == (*e)->namespace && STREQ (name, (*e)->name))
return e;
}
return NULL;
}
/* Return (in SYM) the last cached definition for global or static symbol NAME
in namespace NAMESPACE. Returns 1 if entry found, 0 otherwise.
If SYMTAB is non-NULL, store the symbol
table in which the symbol was found there, or NULL if not found.
*BLOCK is set to the block in which NAME is found. */
int
lookup_cached_symbol (name, namespace, sym, block, symtab)
const char* name;
namespace_enum namespace;
struct symbol** sym;
struct block** block;
struct symtab** symtab;
{
struct cache_entry** e = find_entry (name, namespace);
if (e == NULL)
return 0;
if (sym != NULL)
*sym = (*e)->sym;
if (block != NULL)
*block = (*e)->block;
if (symtab != NULL)
*symtab = (*e)->symtab;
return 1;
}
/* Set the cached definition of NAME in NAMESPACE to SYM in block
BLOCK and symbol table SYMTAB. */
void
cache_symbol (name, namespace, sym, block, symtab)
const char* name;
namespace_enum namespace;
struct symbol* sym;
struct block* block;
struct symtab* symtab;
{
int h = shash (name);
char* copy;
struct cache_entry* e =
(struct cache_entry*) obstack_alloc(&cache_space, sizeof (*e));
e->next = cache[h];
cache[h] = e;
e->name = copy = obstack_alloc (&cache_space, strlen (name) + 1);
strcpy (copy, name);
e->sym = sym;
e->namespace = namespace;
e->symtab = symtab;
e->block = block;
}
void
_initialize_sym_cache ()
{
obstack_init (&cache_space);
}
|