2 * Copyright (C) 2003, 2004, 2005, 2006, 2007
3 * Robert Lougher <rob@lougher.org.uk>.
5 * This file is part of JamVM.
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2,
10 * or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24 typedef struct hash_entry
{
29 typedef struct hash_table
{
30 HashEntry
*hash_table
;
36 extern void resizeHash(HashTable
*table
, int new_size
);
37 extern void lockHashTable0(HashTable
*table
, Thread
*self
);
38 extern void unlockHashTable0(HashTable
*table
, Thread
*self
);
40 #define initHashTable(table, initial_size, create_lock) \
42 table.hash_table = (HashEntry*)gcMemMalloc(sizeof(HashEntry)*initial_size); \
43 memset(table.hash_table, 0, sizeof(HashEntry)*initial_size); \
44 table.hash_size = initial_size; \
45 table.hash_count = 0; \
47 initVMLock(table.lock); \
50 #define lockHashTable(table) \
51 lockHashTable0(&table, threadSelf());
53 #define unlockHashTable(table) \
54 unlockHashTable0(&table, threadSelf());
56 #define findHashEntry(table, ptr, ptr2, add_if_absent, scavenge, locked) \
58 int hash = HASH(ptr); \
63 self = threadSelf(); \
64 lockHashTable0(&table, self); \
67 i = hash & (table.hash_size - 1); \
70 ptr2 = table.hash_table[i].data; \
71 if((ptr2 == NULL) || (COMPARE(ptr, ptr2, hash, table.hash_table[i].hash))) \
74 i = (i+1) & (table.hash_size - 1); \
81 table.hash_table[i].hash = hash; \
82 ptr2 = table.hash_table[i].data = PREPARE(ptr); \
86 if((table.hash_count * 4) > (table.hash_size * 3)) { \
89 HashEntry *entry = table.hash_table; \
90 int cnt = table.hash_count; \
91 for(; cnt; entry++) { \
92 void *data = entry->data; \
94 if(SCAVENGE(data)) { \
101 if((table.hash_count * 3) > (table.hash_size * 2)) \
102 new_size = table.hash_size*2; \
104 new_size = table.hash_size; \
106 new_size = table.hash_size*2; \
108 resizeHash(&table, new_size); \
114 unlockHashTable0(&table, self); \
117 #define deleteHashEntry(table, ptr, locked) \
119 int hash = HASH(ptr); \
125 self = threadSelf(); \
126 lockHashTable0(&table, self); \
129 i = hash & (table.hash_size - 1); \
132 ptr2 = table.hash_table[i].data; \
133 if((ptr2 == NULL) || (COMPARE(ptr, ptr2, hash, table.hash_table[i].hash))) \
136 i = (i+1) & (table.hash_size - 1); \
140 table.hash_table[i].data = DELETED; \
143 unlockHashTable0(&table, self); \
146 #define hashIterate(table) \
148 HashEntry *entry = table.hash_table; \
149 int cnt = table.hash_count; \
152 void *data = entry++->data; \
160 #define hashIterateP(table) \
162 HashEntry *entry = table.hash_table; \
163 int cnt = table.hash_count; \
166 void **data_pntr = &entry++->data; \
168 ITERATE(data_pntr); \
174 #define gcFreeHashTable(table) \
175 gcMemFree(table.hash_table);
177 #define freeHashTable(table) \
178 gcMemFree(table.hash_table);