comparison src/share/vm/memory/metaspace.cpp @ 12303:b960c9df4f11

8025096: Move the ChunkManager instances out of the VirtualSpaceLists Reviewed-by: coleenp, mgerdin, jmasa
author stefank
date Sat, 21 Sep 2013 10:09:42 +0200
parents 9361de86a50f
children 03f493ce3a71
comparison
equal deleted inserted replaced
12302:9361de86a50f 12303:b960c9df4f11
21 * questions. 21 * questions.
22 * 22 *
23 */ 23 */
24 #include "precompiled.hpp" 24 #include "precompiled.hpp"
25 #include "gc_interface/collectedHeap.hpp" 25 #include "gc_interface/collectedHeap.hpp"
26 #include "memory/allocation.hpp"
26 #include "memory/binaryTreeDictionary.hpp" 27 #include "memory/binaryTreeDictionary.hpp"
27 #include "memory/freeList.hpp" 28 #include "memory/freeList.hpp"
28 #include "memory/collectorPolicy.hpp" 29 #include "memory/collectorPolicy.hpp"
29 #include "memory/filemap.hpp" 30 #include "memory/filemap.hpp"
30 #include "memory/freeList.hpp" 31 #include "memory/freeList.hpp"
109 110
110 // Manages the global free lists of chunks. 111 // Manages the global free lists of chunks.
111 // Has three lists of free chunks, and a total size and 112 // Has three lists of free chunks, and a total size and
112 // count that includes all three 113 // count that includes all three
113 114
114 class ChunkManager VALUE_OBJ_CLASS_SPEC { 115 class ChunkManager : public CHeapObj<mtInternal> {
115 116
116 // Free list of chunks of different sizes. 117 // Free list of chunks of different sizes.
117 // SpecializedChunk 118 // SpecializedChunk
118 // SmallChunk 119 // SmallChunk
119 // MediumChunk 120 // MediumChunk
156 } 157 }
157 void verify_free_chunks_count(); 158 void verify_free_chunks_count();
158 159
159 public: 160 public:
160 161
161 ChunkManager() : _free_chunks_total(0), _free_chunks_count(0) {} 162 ChunkManager(size_t specialized_size, size_t small_size, size_t medium_size)
163 : _free_chunks_total(0), _free_chunks_count(0) {
164 _free_chunks[SpecializedIndex].set_size(specialized_size);
165 _free_chunks[SmallIndex].set_size(small_size);
166 _free_chunks[MediumIndex].set_size(medium_size);
167 }
162 168
163 // add or delete (return) a chunk to the global freelist. 169 // add or delete (return) a chunk to the global freelist.
164 Metachunk* chunk_freelist_allocate(size_t word_size); 170 Metachunk* chunk_freelist_allocate(size_t word_size);
165 void chunk_freelist_deallocate(Metachunk* chunk); 171 void chunk_freelist_deallocate(Metachunk* chunk);
166 172
217 void verify_free_chunks_total(); 223 void verify_free_chunks_total();
218 224
219 void locked_print_free_chunks(outputStream* st); 225 void locked_print_free_chunks(outputStream* st);
220 void locked_print_sum_free_chunks(outputStream* st); 226 void locked_print_sum_free_chunks(outputStream* st);
221 227
222 void print_on(outputStream* st); 228 void print_on(outputStream* st) const;
223 }; 229 };
224 230
225 // Used to manage the free list of Metablocks (a block corresponds 231 // Used to manage the free list of Metablocks (a block corresponds
226 // to the allocation of a quantum of metadata). 232 // to the allocation of a quantum of metadata).
227 class BlockFreelist VALUE_OBJ_CLASS_SPEC { 233 class BlockFreelist VALUE_OBJ_CLASS_SPEC {
274 280
275 // The first Metachunk will be allocated at the bottom of the 281 // The first Metachunk will be allocated at the bottom of the
276 // VirtualSpace 282 // VirtualSpace
277 Metachunk* first_chunk() { return (Metachunk*) bottom(); } 283 Metachunk* first_chunk() { return (Metachunk*) bottom(); }
278 284
279 void inc_container_count();
280 #ifdef ASSERT
281 uint container_count_slow();
282 #endif
283
284 public: 285 public:
285 286
286 VirtualSpaceNode(size_t byte_size); 287 VirtualSpaceNode(size_t byte_size);
287 VirtualSpaceNode(ReservedSpace rs) : _top(NULL), _next(NULL), _rs(rs), _container_count(0) {} 288 VirtualSpaceNode(ReservedSpace rs) : _top(NULL), _next(NULL), _rs(rs), _container_count(0) {}
288 ~VirtualSpaceNode(); 289 ~VirtualSpaceNode();
312 313
313 MetaWord* top() const { return _top; } 314 MetaWord* top() const { return _top; }
314 void inc_top(size_t word_size) { _top += word_size; } 315 void inc_top(size_t word_size) { _top += word_size; }
315 316
316 uintx container_count() { return _container_count; } 317 uintx container_count() { return _container_count; }
318 void inc_container_count();
317 void dec_container_count(); 319 void dec_container_count();
318 #ifdef ASSERT 320 #ifdef ASSERT
321 uint container_count_slow();
319 void verify_container_count(); 322 void verify_container_count();
320 #endif 323 #endif
321 324
322 // used and capacity in this single entry in the list 325 // used and capacity in this single entry in the list
323 size_t used_words_in_vs() const; 326 size_t used_words_in_vs() const;
419 // Global list of virtual spaces 422 // Global list of virtual spaces
420 // Head of the list 423 // Head of the list
421 VirtualSpaceNode* _virtual_space_list; 424 VirtualSpaceNode* _virtual_space_list;
422 // virtual space currently being used for allocations 425 // virtual space currently being used for allocations
423 VirtualSpaceNode* _current_virtual_space; 426 VirtualSpaceNode* _current_virtual_space;
424 // Free chunk list for all other metadata
425 ChunkManager _chunk_manager;
426 427
427 // Can this virtual list allocate >1 spaces? Also, used to determine 428 // Can this virtual list allocate >1 spaces? Also, used to determine
428 // whether to allocate unlimited small chunks in this virtual space 429 // whether to allocate unlimited small chunks in this virtual space
429 bool _is_class; 430 bool _is_class;
430 bool can_grow() const { return !is_class() || !UseCompressedClassPointers; } 431 bool can_grow() const { return !is_class() || !UseCompressedClassPointers; }
473 474
474 VirtualSpaceNode* current_virtual_space() { 475 VirtualSpaceNode* current_virtual_space() {
475 return _current_virtual_space; 476 return _current_virtual_space;
476 } 477 }
477 478
478 ChunkManager* chunk_manager() { return &_chunk_manager; }
479 bool is_class() const { return _is_class; } 479 bool is_class() const { return _is_class; }
480 480
481 // Allocate the first virtualspace. 481 // Allocate the first virtualspace.
482 void initialize(size_t word_size); 482 void initialize(size_t word_size);
483 483
492 void dec_committed_words(size_t v); 492 void dec_committed_words(size_t v);
493 void inc_virtual_space_count(); 493 void inc_virtual_space_count();
494 void dec_virtual_space_count(); 494 void dec_virtual_space_count();
495 495
496 // Unlink empty VirtualSpaceNodes and free it. 496 // Unlink empty VirtualSpaceNodes and free it.
497 void purge(); 497 void purge(ChunkManager* chunk_manager);
498
499 // Used and capacity in the entire list of virtual spaces.
500 // These are global values shared by all Metaspaces
501 size_t capacity_words_sum();
502 size_t capacity_bytes_sum() { return capacity_words_sum() * BytesPerWord; }
503 size_t used_words_sum();
504 size_t used_bytes_sum() { return used_words_sum() * BytesPerWord; }
505 498
506 bool contains(const void *ptr); 499 bool contains(const void *ptr);
507 500
508 void print_on(outputStream* st) const; 501 void print_on(outputStream* st) const;
509 502
580 Mutex* const _lock; 573 Mutex* const _lock;
581 574
582 // Type of metadata allocated. 575 // Type of metadata allocated.
583 Metaspace::MetadataType _mdtype; 576 Metaspace::MetadataType _mdtype;
584 577
585 // Chunk related size
586 size_t _medium_chunk_bunch;
587
588 // List of chunks in use by this SpaceManager. Allocations 578 // List of chunks in use by this SpaceManager. Allocations
589 // are done from the current chunk. The list is used for deallocating 579 // are done from the current chunk. The list is used for deallocating
590 // chunks when the SpaceManager is freed. 580 // chunks when the SpaceManager is freed.
591 Metachunk* _chunks_in_use[NumberOfInUseLists]; 581 Metachunk* _chunks_in_use[NumberOfInUseLists];
592 Metachunk* _current_chunk; 582 Metachunk* _current_chunk;
593 583
594 // Virtual space where allocation comes from.
595 VirtualSpaceList* _vs_list;
596
597 // Number of small chunks to allocate to a manager 584 // Number of small chunks to allocate to a manager
598 // If class space manager, small chunks are unlimited 585 // If class space manager, small chunks are unlimited
599 static uint const _small_chunk_limit; 586 static uint const _small_chunk_limit;
600 587
601 // Sum of all space in allocated chunks 588 // Sum of all space in allocated chunks
624 BlockFreelist* block_freelists() const { 611 BlockFreelist* block_freelists() const {
625 return (BlockFreelist*) &_block_freelists; 612 return (BlockFreelist*) &_block_freelists;
626 } 613 }
627 614
628 Metaspace::MetadataType mdtype() { return _mdtype; } 615 Metaspace::MetadataType mdtype() { return _mdtype; }
629 VirtualSpaceList* vs_list() const { return _vs_list; } 616
617 VirtualSpaceList* vs_list() const { return Metaspace::get_space_list(_mdtype); }
618 ChunkManager* chunk_manager() const { return Metaspace::get_chunk_manager(_mdtype); }
630 619
631 Metachunk* current_chunk() const { return _current_chunk; } 620 Metachunk* current_chunk() const { return _current_chunk; }
632 void set_current_chunk(Metachunk* v) { 621 void set_current_chunk(Metachunk* v) {
633 _current_chunk = v; 622 _current_chunk = v;
634 } 623 }
646 protected: 635 protected:
647 void initialize(); 636 void initialize();
648 637
649 public: 638 public:
650 SpaceManager(Metaspace::MetadataType mdtype, 639 SpaceManager(Metaspace::MetadataType mdtype,
651 Mutex* lock, 640 Mutex* lock);
652 VirtualSpaceList* vs_list);
653 ~SpaceManager(); 641 ~SpaceManager();
654 642
655 enum ChunkMultiples { 643 enum ChunkMultiples {
656 MediumChunkMultiple = 4 644 MediumChunkMultiple = 4
657 }; 645 };
658 646
647 bool is_class() { return _mdtype == Metaspace::ClassType; }
648
659 // Accessors 649 // Accessors
660 size_t specialized_chunk_size() { return SpecializedChunk; } 650 size_t specialized_chunk_size() { return SpecializedChunk; }
661 size_t small_chunk_size() { return (size_t) vs_list()->is_class() ? ClassSmallChunk : SmallChunk; } 651 size_t small_chunk_size() { return (size_t) is_class() ? ClassSmallChunk : SmallChunk; }
662 size_t medium_chunk_size() { return (size_t) vs_list()->is_class() ? ClassMediumChunk : MediumChunk; } 652 size_t medium_chunk_size() { return (size_t) is_class() ? ClassMediumChunk : MediumChunk; }
663 size_t medium_chunk_bunch() { return medium_chunk_size() * MediumChunkMultiple; } 653 size_t medium_chunk_bunch() { return medium_chunk_size() * MediumChunkMultiple; }
664 654
665 size_t allocated_blocks_words() const { return _allocated_blocks_words; } 655 size_t allocated_blocks_words() const { return _allocated_blocks_words; }
666 size_t allocated_blocks_bytes() const { return _allocated_blocks_words * BytesPerWord; } 656 size_t allocated_blocks_bytes() const { return _allocated_blocks_words * BytesPerWord; }
667 size_t allocated_chunks_words() const { return _allocated_chunks_words; } 657 size_t allocated_chunks_words() const { return _allocated_chunks_words; }
760 void VirtualSpaceNode::inc_container_count() { 750 void VirtualSpaceNode::inc_container_count() {
761 assert_lock_strong(SpaceManager::expand_lock()); 751 assert_lock_strong(SpaceManager::expand_lock());
762 _container_count++; 752 _container_count++;
763 assert(_container_count == container_count_slow(), 753 assert(_container_count == container_count_slow(),
764 err_msg("Inconsistency in countainer_count _container_count " SIZE_FORMAT 754 err_msg("Inconsistency in countainer_count _container_count " SIZE_FORMAT
765 "container_count_slow() " SIZE_FORMAT, 755 " container_count_slow() " SIZE_FORMAT,
766 _container_count, container_count_slow())); 756 _container_count, container_count_slow()));
767 } 757 }
768 758
769 void VirtualSpaceNode::dec_container_count() { 759 void VirtualSpaceNode::dec_container_count() {
770 assert_lock_strong(SpaceManager::expand_lock()); 760 assert_lock_strong(SpaceManager::expand_lock());
773 763
774 #ifdef ASSERT 764 #ifdef ASSERT
775 void VirtualSpaceNode::verify_container_count() { 765 void VirtualSpaceNode::verify_container_count() {
776 assert(_container_count == container_count_slow(), 766 assert(_container_count == container_count_slow(),
777 err_msg("Inconsistency in countainer_count _container_count " SIZE_FORMAT 767 err_msg("Inconsistency in countainer_count _container_count " SIZE_FORMAT
778 "container_count_slow() " SIZE_FORMAT, _container_count, container_count_slow())); 768 " container_count_slow() " SIZE_FORMAT, _container_count, container_count_slow()));
779 } 769 }
780 #endif 770 #endif
781 771
782 // BlockFreelist methods 772 // BlockFreelist methods
783 773
1018 } 1008 }
1019 1009
1020 // Walk the list of VirtualSpaceNodes and delete 1010 // Walk the list of VirtualSpaceNodes and delete
1021 // nodes with a 0 container_count. Remove Metachunks in 1011 // nodes with a 0 container_count. Remove Metachunks in
1022 // the node from their respective freelists. 1012 // the node from their respective freelists.
1023 void VirtualSpaceList::purge() { 1013 void VirtualSpaceList::purge(ChunkManager* chunk_manager) {
1024 assert_lock_strong(SpaceManager::expand_lock()); 1014 assert_lock_strong(SpaceManager::expand_lock());
1025 // Don't use a VirtualSpaceListIterator because this 1015 // Don't use a VirtualSpaceListIterator because this
1026 // list is being changed and a straightforward use of an iterator is not safe. 1016 // list is being changed and a straightforward use of an iterator is not safe.
1027 VirtualSpaceNode* purged_vsl = NULL; 1017 VirtualSpaceNode* purged_vsl = NULL;
1028 VirtualSpaceNode* prev_vsl = virtual_space_list(); 1018 VirtualSpaceNode* prev_vsl = virtual_space_list();
1040 set_virtual_space_list(vsl->next()); 1030 set_virtual_space_list(vsl->next());
1041 } else { 1031 } else {
1042 prev_vsl->set_next(vsl->next()); 1032 prev_vsl->set_next(vsl->next());
1043 } 1033 }
1044 1034
1045 vsl->purge(chunk_manager()); 1035 vsl->purge(chunk_manager);
1046 dec_reserved_words(vsl->reserved_words()); 1036 dec_reserved_words(vsl->reserved_words());
1047 dec_committed_words(vsl->committed_words()); 1037 dec_committed_words(vsl->committed_words());
1048 dec_virtual_space_count(); 1038 dec_virtual_space_count();
1049 purged_vsl = vsl; 1039 purged_vsl = vsl;
1050 delete vsl; 1040 delete vsl;
1060 VirtualSpaceNode* vsl = iter.get_next(); 1050 VirtualSpaceNode* vsl = iter.get_next();
1061 assert(vsl != purged_vsl, "Purge of vsl failed"); 1051 assert(vsl != purged_vsl, "Purge of vsl failed");
1062 } 1052 }
1063 } 1053 }
1064 #endif 1054 #endif
1065 }
1066
1067 size_t VirtualSpaceList::used_words_sum() {
1068 size_t allocated_by_vs = 0;
1069 VirtualSpaceListIterator iter(virtual_space_list());
1070 while (iter.repeat()) {
1071 VirtualSpaceNode* vsl = iter.get_next();
1072 // Sum used region [bottom, top) in each virtualspace
1073 allocated_by_vs += vsl->used_words_in_vs();
1074 }
1075 assert(allocated_by_vs >= chunk_manager()->free_chunks_total_words(),
1076 err_msg("Total in free chunks " SIZE_FORMAT
1077 " greater than total from virtual_spaces " SIZE_FORMAT,
1078 allocated_by_vs, chunk_manager()->free_chunks_total_words()));
1079 size_t used =
1080 allocated_by_vs - chunk_manager()->free_chunks_total_words();
1081 return used;
1082 }
1083
1084 // Space available in all MetadataVirtualspaces allocated
1085 // for metadata. This is the upper limit on the capacity
1086 // of chunks allocated out of all the MetadataVirtualspaces.
1087 size_t VirtualSpaceList::capacity_words_sum() {
1088 size_t capacity = 0;
1089 VirtualSpaceListIterator iter(virtual_space_list());
1090 while (iter.repeat()) {
1091 VirtualSpaceNode* vsl = iter.get_next();
1092 capacity += vsl->capacity_words_in_vs();
1093 }
1094 return capacity;
1095 } 1055 }
1096 1056
1097 VirtualSpaceList::VirtualSpaceList(size_t word_size ) : 1057 VirtualSpaceList::VirtualSpaceList(size_t word_size ) :
1098 _is_class(false), 1058 _is_class(false),
1099 _virtual_space_list(NULL), 1059 _virtual_space_list(NULL),
1102 _committed_words(0), 1062 _committed_words(0),
1103 _virtual_space_count(0) { 1063 _virtual_space_count(0) {
1104 MutexLockerEx cl(SpaceManager::expand_lock(), 1064 MutexLockerEx cl(SpaceManager::expand_lock(),
1105 Mutex::_no_safepoint_check_flag); 1065 Mutex::_no_safepoint_check_flag);
1106 bool initialization_succeeded = grow_vs(word_size); 1066 bool initialization_succeeded = grow_vs(word_size);
1107
1108 _chunk_manager.free_chunks(SpecializedIndex)->set_size(SpecializedChunk);
1109 _chunk_manager.free_chunks(SmallIndex)->set_size(SmallChunk);
1110 _chunk_manager.free_chunks(MediumIndex)->set_size(MediumChunk);
1111 assert(initialization_succeeded, 1067 assert(initialization_succeeded,
1112 " VirtualSpaceList initialization should not fail"); 1068 " VirtualSpaceList initialization should not fail");
1113 } 1069 }
1114 1070
1115 VirtualSpaceList::VirtualSpaceList(ReservedSpace rs) : 1071 VirtualSpaceList::VirtualSpaceList(ReservedSpace rs) :
1121 _virtual_space_count(0) { 1077 _virtual_space_count(0) {
1122 MutexLockerEx cl(SpaceManager::expand_lock(), 1078 MutexLockerEx cl(SpaceManager::expand_lock(),
1123 Mutex::_no_safepoint_check_flag); 1079 Mutex::_no_safepoint_check_flag);
1124 VirtualSpaceNode* class_entry = new VirtualSpaceNode(rs); 1080 VirtualSpaceNode* class_entry = new VirtualSpaceNode(rs);
1125 bool succeeded = class_entry->initialize(); 1081 bool succeeded = class_entry->initialize();
1126 _chunk_manager.free_chunks(SpecializedIndex)->set_size(SpecializedChunk);
1127 _chunk_manager.free_chunks(SmallIndex)->set_size(ClassSmallChunk);
1128 _chunk_manager.free_chunks(MediumIndex)->set_size(ClassMediumChunk);
1129 assert(succeeded, " VirtualSpaceList initialization should not fail"); 1082 assert(succeeded, " VirtualSpaceList initialization should not fail");
1130 link_vs(class_entry); 1083 link_vs(class_entry);
1131 } 1084 }
1132 1085
1133 size_t VirtualSpaceList::free_bytes() { 1086 size_t VirtualSpaceList::free_bytes() {
1193 1146
1194 Metachunk* VirtualSpaceList::get_new_chunk(size_t word_size, 1147 Metachunk* VirtualSpaceList::get_new_chunk(size_t word_size,
1195 size_t grow_chunks_by_words, 1148 size_t grow_chunks_by_words,
1196 size_t medium_chunk_bunch) { 1149 size_t medium_chunk_bunch) {
1197 1150
1198 // Get a chunk from the chunk freelist 1151 // Allocate a chunk out of the current virtual space.
1199 Metachunk* next = chunk_manager()->chunk_freelist_allocate(grow_chunks_by_words); 1152 Metachunk* next = current_virtual_space()->get_chunk_vs(grow_chunks_by_words);
1200
1201 if (next != NULL) {
1202 next->container()->inc_container_count();
1203 } else {
1204 // Allocate a chunk out of the current virtual space.
1205 next = current_virtual_space()->get_chunk_vs(grow_chunks_by_words);
1206 }
1207 1153
1208 if (next == NULL) { 1154 if (next == NULL) {
1209 // Not enough room in current virtual space. Try to commit 1155 // Not enough room in current virtual space. Try to commit
1210 // more space. 1156 // more space.
1211 size_t expand_vs_by_words = MAX2(medium_chunk_bunch, 1157 size_t expand_vs_by_words = MAX2(medium_chunk_bunch,
1535 for (uint i = 0; i < metadata_deallocate_a_lock_chunk; i++) { 1481 for (uint i = 0; i < metadata_deallocate_a_lock_chunk; i++) {
1536 Metachunk* dummy_chunk = vsl->current_virtual_space()->take_from_committed(chunk_word_size); 1482 Metachunk* dummy_chunk = vsl->current_virtual_space()->take_from_committed(chunk_word_size);
1537 if (dummy_chunk == NULL) { 1483 if (dummy_chunk == NULL) {
1538 break; 1484 break;
1539 } 1485 }
1540 vsl->chunk_manager()->chunk_freelist_deallocate(dummy_chunk); 1486 sm->chunk_manager()->chunk_freelist_deallocate(dummy_chunk);
1541 1487
1542 if (TraceMetadataChunkAllocation && Verbose) { 1488 if (TraceMetadataChunkAllocation && Verbose) {
1543 gclog_or_tty->print("Metadebug::deallocate_chunk_a_lot: %d) ", 1489 gclog_or_tty->print("Metadebug::deallocate_chunk_a_lot: %d) ",
1544 sm->sum_count_in_chunks_in_use()); 1490 sm->sum_count_in_chunks_in_use());
1545 dummy_chunk->print_on(gclog_or_tty); 1491 dummy_chunk->print_on(gclog_or_tty);
1546 gclog_or_tty->print_cr(" Free chunks total %d count %d", 1492 gclog_or_tty->print_cr(" Free chunks total %d count %d",
1547 vsl->chunk_manager()->free_chunks_total_words(), 1493 sm->chunk_manager()->free_chunks_total_words(),
1548 vsl->chunk_manager()->free_chunks_count()); 1494 sm->chunk_manager()->free_chunks_count());
1549 } 1495 }
1550 } 1496 }
1551 } else { 1497 } else {
1552 Metadebug::inc_deallocate_chunk_a_lot_count(); 1498 Metadebug::inc_deallocate_chunk_a_lot_count();
1553 } 1499 }
1795 #ifdef ASSERT 1741 #ifdef ASSERT
1796 // Chunk is no longer on any freelist. Setting to false make container_count_slow() 1742 // Chunk is no longer on any freelist. Setting to false make container_count_slow()
1797 // work. 1743 // work.
1798 chunk->set_is_free(false); 1744 chunk->set_is_free(false);
1799 #endif 1745 #endif
1746 chunk->container()->inc_container_count();
1747
1800 slow_locked_verify(); 1748 slow_locked_verify();
1801 return chunk; 1749 return chunk;
1802 } 1750 }
1803 1751
1804 Metachunk* ChunkManager::chunk_freelist_allocate(size_t word_size) { 1752 Metachunk* ChunkManager::chunk_freelist_allocate(size_t word_size) {
1829 } 1777 }
1830 1778
1831 return chunk; 1779 return chunk;
1832 } 1780 }
1833 1781
1834 void ChunkManager::print_on(outputStream* out) { 1782 void ChunkManager::print_on(outputStream* out) const {
1835 if (PrintFLSStatistics != 0) { 1783 if (PrintFLSStatistics != 0) {
1836 humongous_dictionary()->report_statistics(); 1784 const_cast<ChunkManager *>(this)->humongous_dictionary()->report_statistics();
1837 } 1785 }
1838 } 1786 }
1839 1787
1840 // SpaceManager methods 1788 // SpaceManager methods
1841 1789
1978 } else { 1926 } else {
1979 st->print_cr(""); 1927 st->print_cr("");
1980 } 1928 }
1981 } 1929 }
1982 1930
1983 vs_list()->chunk_manager()->locked_print_free_chunks(st); 1931 chunk_manager()->locked_print_free_chunks(st);
1984 vs_list()->chunk_manager()->locked_print_sum_free_chunks(st); 1932 chunk_manager()->locked_print_sum_free_chunks(st);
1985 } 1933 }
1986 1934
1987 size_t SpaceManager::calc_chunk_size(size_t word_size) { 1935 size_t SpaceManager::calc_chunk_size(size_t word_size) {
1988 1936
1989 // Decide between a small chunk and a medium chunk. Up to 1937 // Decide between a small chunk and a medium chunk. Up to
2083 block_freelists()->total_size()); 2031 block_freelists()->total_size());
2084 } 2032 }
2085 } 2033 }
2086 2034
2087 SpaceManager::SpaceManager(Metaspace::MetadataType mdtype, 2035 SpaceManager::SpaceManager(Metaspace::MetadataType mdtype,
2088 Mutex* lock, 2036 Mutex* lock) :
2089 VirtualSpaceList* vs_list) :
2090 _vs_list(vs_list),
2091 _mdtype(mdtype), 2037 _mdtype(mdtype),
2092 _allocated_blocks_words(0), 2038 _allocated_blocks_words(0),
2093 _allocated_chunks_words(0), 2039 _allocated_chunks_words(0),
2094 _allocated_chunks_count(0), 2040 _allocated_chunks_count(0),
2095 _lock(lock) 2041 _lock(lock)
2171 sum_capacity_in_chunks_in_use(), allocated_chunks_words())); 2117 sum_capacity_in_chunks_in_use(), allocated_chunks_words()));
2172 2118
2173 MutexLockerEx fcl(SpaceManager::expand_lock(), 2119 MutexLockerEx fcl(SpaceManager::expand_lock(),
2174 Mutex::_no_safepoint_check_flag); 2120 Mutex::_no_safepoint_check_flag);
2175 2121
2176 ChunkManager* chunk_manager = vs_list()->chunk_manager(); 2122 chunk_manager()->slow_locked_verify();
2177
2178 chunk_manager->slow_locked_verify();
2179 2123
2180 dec_total_from_size_metrics(); 2124 dec_total_from_size_metrics();
2181 2125
2182 if (TraceMetadataChunkAllocation && Verbose) { 2126 if (TraceMetadataChunkAllocation && Verbose) {
2183 gclog_or_tty->print_cr("~SpaceManager(): " PTR_FORMAT, this); 2127 gclog_or_tty->print_cr("~SpaceManager(): " PTR_FORMAT, this);
2187 // Do not mangle freed Metachunks. The chunk size inside Metachunks 2131 // Do not mangle freed Metachunks. The chunk size inside Metachunks
2188 // is during the freeing of a VirtualSpaceNodes. 2132 // is during the freeing of a VirtualSpaceNodes.
2189 2133
2190 // Have to update before the chunks_in_use lists are emptied 2134 // Have to update before the chunks_in_use lists are emptied
2191 // below. 2135 // below.
2192 chunk_manager->inc_free_chunks_total(allocated_chunks_words(), 2136 chunk_manager()->inc_free_chunks_total(allocated_chunks_words(),
2193 sum_count_in_chunks_in_use()); 2137 sum_count_in_chunks_in_use());
2194 2138
2195 // Add all the chunks in use by this space manager 2139 // Add all the chunks in use by this space manager
2196 // to the global list of free chunks. 2140 // to the global list of free chunks.
2197 2141
2198 // Follow each list of chunks-in-use and add them to the 2142 // Follow each list of chunks-in-use and add them to the
2203 gclog_or_tty->print_cr("returned %d %s chunks to freelist", 2147 gclog_or_tty->print_cr("returned %d %s chunks to freelist",
2204 sum_count_in_chunks_in_use(i), 2148 sum_count_in_chunks_in_use(i),
2205 chunk_size_name(i)); 2149 chunk_size_name(i));
2206 } 2150 }
2207 Metachunk* chunks = chunks_in_use(i); 2151 Metachunk* chunks = chunks_in_use(i);
2208 chunk_manager->return_chunks(i, chunks); 2152 chunk_manager()->return_chunks(i, chunks);
2209 set_chunks_in_use(i, NULL); 2153 set_chunks_in_use(i, NULL);
2210 if (TraceMetadataChunkAllocation && Verbose) { 2154 if (TraceMetadataChunkAllocation && Verbose) {
2211 gclog_or_tty->print_cr("updated freelist count %d %s", 2155 gclog_or_tty->print_cr("updated freelist count %d %s",
2212 chunk_manager->free_chunks(i)->count(), 2156 chunk_manager()->free_chunks(i)->count(),
2213 chunk_size_name(i)); 2157 chunk_size_name(i));
2214 } 2158 }
2215 assert(i != HumongousIndex, "Humongous chunks are handled explicitly later"); 2159 assert(i != HumongousIndex, "Humongous chunks are handled explicitly later");
2216 } 2160 }
2217 2161
2244 err_msg("Humongous chunk size is wrong: word size " SIZE_FORMAT 2188 err_msg("Humongous chunk size is wrong: word size " SIZE_FORMAT
2245 " granularity %d", 2189 " granularity %d",
2246 humongous_chunks->word_size(), HumongousChunkGranularity)); 2190 humongous_chunks->word_size(), HumongousChunkGranularity));
2247 Metachunk* next_humongous_chunks = humongous_chunks->next(); 2191 Metachunk* next_humongous_chunks = humongous_chunks->next();
2248 humongous_chunks->container()->dec_container_count(); 2192 humongous_chunks->container()->dec_container_count();
2249 chunk_manager->humongous_dictionary()->return_chunk(humongous_chunks); 2193 chunk_manager()->humongous_dictionary()->return_chunk(humongous_chunks);
2250 humongous_chunks = next_humongous_chunks; 2194 humongous_chunks = next_humongous_chunks;
2251 } 2195 }
2252 if (TraceMetadataChunkAllocation && Verbose) { 2196 if (TraceMetadataChunkAllocation && Verbose) {
2253 gclog_or_tty->print_cr(""); 2197 gclog_or_tty->print_cr("");
2254 gclog_or_tty->print_cr("updated dictionary count %d %s", 2198 gclog_or_tty->print_cr("updated dictionary count %d %s",
2255 chunk_manager->humongous_dictionary()->total_count(), 2199 chunk_manager()->humongous_dictionary()->total_count(),
2256 chunk_size_name(HumongousIndex)); 2200 chunk_size_name(HumongousIndex));
2257 } 2201 }
2258 chunk_manager->slow_locked_verify(); 2202 chunk_manager()->slow_locked_verify();
2259 } 2203 }
2260 2204
2261 const char* SpaceManager::chunk_size_name(ChunkIndex index) const { 2205 const char* SpaceManager::chunk_size_name(ChunkIndex index) const {
2262 switch (index) { 2206 switch (index) {
2263 case SpecializedIndex: 2207 case SpecializedIndex:
2342 assert(new_chunk->is_empty(), "Not ready for reuse"); 2286 assert(new_chunk->is_empty(), "Not ready for reuse");
2343 if (TraceMetadataChunkAllocation && Verbose) { 2287 if (TraceMetadataChunkAllocation && Verbose) {
2344 gclog_or_tty->print("SpaceManager::add_chunk: %d) ", 2288 gclog_or_tty->print("SpaceManager::add_chunk: %d) ",
2345 sum_count_in_chunks_in_use()); 2289 sum_count_in_chunks_in_use());
2346 new_chunk->print_on(gclog_or_tty); 2290 new_chunk->print_on(gclog_or_tty);
2347 if (vs_list() != NULL) { 2291 chunk_manager()->locked_print_free_chunks(gclog_or_tty);
2348 vs_list()->chunk_manager()->locked_print_free_chunks(gclog_or_tty);
2349 }
2350 } 2292 }
2351 } 2293 }
2352 2294
2353 void SpaceManager::retire_current_chunk() { 2295 void SpaceManager::retire_current_chunk() {
2354 if (current_chunk() != NULL) { 2296 if (current_chunk() != NULL) {
2360 } 2302 }
2361 } 2303 }
2362 2304
2363 Metachunk* SpaceManager::get_new_chunk(size_t word_size, 2305 Metachunk* SpaceManager::get_new_chunk(size_t word_size,
2364 size_t grow_chunks_by_words) { 2306 size_t grow_chunks_by_words) {
2365 2307 // Get a chunk from the chunk freelist
2366 Metachunk* next = vs_list()->get_new_chunk(word_size, 2308 Metachunk* next = chunk_manager()->chunk_freelist_allocate(grow_chunks_by_words);
2367 grow_chunks_by_words, 2309
2368 medium_chunk_bunch()); 2310 if (next == NULL) {
2311 next = vs_list()->get_new_chunk(word_size,
2312 grow_chunks_by_words,
2313 medium_chunk_bunch());
2314 }
2369 2315
2370 if (TraceMetadataHumongousAllocation && next != NULL && 2316 if (TraceMetadataHumongousAllocation && next != NULL &&
2371 SpaceManager::is_humongous(next->word_size())) { 2317 SpaceManager::is_humongous(next->word_size())) {
2372 gclog_or_tty->print_cr(" new humongous chunk word size " 2318 gclog_or_tty->print_cr(" new humongous chunk word size "
2373 PTR_FORMAT, next->word_size()); 2319 PTR_FORMAT, next->word_size());
2643 } 2589 }
2644 2590
2645 size_t MetaspaceAux::min_chunk_size_words() { return Metaspace::first_chunk_word_size(); } 2591 size_t MetaspaceAux::min_chunk_size_words() { return Metaspace::first_chunk_word_size(); }
2646 2592
2647 size_t MetaspaceAux::free_chunks_total_words(Metaspace::MetadataType mdtype) { 2593 size_t MetaspaceAux::free_chunks_total_words(Metaspace::MetadataType mdtype) {
2648 VirtualSpaceList* list = Metaspace::get_space_list(mdtype); 2594 ChunkManager* chunk_manager = Metaspace::get_chunk_manager(mdtype);
2649 if (list == NULL) { 2595 if (chunk_manager == NULL) {
2650 return 0; 2596 return 0;
2651 } 2597 }
2652 ChunkManager* chunk = list->chunk_manager(); 2598 chunk_manager->slow_verify();
2653 chunk->slow_verify(); 2599 return chunk_manager->free_chunks_total_words();
2654 return chunk->free_chunks_total_words();
2655 } 2600 }
2656 2601
2657 size_t MetaspaceAux::free_chunks_total_bytes(Metaspace::MetadataType mdtype) { 2602 size_t MetaspaceAux::free_chunks_total_bytes(Metaspace::MetadataType mdtype) {
2658 return free_chunks_total_words(mdtype) * BytesPerWord; 2603 return free_chunks_total_words(mdtype) * BytesPerWord;
2659 } 2604 }
2800 out->print("class space: "); print_on(out, Metaspace::ClassType); 2745 out->print("class space: "); print_on(out, Metaspace::ClassType);
2801 print_waste(out); 2746 print_waste(out);
2802 } 2747 }
2803 2748
2804 void MetaspaceAux::verify_free_chunks() { 2749 void MetaspaceAux::verify_free_chunks() {
2805 Metaspace::space_list()->chunk_manager()->verify(); 2750 Metaspace::chunk_manager_metadata()->verify();
2806 if (Metaspace::using_class_space()) { 2751 if (Metaspace::using_class_space()) {
2807 Metaspace::class_space_list()->chunk_manager()->verify(); 2752 Metaspace::chunk_manager_class()->verify();
2808 } 2753 }
2809 } 2754 }
2810 2755
2811 void MetaspaceAux::verify_capacity() { 2756 void MetaspaceAux::verify_capacity() {
2812 #ifdef ASSERT 2757 #ifdef ASSERT
2873 } 2818 }
2874 2819
2875 VirtualSpaceList* Metaspace::_space_list = NULL; 2820 VirtualSpaceList* Metaspace::_space_list = NULL;
2876 VirtualSpaceList* Metaspace::_class_space_list = NULL; 2821 VirtualSpaceList* Metaspace::_class_space_list = NULL;
2877 2822
2823 ChunkManager* Metaspace::_chunk_manager_metadata = NULL;
2824 ChunkManager* Metaspace::_chunk_manager_class = NULL;
2825
2878 #define VIRTUALSPACEMULTIPLIER 2 2826 #define VIRTUALSPACEMULTIPLIER 2
2879 2827
2880 #ifdef _LP64 2828 #ifdef _LP64
2881 void Metaspace::set_narrow_klass_base_and_shift(address metaspace_base, address cds_base) { 2829 void Metaspace::set_narrow_klass_base_and_shift(address metaspace_base, address cds_base) {
2882 // Figure out the narrow_klass_base and the narrow_klass_shift. The 2830 // Figure out the narrow_klass_base and the narrow_klass_shift. The
2980 // The reserved space size may be bigger because of alignment, esp with UseLargePages 2928 // The reserved space size may be bigger because of alignment, esp with UseLargePages
2981 assert(rs.size() >= CompressedClassSpaceSize, 2929 assert(rs.size() >= CompressedClassSpaceSize,
2982 err_msg(SIZE_FORMAT " != " UINTX_FORMAT, rs.size(), CompressedClassSpaceSize)); 2930 err_msg(SIZE_FORMAT " != " UINTX_FORMAT, rs.size(), CompressedClassSpaceSize));
2983 assert(using_class_space(), "Must be using class space"); 2931 assert(using_class_space(), "Must be using class space");
2984 _class_space_list = new VirtualSpaceList(rs); 2932 _class_space_list = new VirtualSpaceList(rs);
2933 _chunk_manager_class = new ChunkManager(SpecializedChunk, ClassSmallChunk, ClassMediumChunk);
2985 } 2934 }
2986 2935
2987 #endif 2936 #endif
2988 2937
2989 void Metaspace::global_initialize() { 2938 void Metaspace::global_initialize() {
3005 // Initialize with the sum of the shared space sizes. The read-only 2954 // Initialize with the sum of the shared space sizes. The read-only
3006 // and read write metaspace chunks will be allocated out of this and the 2955 // and read write metaspace chunks will be allocated out of this and the
3007 // remainder is the misc code and data chunks. 2956 // remainder is the misc code and data chunks.
3008 cds_total = FileMapInfo::shared_spaces_size(); 2957 cds_total = FileMapInfo::shared_spaces_size();
3009 _space_list = new VirtualSpaceList(cds_total/wordSize); 2958 _space_list = new VirtualSpaceList(cds_total/wordSize);
2959 _chunk_manager_metadata = new ChunkManager(SpecializedChunk, SmallChunk, MediumChunk);
3010 2960
3011 #ifdef _LP64 2961 #ifdef _LP64
3012 // Set the compressed klass pointer base so that decoding of these pointers works 2962 // Set the compressed klass pointer base so that decoding of these pointers works
3013 // properly when creating the shared archive. 2963 // properly when creating the shared archive.
3014 assert(UseCompressedOops && UseCompressedClassPointers, 2964 assert(UseCompressedOops && UseCompressedClassPointers,
3072 // Arbitrarily set the initial virtual space to a multiple 3022 // Arbitrarily set the initial virtual space to a multiple
3073 // of the boot class loader size. 3023 // of the boot class loader size.
3074 size_t word_size = VIRTUALSPACEMULTIPLIER * first_chunk_word_size(); 3024 size_t word_size = VIRTUALSPACEMULTIPLIER * first_chunk_word_size();
3075 // Initialize the list of virtual spaces. 3025 // Initialize the list of virtual spaces.
3076 _space_list = new VirtualSpaceList(word_size); 3026 _space_list = new VirtualSpaceList(word_size);
3077 } 3027 _chunk_manager_metadata = new ChunkManager(SpecializedChunk, SmallChunk, MediumChunk);
3028 }
3029 }
3030
3031 Metachunk* Metaspace::get_initialization_chunk(MetadataType mdtype,
3032 size_t chunk_word_size,
3033 size_t chunk_bunch) {
3034 // Get a chunk from the chunk freelist
3035 Metachunk* chunk = get_chunk_manager(mdtype)->chunk_freelist_allocate(chunk_word_size);
3036 if (chunk != NULL) {
3037 return chunk;
3038 }
3039
3040 return get_space_list(mdtype)->get_initialization_chunk(chunk_word_size, chunk_bunch);
3078 } 3041 }
3079 3042
3080 void Metaspace::initialize(Mutex* lock, MetaspaceType type) { 3043 void Metaspace::initialize(Mutex* lock, MetaspaceType type) {
3081 3044
3082 assert(space_list() != NULL, 3045 assert(space_list() != NULL,
3083 "Metadata VirtualSpaceList has not been initialized"); 3046 "Metadata VirtualSpaceList has not been initialized");
3084 3047 assert(chunk_manager_metadata() != NULL,
3085 _vsm = new SpaceManager(NonClassType, lock, space_list()); 3048 "Metadata ChunkManager has not been initialized");
3049
3050 _vsm = new SpaceManager(NonClassType, lock);
3086 if (_vsm == NULL) { 3051 if (_vsm == NULL) {
3087 return; 3052 return;
3088 } 3053 }
3089 size_t word_size; 3054 size_t word_size;
3090 size_t class_word_size; 3055 size_t class_word_size;
3091 vsm()->get_initial_chunk_sizes(type, &word_size, &class_word_size); 3056 vsm()->get_initial_chunk_sizes(type, &word_size, &class_word_size);
3092 3057
3093 if (using_class_space()) { 3058 if (using_class_space()) {
3094 assert(class_space_list() != NULL, 3059 assert(class_space_list() != NULL,
3095 "Class VirtualSpaceList has not been initialized"); 3060 "Class VirtualSpaceList has not been initialized");
3061 assert(chunk_manager_class() != NULL,
3062 "Class ChunkManager has not been initialized");
3096 3063
3097 // Allocate SpaceManager for classes. 3064 // Allocate SpaceManager for classes.
3098 _class_vsm = new SpaceManager(ClassType, lock, class_space_list()); 3065 _class_vsm = new SpaceManager(ClassType, lock);
3099 if (_class_vsm == NULL) { 3066 if (_class_vsm == NULL) {
3100 return; 3067 return;
3101 } 3068 }
3102 } 3069 }
3103 3070
3104 MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag); 3071 MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag);
3105 3072
3106 // Allocate chunk for metadata objects 3073 // Allocate chunk for metadata objects
3107 Metachunk* new_chunk = 3074 Metachunk* new_chunk = get_initialization_chunk(NonClassType,
3108 space_list()->get_initialization_chunk(word_size, 3075 word_size,
3109 vsm()->medium_chunk_bunch()); 3076 vsm()->medium_chunk_bunch());
3110 assert(!DumpSharedSpaces || new_chunk != NULL, "should have enough space for both chunks"); 3077 assert(!DumpSharedSpaces || new_chunk != NULL, "should have enough space for both chunks");
3111 if (new_chunk != NULL) { 3078 if (new_chunk != NULL) {
3112 // Add to this manager's list of chunks in use and current_chunk(). 3079 // Add to this manager's list of chunks in use and current_chunk().
3113 vsm()->add_chunk(new_chunk, true); 3080 vsm()->add_chunk(new_chunk, true);
3114 } 3081 }
3115 3082
3116 // Allocate chunk for class metadata objects 3083 // Allocate chunk for class metadata objects
3117 if (using_class_space()) { 3084 if (using_class_space()) {
3118 Metachunk* class_chunk = 3085 Metachunk* class_chunk = get_initialization_chunk(ClassType,
3119 class_space_list()->get_initialization_chunk(class_word_size, 3086 class_word_size,
3120 class_vsm()->medium_chunk_bunch()); 3087 class_vsm()->medium_chunk_bunch());
3121 if (class_chunk != NULL) { 3088 if (class_chunk != NULL) {
3122 class_vsm()->add_chunk(class_chunk, true); 3089 class_vsm()->add_chunk(class_chunk, true);
3123 } 3090 }
3124 } 3091 }
3125 3092
3332 if (last_addr < top) { 3299 if (last_addr < top) {
3333 closure->doit(last_addr, MetaspaceObj::UnknownType, top - last_addr); 3300 closure->doit(last_addr, MetaspaceObj::UnknownType, top - last_addr);
3334 } 3301 }
3335 } 3302 }
3336 3303
3304 void Metaspace::purge(MetadataType mdtype) {
3305 get_space_list(mdtype)->purge(get_chunk_manager(mdtype));
3306 }
3307
3337 void Metaspace::purge() { 3308 void Metaspace::purge() {
3338 MutexLockerEx cl(SpaceManager::expand_lock(), 3309 MutexLockerEx cl(SpaceManager::expand_lock(),
3339 Mutex::_no_safepoint_check_flag); 3310 Mutex::_no_safepoint_check_flag);
3340 space_list()->purge(); 3311 purge(NonClassType);
3341 if (using_class_space()) { 3312 if (using_class_space()) {
3342 class_space_list()->purge(); 3313 purge(ClassType);
3343 } 3314 }
3344 } 3315 }
3345 3316
3346 void Metaspace::print_on(outputStream* out) const { 3317 void Metaspace::print_on(outputStream* out) const {
3347 // Print both class virtual space counts and metaspace. 3318 // Print both class virtual space counts and metaspace.