25 #include "precompiled.hpp" |
25 #include "precompiled.hpp" |
26 #include "gc/cms/allocationStats.hpp" |
26 #include "gc/cms/allocationStats.hpp" |
27 #include "gc/shared/spaceDecorator.hpp" |
27 #include "gc/shared/spaceDecorator.hpp" |
28 #include "logging/logStream.inline.hpp" |
28 #include "logging/logStream.inline.hpp" |
29 #include "memory/binaryTreeDictionary.hpp" |
29 #include "memory/binaryTreeDictionary.hpp" |
30 #include "memory/freeBlockDictionary.hpp" |
|
31 #include "memory/freeList.hpp" |
30 #include "memory/freeList.hpp" |
32 #include "memory/metachunk.hpp" |
31 #include "memory/metachunk.hpp" |
33 #include "memory/resourceArea.hpp" |
32 #include "memory/resourceArea.hpp" |
34 #include "runtime/globals.hpp" |
33 #include "runtime/globals.hpp" |
35 #include "utilities/macros.hpp" |
34 #include "utilities/macros.hpp" |
421 } |
420 } |
422 |
421 |
423 // Get a free block of size at least size from tree, or NULL. |
422 // Get a free block of size at least size from tree, or NULL. |
424 template <class Chunk_t, class FreeList_t> |
423 template <class Chunk_t, class FreeList_t> |
425 TreeChunk<Chunk_t, FreeList_t>* |
424 TreeChunk<Chunk_t, FreeList_t>* |
426 BinaryTreeDictionary<Chunk_t, FreeList_t>::get_chunk_from_tree( |
425 BinaryTreeDictionary<Chunk_t, FreeList_t>::get_chunk_from_tree(size_t size) |
427 size_t size, |
|
428 enum FreeBlockDictionary<Chunk_t>::Dither dither) |
|
429 { |
426 { |
430 TreeList<Chunk_t, FreeList_t> *curTL, *prevTL; |
427 TreeList<Chunk_t, FreeList_t> *curTL, *prevTL; |
431 TreeChunk<Chunk_t, FreeList_t>* retTC = NULL; |
428 TreeChunk<Chunk_t, FreeList_t>* retTC = NULL; |
432 |
429 |
433 assert((size >= min_size()), "minimum chunk size"); |
430 assert((size >= min_size()), "minimum chunk size"); |
447 assert(curTL->size() > size, "size inconsistency"); |
444 assert(curTL->size() > size, "size inconsistency"); |
448 curTL = curTL->left(); |
445 curTL = curTL->left(); |
449 } |
446 } |
450 } |
447 } |
451 if (curTL == NULL) { // couldn't find exact match |
448 if (curTL == NULL) { // couldn't find exact match |
452 |
|
453 if (dither == FreeBlockDictionary<Chunk_t>::exactly) return NULL; |
|
454 |
449 |
455 // try and find the next larger size by walking back up the search path |
450 // try and find the next larger size by walking back up the search path |
456 for (curTL = prevTL; curTL != NULL;) { |
451 for (curTL = prevTL; curTL != NULL;) { |
457 if (curTL->size() >= size) break; |
452 if (curTL->size() >= size) break; |
458 else curTL = curTL->parent(); |
453 else curTL = curTL->parent(); |
767 } |
762 } |
768 } |
763 } |
769 |
764 |
770 template <class Chunk_t, class FreeList_t> |
765 template <class Chunk_t, class FreeList_t> |
771 size_t BinaryTreeDictionary<Chunk_t, FreeList_t>::max_chunk_size() const { |
766 size_t BinaryTreeDictionary<Chunk_t, FreeList_t>::max_chunk_size() const { |
772 FreeBlockDictionary<Chunk_t>::verify_par_locked(); |
767 verify_par_locked(); |
773 TreeList<Chunk_t, FreeList_t>* tc = root(); |
768 TreeList<Chunk_t, FreeList_t>* tc = root(); |
774 if (tc == NULL) return 0; |
769 if (tc == NULL) return 0; |
775 for (; tc->right() != NULL; tc = tc->right()); |
770 for (; tc->right() != NULL; tc = tc->right()); |
776 return tc->size(); |
771 return tc->size(); |
777 } |
772 } |
1107 size_t BinaryTreeDictionary<Chunk_t, FreeList_t>::total_count() { |
1102 size_t BinaryTreeDictionary<Chunk_t, FreeList_t>::total_count() { |
1108 treeCountClosure<Chunk_t, FreeList_t> ctc(0); |
1103 treeCountClosure<Chunk_t, FreeList_t> ctc(0); |
1109 ctc.do_tree(root()); |
1104 ctc.do_tree(root()); |
1110 return ctc.count; |
1105 return ctc.count; |
1111 } |
1106 } |
|
1107 |
|
1108 template <class Chunk_t, class FreeList_t> |
|
1109 Mutex* BinaryTreeDictionary<Chunk_t, FreeList_t>::par_lock() const { |
|
1110 return _lock; |
|
1111 } |
|
1112 |
|
1113 template <class Chunk_t, class FreeList_t> |
|
1114 void BinaryTreeDictionary<Chunk_t, FreeList_t>::set_par_lock(Mutex* lock) { |
|
1115 _lock = lock; |
|
1116 } |
|
1117 |
|
1118 template <class Chunk_t, class FreeList_t> |
|
1119 void BinaryTreeDictionary<Chunk_t, FreeList_t>::verify_par_locked() const { |
|
1120 #ifdef ASSERT |
|
1121 Thread* my_thread = Thread::current(); |
|
1122 if (my_thread->is_GC_task_thread()) { |
|
1123 assert(par_lock() != NULL, "Should be using locking?"); |
|
1124 assert_lock_strong(par_lock()); |
|
1125 } |
|
1126 #endif // ASSERT |
|
1127 } |
1112 #endif // PRODUCT |
1128 #endif // PRODUCT |
1113 |
1129 |
1114 // Calculate surpluses for the lists in the tree. |
1130 // Calculate surpluses for the lists in the tree. |
1115 template <class Chunk_t, class FreeList_t> |
1131 template <class Chunk_t, class FreeList_t> |
1116 class setTreeSurplusClosure : public AscendTreeCensusClosure<Chunk_t, FreeList_t> { |
1132 class setTreeSurplusClosure : public AscendTreeCensusClosure<Chunk_t, FreeList_t> { |
1197 } |
1213 } |
1198 |
1214 |
1199 // Print summary statistics |
1215 // Print summary statistics |
1200 template <class Chunk_t, class FreeList_t> |
1216 template <class Chunk_t, class FreeList_t> |
1201 void BinaryTreeDictionary<Chunk_t, FreeList_t>::report_statistics(outputStream* st) const { |
1217 void BinaryTreeDictionary<Chunk_t, FreeList_t>::report_statistics(outputStream* st) const { |
1202 FreeBlockDictionary<Chunk_t>::verify_par_locked(); |
1218 verify_par_locked(); |
1203 st->print_cr("Statistics for BinaryTreeDictionary:"); |
1219 st->print_cr("Statistics for BinaryTreeDictionary:"); |
1204 st->print_cr("------------------------------------"); |
1220 st->print_cr("------------------------------------"); |
1205 size_t total_size = total_chunk_size(debug_only(NULL)); |
1221 size_t total_size = total_chunk_size(debug_only(NULL)); |
1206 size_t free_blocks = num_free_blocks(); |
1222 size_t free_blocks = num_free_blocks(); |
1207 st->print_cr("Total Free Space: " SIZE_FORMAT, total_size); |
1223 st->print_cr("Total Free Space: " SIZE_FORMAT, total_size); |