Mercurial > hg > truffle
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. |