262 } else { |
262 } else { |
263 return obj->size(); |
263 return obj->size(); |
264 } |
264 } |
265 } |
265 } |
266 |
266 |
|
267 template <MEMFLAGS F> bool BasicHashtable<F>::resize(int new_size) { |
|
268 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); |
|
269 |
|
270 // Allocate new buckets |
|
271 HashtableBucket<F>* buckets_new = NEW_C_HEAP_ARRAY2_RETURN_NULL(HashtableBucket<F>, new_size, F, CURRENT_PC); |
|
272 if (buckets_new == NULL) { |
|
273 return false; |
|
274 } |
|
275 |
|
276 // Clear the new buckets |
|
277 for (int i = 0; i < new_size; i++) { |
|
278 buckets_new[i].clear(); |
|
279 } |
|
280 |
|
281 int table_size_old = _table_size; |
|
282 // hash_to_index() uses _table_size, so switch the sizes now |
|
283 _table_size = new_size; |
|
284 |
|
285 // Move entries from the old table to a new table |
|
286 for (int index_old = 0; index_old < table_size_old; index_old++) { |
|
287 for (BasicHashtableEntry<F>* p = _buckets[index_old].get_entry(); p != NULL; ) { |
|
288 BasicHashtableEntry<F>* next = p->next(); |
|
289 bool keep_shared = p->is_shared(); |
|
290 int index_new = hash_to_index(p->hash()); |
|
291 |
|
292 p->set_next(buckets_new[index_new].get_entry()); |
|
293 buckets_new[index_new].set_entry(p); |
|
294 |
|
295 if (keep_shared) { |
|
296 p->set_shared(); |
|
297 } |
|
298 p = next; |
|
299 } |
|
300 } |
|
301 |
|
302 // The old backets now can be released |
|
303 BasicHashtable<F>::free_buckets(); |
|
304 |
|
305 // Switch to the new storage |
|
306 _buckets = buckets_new; |
|
307 |
|
308 return true; |
|
309 } |
267 |
310 |
268 // Dump footprint and bucket length statistics |
311 // Dump footprint and bucket length statistics |
269 // |
312 // |
270 // Note: if you create a new subclass of Hashtable<MyNewType, F>, you will need to |
313 // Note: if you create a new subclass of Hashtable<MyNewType, F>, you will need to |
271 // add a new function static int literal_size(MyNewType lit) |
314 // add a new function static int literal_size(MyNewType lit) |