161 void reverse();
162
163 private:
164 // Instance variables
165 int _table_size;
166 HashtableBucket<F>* _buckets;
167 BasicHashtableEntry<F>* _free_list;
168 char* _first_free_entry;
169 char* _end_block;
170 int _entry_size;
171 int _number_of_entries;
172
173 protected:
174
175 #ifdef ASSERT
176 int _lookup_count;
177 int _lookup_length;
178 void verify_lookup_length(double load);
179 #endif
180
181 enum {
182 rehash_count = 100,
183 rehash_multiple = 60
184 };
185
186 void initialize(int table_size, int entry_size, int number_of_entries);
187
188 // Accessor
189 int entry_size() const { return _entry_size; }
190
191 // The following method is MT-safe and may be used with caution.
192 BasicHashtableEntry<F>* bucket(int i);
193
194 // The following method is not MT-safe and must be done under lock.
195 BasicHashtableEntry<F>** bucket_addr(int i) { return _buckets[i].entry_addr(); }
196
197 // Table entry management
198 BasicHashtableEntry<F>* new_entry(unsigned int hashValue);
199
200 // Check that the table is unbalanced
201 bool check_rehash_table(int count);
202
203 // Used when moving the entry to another table
204 // Clean up links, but do not add to free_list
205 void unlink_entry(BasicHashtableEntry<F>* entry) {
206 entry->set_next(NULL);
207 --_number_of_entries;
208 }
209
210 // Move over freelist and free block for allocation
211 void copy_freelist(BasicHashtable* src) {
212 _free_list = src->_free_list;
213 src->_free_list = NULL;
214 _first_free_entry = src->_first_free_entry;
215 src->_first_free_entry = NULL;
216 _end_block = src->_end_block;
217 src->_end_block = NULL;
218 }
219
220 // Free the buckets in this hashtable
221 void free_buckets();
222
260 return (unsigned int) name->identity_hash();
261 }
262
263 int index_for(Symbol* name) {
264 return this->hash_to_index(compute_hash(name));
265 }
266
267 // Table entry management
268 HashtableEntry<T, F>* new_entry(unsigned int hashValue, T obj);
269
270 // The following method is MT-safe and may be used with caution.
271 HashtableEntry<T, F>* bucket(int i) {
272 return (HashtableEntry<T, F>*)BasicHashtable<F>::bucket(i);
273 }
274
275 // The following method is not MT-safe and must be done under lock.
276 HashtableEntry<T, F>** bucket_addr(int i) {
277 return (HashtableEntry<T, F>**)BasicHashtable<F>::bucket_addr(i);
278 }
279
280 // Function to move these elements into the new table.
281 void move_to(Hashtable<T, F>* new_table);
282 static bool use_alternate_hashcode() { return _seed != 0; }
283 static juint seed() { return _seed; }
284
285 static int literal_size(Symbol *symbol);
286 static int literal_size(oop oop);
287
288 // The following two are currently not used, but are needed anyway because some
289 // C++ compilers (MacOS and Solaris) force the instantiation of
290 // Hashtable<ConstantPool*, mtClass>::dump_table() even though we never call this function
291 // in the VM code.
292 static int literal_size(ConstantPool *cp) {Unimplemented(); return 0;}
293 static int literal_size(Klass *k) {Unimplemented(); return 0;}
294
295 public:
296 void dump_table(outputStream* st, const char *table_name);
297
298 private:
299 static juint _seed;
300 };
301
302
303 // Verions of hashtable where two handles are used to compute the index.
304
305 template <class T, MEMFLAGS F> class TwoOopHashtable : public Hashtable<T, F> {
306 friend class VMStructs;
307 protected:
308 TwoOopHashtable(int table_size, int entry_size)
309 : Hashtable<T, F>(table_size, entry_size) {}
310
311 TwoOopHashtable(int table_size, int entry_size, HashtableBucket<F>* t,
312 int number_of_entries)
313 : Hashtable<T, F>(table_size, entry_size, t, number_of_entries) {}
314
315 public:
|
161 void reverse();
162
163 private:
164 // Instance variables
165 int _table_size;
166 HashtableBucket<F>* _buckets;
167 BasicHashtableEntry<F>* _free_list;
168 char* _first_free_entry;
169 char* _end_block;
170 int _entry_size;
171 int _number_of_entries;
172
173 protected:
174
175 #ifdef ASSERT
176 int _lookup_count;
177 int _lookup_length;
178 void verify_lookup_length(double load);
179 #endif
180
181 void initialize(int table_size, int entry_size, int number_of_entries);
182
183 // Accessor
184 int entry_size() const { return _entry_size; }
185
186 // The following method is MT-safe and may be used with caution.
187 BasicHashtableEntry<F>* bucket(int i);
188
189 // The following method is not MT-safe and must be done under lock.
190 BasicHashtableEntry<F>** bucket_addr(int i) { return _buckets[i].entry_addr(); }
191
192 // Attempt to get an entry from the free list
193 BasicHashtableEntry<F>* new_entry_free_list();
194
195 // Table entry management
196 BasicHashtableEntry<F>* new_entry(unsigned int hashValue);
197
198 // Used when moving the entry to another table
199 // Clean up links, but do not add to free_list
200 void unlink_entry(BasicHashtableEntry<F>* entry) {
201 entry->set_next(NULL);
202 --_number_of_entries;
203 }
204
205 // Move over freelist and free block for allocation
206 void copy_freelist(BasicHashtable* src) {
207 _free_list = src->_free_list;
208 src->_free_list = NULL;
209 _first_free_entry = src->_first_free_entry;
210 src->_first_free_entry = NULL;
211 _end_block = src->_end_block;
212 src->_end_block = NULL;
213 }
214
215 // Free the buckets in this hashtable
216 void free_buckets();
217
255 return (unsigned int) name->identity_hash();
256 }
257
258 int index_for(Symbol* name) {
259 return this->hash_to_index(compute_hash(name));
260 }
261
262 // Table entry management
263 HashtableEntry<T, F>* new_entry(unsigned int hashValue, T obj);
264
265 // The following method is MT-safe and may be used with caution.
266 HashtableEntry<T, F>* bucket(int i) {
267 return (HashtableEntry<T, F>*)BasicHashtable<F>::bucket(i);
268 }
269
270 // The following method is not MT-safe and must be done under lock.
271 HashtableEntry<T, F>** bucket_addr(int i) {
272 return (HashtableEntry<T, F>**)BasicHashtable<F>::bucket_addr(i);
273 }
274
275 };
276
277 template <class T, MEMFLAGS F> class RehashableHashtable : public Hashtable<T, F> {
278 protected:
279
280 enum {
281 rehash_count = 100,
282 rehash_multiple = 60
283 };
284
285 // Check that the table is unbalanced
286 bool check_rehash_table(int count);
287
288 public:
289 RehashableHashtable(int table_size, int entry_size)
290 : Hashtable<T, F>(table_size, entry_size) { }
291
292 RehashableHashtable(int table_size, int entry_size,
293 HashtableBucket<F>* buckets, int number_of_entries)
294 : Hashtable<T, F>(table_size, entry_size, buckets, number_of_entries) { }
295
296
297 // Function to move these elements into the new table.
298 void move_to(RehashableHashtable<T, F>* new_table);
299 static bool use_alternate_hashcode() { return _seed != 0; }
300 static juint seed() { return _seed; }
301
302 static int literal_size(Symbol *symbol);
303 static int literal_size(oop oop);
304
305 // The following two are currently not used, but are needed anyway because some
306 // C++ compilers (MacOS and Solaris) force the instantiation of
307 // Hashtable<ConstantPool*, mtClass>::dump_table() even though we never call this function
308 // in the VM code.
309 static int literal_size(ConstantPool *cp) {Unimplemented(); return 0;}
310 static int literal_size(Klass *k) {Unimplemented(); return 0;}
311
312 void dump_table(outputStream* st, const char *table_name);
313
314 private:
315 static juint _seed;
316 };
317
318
319 // Verions of hashtable where two handles are used to compute the index.
320
321 template <class T, MEMFLAGS F> class TwoOopHashtable : public Hashtable<T, F> {
322 friend class VMStructs;
323 protected:
324 TwoOopHashtable(int table_size, int entry_size)
325 : Hashtable<T, F>(table_size, entry_size) {}
326
327 TwoOopHashtable(int table_size, int entry_size, HashtableBucket<F>* t,
328 int number_of_entries)
329 : Hashtable<T, F>(table_size, entry_size, t, number_of_entries) {}
330
331 public:
|