Mercurial > hg > truffle
comparison src/share/vm/utilities/hashtable.cpp @ 14521:29ccc4cbabca
Merge
author | Gilles Duboscq <duboscq@ssw.jku.at> |
---|---|
date | Wed, 12 Mar 2014 13:30:08 +0100 |
parents | 524b54a7f1b5 |
children | 3c6ae9109a86 4ca6dc0799b6 |
comparison
equal
deleted
inserted
replaced
14520:f84115370178 | 14521:29ccc4cbabca |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
23 */ | 23 */ |
24 | 24 |
25 #include "precompiled.hpp" | 25 #include "precompiled.hpp" |
26 #include "classfile/altHashing.hpp" | 26 #include "classfile/altHashing.hpp" |
27 #include "classfile/javaClasses.hpp" | 27 #include "classfile/javaClasses.hpp" |
28 #include "code/dependencies.hpp" | |
28 #include "memory/allocation.inline.hpp" | 29 #include "memory/allocation.inline.hpp" |
29 #include "memory/filemap.hpp" | 30 #include "memory/filemap.hpp" |
30 #include "memory/resourceArea.hpp" | 31 #include "memory/resourceArea.hpp" |
31 #include "oops/oop.inline.hpp" | 32 #include "oops/oop.inline.hpp" |
32 #include "runtime/safepoint.hpp" | 33 #include "runtime/safepoint.hpp" |
91 return true; | 92 return true; |
92 } | 93 } |
93 return false; | 94 return false; |
94 } | 95 } |
95 | 96 |
96 template <class T, MEMFLAGS F> jint Hashtable<T, F>::_seed = 0; | 97 template <class T, MEMFLAGS F> juint Hashtable<T, F>::_seed = 0; |
97 | 98 |
98 // Create a new table and using alternate hash code, populate the new table | 99 // Create a new table and using alternate hash code, populate the new table |
99 // with the existing elements. This can be used to change the hash code | 100 // with the existing elements. This can be used to change the hash code |
100 // and could in the future change the size of the table. | 101 // and could in the future change the size of the table. |
101 | 102 |
336 } | 337 } |
337 | 338 |
338 | 339 |
339 #endif // PRODUCT | 340 #endif // PRODUCT |
340 | 341 |
341 | |
342 #ifdef ASSERT | 342 #ifdef ASSERT |
343 | 343 |
344 template <MEMFLAGS F> void BasicHashtable<F>::verify_lookup_length(double load) { | 344 template <MEMFLAGS F> void BasicHashtable<F>::verify_lookup_length(double load) { |
345 if ((double)_lookup_length / (double)_lookup_count > load * 2.0) { | 345 if ((double)_lookup_length / (double)_lookup_count > load * 2.0) { |
346 warning("Performance bug: SystemDictionary lookup_count=%d " | 346 warning("Performance bug: SystemDictionary lookup_count=%d " |
349 (double) _lookup_length / _lookup_count, load); | 349 (double) _lookup_length / _lookup_count, load); |
350 } | 350 } |
351 } | 351 } |
352 | 352 |
353 #endif | 353 #endif |
354 | |
355 | |
356 template<class T, class M> GenericHashtable<T, M>::GenericHashtable(int size, bool C_heap, MEMFLAGS memflag) { | |
357 assert(size > 0, " Invalid hashtable size"); | |
358 _size = size; | |
359 _C_heap = C_heap; | |
360 _memflag = memflag; | |
361 // Perform subtype-specific resource allocation | |
362 _items = (C_heap) ? NEW_C_HEAP_ARRAY(T*, size, memflag) : NEW_RESOURCE_ARRAY(T*, size); | |
363 memset(_items, 0, sizeof(T*) * size); | |
364 | |
365 DEBUG_ONLY(_num_items = 0;) | |
366 } | |
367 | |
368 template<class T, class M> GenericHashtable<T, M>::~GenericHashtable() { | |
369 if (on_C_heap()) { | |
370 // Check backing array | |
371 for (int i = 0; i < size(); i++) { | |
372 T* item = head(i); | |
373 // Delete all items in linked list | |
374 while (item != NULL) { | |
375 T* next_item = item->next(); | |
376 delete item; | |
377 DEBUG_ONLY(_num_items--); | |
378 item = next_item; | |
379 } | |
380 } | |
381 FREE_C_HEAP_ARRAY(T*, _items, _memflag); | |
382 _items = NULL; | |
383 assert (_num_items == 0, "Not all memory released"); | |
384 } | |
385 } | |
386 | |
387 /** | |
388 * Return a pointer to the item 'I' that is stored in the hashtable for | |
389 * which match_item->equals(I) == true. If no such item is found, NULL | |
390 * is returned. | |
391 */ | |
392 template<class T, class F> T* GenericHashtable<T, F>::contains(T* match_item) { | |
393 if (match_item != NULL) { | |
394 int idx = index(match_item); | |
395 return contains_impl(match_item, idx); | |
396 } | |
397 return NULL; | |
398 } | |
399 | |
400 /** | |
401 * Add item to the hashtable. Return 'true' if the item was added | |
402 * and false otherwise. | |
403 */ | |
404 template<class T, class F> bool GenericHashtable<T, F>::add(T* item) { | |
405 if (item != NULL) { | |
406 int idx = index(item); | |
407 T* found_item = contains_impl(item, idx); | |
408 if (found_item == NULL) { | |
409 T* list_head = head(idx); | |
410 item->set_next(list_head); | |
411 item->set_prev(NULL); | |
412 | |
413 if (list_head != NULL) { | |
414 list_head->set_prev(item); | |
415 } | |
416 set_head(item, idx); | |
417 DEBUG_ONLY(_num_items++); | |
418 return true; | |
419 } | |
420 } | |
421 return false; | |
422 } | |
423 | |
424 /** | |
425 * Removes an item 'I' from the hashtable, if present. 'I' is removed, if | |
426 * match_item->equals(I) == true. Removing an item from the hashtable does | |
427 * not free memory. | |
428 */ | |
429 template<class T, class F> T* GenericHashtable<T, F>::remove(T* match_item) { | |
430 if (match_item != NULL) { | |
431 int idx = index(match_item); | |
432 T* found_item = contains_impl(match_item, idx); | |
433 if (found_item != NULL) { | |
434 // Remove item from linked list | |
435 T* prev = found_item->prev(); | |
436 T* next = found_item->next(); | |
437 if (prev != NULL) { | |
438 prev->set_next(next); | |
439 } else { | |
440 set_head(next, idx); | |
441 } | |
442 if (next != NULL) { | |
443 next->set_prev(prev); | |
444 } | |
445 | |
446 DEBUG_ONLY(_num_items--); | |
447 return found_item; | |
448 } | |
449 } | |
450 return NULL; | |
451 } | |
452 | |
453 | |
454 template<class T, class F> T* GenericHashtable<T, F>::contains_impl(T* item, int idx) { | |
455 T* current_item = head(idx); | |
456 while (current_item != NULL) { | |
457 if (current_item->equals(item)) { | |
458 return current_item; | |
459 } | |
460 current_item = current_item->next(); | |
461 } | |
462 return NULL; | |
463 } | |
464 | |
465 | |
354 // Explicitly instantiate these types | 466 // Explicitly instantiate these types |
355 template class Hashtable<ConstantPool*, mtClass>; | 467 template class Hashtable<ConstantPool*, mtClass>; |
356 template class Hashtable<Symbol*, mtSymbol>; | 468 template class Hashtable<Symbol*, mtSymbol>; |
357 template class Hashtable<Klass*, mtClass>; | 469 template class Hashtable<Klass*, mtClass>; |
358 template class Hashtable<oop, mtClass>; | 470 template class Hashtable<oop, mtClass>; |
368 template class BasicHashtableEntry<mtCode>; | 480 template class BasicHashtableEntry<mtCode>; |
369 template class BasicHashtable<mtClass>; | 481 template class BasicHashtable<mtClass>; |
370 template class BasicHashtable<mtSymbol>; | 482 template class BasicHashtable<mtSymbol>; |
371 template class BasicHashtable<mtCode>; | 483 template class BasicHashtable<mtCode>; |
372 template class BasicHashtable<mtInternal>; | 484 template class BasicHashtable<mtInternal>; |
485 | |
486 template class GenericHashtable<DependencySignature, ResourceObj>; |