Mercurial > hg > truffle
comparison src/share/vm/memory/metaspace.cpp @ 12873:4e7f99b70d9d
Merge
author | adlertz |
---|---|
date | Wed, 09 Oct 2013 05:03:34 -0700 |
parents | bc918fd1e584 |
children | 85c1ca43713f |
comparison
equal
deleted
inserted
replaced
12872:98692a2d36d7 | 12873:4e7f99b70d9d |
---|---|
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() { |
1140 if (vs_word_size == 0) { | 1093 if (vs_word_size == 0) { |
1141 return false; | 1094 return false; |
1142 } | 1095 } |
1143 // Reserve the space | 1096 // Reserve the space |
1144 size_t vs_byte_size = vs_word_size * BytesPerWord; | 1097 size_t vs_byte_size = vs_word_size * BytesPerWord; |
1145 assert(vs_byte_size % os::vm_page_size() == 0, "Not aligned"); | 1098 assert(vs_byte_size % os::vm_allocation_granularity() == 0, "Not aligned"); |
1146 | 1099 |
1147 // Allocate the meta virtual space and initialize it. | 1100 // Allocate the meta virtual space and initialize it. |
1148 VirtualSpaceNode* new_entry = new VirtualSpaceNode(vs_byte_size); | 1101 VirtualSpaceNode* new_entry = new VirtualSpaceNode(vs_byte_size); |
1149 if (!new_entry->initialize()) { | 1102 if (!new_entry->initialize()) { |
1150 delete new_entry; | 1103 delete new_entry; |
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, |
1219 // Should the capacity of the metaspaces be expanded for | 1165 // Should the capacity of the metaspaces be expanded for |
1220 // this allocation? If it's the virtual space for classes and is | 1166 // this allocation? If it's the virtual space for classes and is |
1221 // being used for CompressedHeaders, don't allocate a new virtualspace. | 1167 // being used for CompressedHeaders, don't allocate a new virtualspace. |
1222 if (can_grow() && MetaspaceGC::should_expand(this, word_size)) { | 1168 if (can_grow() && MetaspaceGC::should_expand(this, word_size)) { |
1223 // Get another virtual space. | 1169 // Get another virtual space. |
1224 size_t grow_vs_words = | 1170 size_t allocation_aligned_expand_words = |
1225 MAX2((size_t)VirtualSpaceSize, aligned_expand_vs_by_words); | 1171 align_size_up(aligned_expand_vs_by_words, os::vm_allocation_granularity() / BytesPerWord); |
1172 size_t grow_vs_words = | |
1173 MAX2((size_t)VirtualSpaceSize, allocation_aligned_expand_words); | |
1226 if (grow_vs(grow_vs_words)) { | 1174 if (grow_vs(grow_vs_words)) { |
1227 // Got it. It's on the list now. Get a chunk from it. | 1175 // Got it. It's on the list now. Get a chunk from it. |
1228 assert(current_virtual_space()->expanded_words() == 0, | 1176 assert(current_virtual_space()->expanded_words() == 0, |
1229 "New virtuals space nodes should not have expanded"); | 1177 "New virtual space nodes should not have expanded"); |
1230 | 1178 |
1231 size_t grow_chunks_by_words_aligned = align_size_up(grow_chunks_by_words, | 1179 size_t grow_chunks_by_words_aligned = align_size_up(grow_chunks_by_words, |
1232 page_size_words); | 1180 page_size_words); |
1233 // We probably want to expand by aligned_expand_vs_by_words here. | 1181 // We probably want to expand by aligned_expand_vs_by_words here. |
1234 expand_by(current_virtual_space(), grow_chunks_by_words_aligned); | 1182 expand_by(current_virtual_space(), grow_chunks_by_words_aligned); |
1340 // for non-class virtual space, compare against virtual spaces that are reserved. | 1288 // for non-class virtual space, compare against virtual spaces that are reserved. |
1341 // For class virtual space, we only compare against the committed space, not | 1289 // For class virtual space, we only compare against the committed space, not |
1342 // reserved space, because this is a larger space prereserved for compressed | 1290 // reserved space, because this is a larger space prereserved for compressed |
1343 // class pointers. | 1291 // class pointers. |
1344 if (!FLAG_IS_DEFAULT(MaxMetaspaceSize)) { | 1292 if (!FLAG_IS_DEFAULT(MaxMetaspaceSize)) { |
1345 size_t real_allocated = Metaspace::space_list()->reserved_words() + | 1293 size_t nonclass_allocated = MetaspaceAux::reserved_bytes(Metaspace::NonClassType); |
1346 MetaspaceAux::allocated_capacity_bytes(Metaspace::ClassType); | 1294 size_t class_allocated = MetaspaceAux::allocated_capacity_bytes(Metaspace::ClassType); |
1295 size_t real_allocated = nonclass_allocated + class_allocated; | |
1347 if (real_allocated >= MaxMetaspaceSize) { | 1296 if (real_allocated >= MaxMetaspaceSize) { |
1348 return false; | 1297 return false; |
1349 } | 1298 } |
1350 } | 1299 } |
1351 | 1300 |
1534 for (uint i = 0; i < metadata_deallocate_a_lock_chunk; i++) { | 1483 for (uint i = 0; i < metadata_deallocate_a_lock_chunk; i++) { |
1535 Metachunk* dummy_chunk = vsl->current_virtual_space()->take_from_committed(chunk_word_size); | 1484 Metachunk* dummy_chunk = vsl->current_virtual_space()->take_from_committed(chunk_word_size); |
1536 if (dummy_chunk == NULL) { | 1485 if (dummy_chunk == NULL) { |
1537 break; | 1486 break; |
1538 } | 1487 } |
1539 vsl->chunk_manager()->chunk_freelist_deallocate(dummy_chunk); | 1488 sm->chunk_manager()->chunk_freelist_deallocate(dummy_chunk); |
1540 | 1489 |
1541 if (TraceMetadataChunkAllocation && Verbose) { | 1490 if (TraceMetadataChunkAllocation && Verbose) { |
1542 gclog_or_tty->print("Metadebug::deallocate_chunk_a_lot: %d) ", | 1491 gclog_or_tty->print("Metadebug::deallocate_chunk_a_lot: %d) ", |
1543 sm->sum_count_in_chunks_in_use()); | 1492 sm->sum_count_in_chunks_in_use()); |
1544 dummy_chunk->print_on(gclog_or_tty); | 1493 dummy_chunk->print_on(gclog_or_tty); |
1545 gclog_or_tty->print_cr(" Free chunks total %d count %d", | 1494 gclog_or_tty->print_cr(" Free chunks total %d count %d", |
1546 vsl->chunk_manager()->free_chunks_total_words(), | 1495 sm->chunk_manager()->free_chunks_total_words(), |
1547 vsl->chunk_manager()->free_chunks_count()); | 1496 sm->chunk_manager()->free_chunks_count()); |
1548 } | 1497 } |
1549 } | 1498 } |
1550 } else { | 1499 } else { |
1551 Metadebug::inc_deallocate_chunk_a_lot_count(); | 1500 Metadebug::inc_deallocate_chunk_a_lot_count(); |
1552 } | 1501 } |
1794 #ifdef ASSERT | 1743 #ifdef ASSERT |
1795 // Chunk is no longer on any freelist. Setting to false make container_count_slow() | 1744 // Chunk is no longer on any freelist. Setting to false make container_count_slow() |
1796 // work. | 1745 // work. |
1797 chunk->set_is_free(false); | 1746 chunk->set_is_free(false); |
1798 #endif | 1747 #endif |
1748 chunk->container()->inc_container_count(); | |
1749 | |
1799 slow_locked_verify(); | 1750 slow_locked_verify(); |
1800 return chunk; | 1751 return chunk; |
1801 } | 1752 } |
1802 | 1753 |
1803 Metachunk* ChunkManager::chunk_freelist_allocate(size_t word_size) { | 1754 Metachunk* ChunkManager::chunk_freelist_allocate(size_t word_size) { |
1828 } | 1779 } |
1829 | 1780 |
1830 return chunk; | 1781 return chunk; |
1831 } | 1782 } |
1832 | 1783 |
1833 void ChunkManager::print_on(outputStream* out) { | 1784 void ChunkManager::print_on(outputStream* out) const { |
1834 if (PrintFLSStatistics != 0) { | 1785 if (PrintFLSStatistics != 0) { |
1835 humongous_dictionary()->report_statistics(); | 1786 const_cast<ChunkManager *>(this)->humongous_dictionary()->report_statistics(); |
1836 } | 1787 } |
1837 } | 1788 } |
1838 | 1789 |
1839 // SpaceManager methods | 1790 // SpaceManager methods |
1840 | 1791 |
1977 } else { | 1928 } else { |
1978 st->print_cr(""); | 1929 st->print_cr(""); |
1979 } | 1930 } |
1980 } | 1931 } |
1981 | 1932 |
1982 vs_list()->chunk_manager()->locked_print_free_chunks(st); | 1933 chunk_manager()->locked_print_free_chunks(st); |
1983 vs_list()->chunk_manager()->locked_print_sum_free_chunks(st); | 1934 chunk_manager()->locked_print_sum_free_chunks(st); |
1984 } | 1935 } |
1985 | 1936 |
1986 size_t SpaceManager::calc_chunk_size(size_t word_size) { | 1937 size_t SpaceManager::calc_chunk_size(size_t word_size) { |
1987 | 1938 |
1988 // Decide between a small chunk and a medium chunk. Up to | 1939 // Decide between a small chunk and a medium chunk. Up to |
2082 block_freelists()->total_size()); | 2033 block_freelists()->total_size()); |
2083 } | 2034 } |
2084 } | 2035 } |
2085 | 2036 |
2086 SpaceManager::SpaceManager(Metaspace::MetadataType mdtype, | 2037 SpaceManager::SpaceManager(Metaspace::MetadataType mdtype, |
2087 Mutex* lock, | 2038 Mutex* lock) : |
2088 VirtualSpaceList* vs_list) : | |
2089 _vs_list(vs_list), | |
2090 _mdtype(mdtype), | 2039 _mdtype(mdtype), |
2091 _allocated_blocks_words(0), | 2040 _allocated_blocks_words(0), |
2092 _allocated_chunks_words(0), | 2041 _allocated_chunks_words(0), |
2093 _allocated_chunks_count(0), | 2042 _allocated_chunks_count(0), |
2094 _lock(lock) | 2043 _lock(lock) |
2170 sum_capacity_in_chunks_in_use(), allocated_chunks_words())); | 2119 sum_capacity_in_chunks_in_use(), allocated_chunks_words())); |
2171 | 2120 |
2172 MutexLockerEx fcl(SpaceManager::expand_lock(), | 2121 MutexLockerEx fcl(SpaceManager::expand_lock(), |
2173 Mutex::_no_safepoint_check_flag); | 2122 Mutex::_no_safepoint_check_flag); |
2174 | 2123 |
2175 ChunkManager* chunk_manager = vs_list()->chunk_manager(); | 2124 chunk_manager()->slow_locked_verify(); |
2176 | |
2177 chunk_manager->slow_locked_verify(); | |
2178 | 2125 |
2179 dec_total_from_size_metrics(); | 2126 dec_total_from_size_metrics(); |
2180 | 2127 |
2181 if (TraceMetadataChunkAllocation && Verbose) { | 2128 if (TraceMetadataChunkAllocation && Verbose) { |
2182 gclog_or_tty->print_cr("~SpaceManager(): " PTR_FORMAT, this); | 2129 gclog_or_tty->print_cr("~SpaceManager(): " PTR_FORMAT, this); |
2186 // Do not mangle freed Metachunks. The chunk size inside Metachunks | 2133 // Do not mangle freed Metachunks. The chunk size inside Metachunks |
2187 // is during the freeing of a VirtualSpaceNodes. | 2134 // is during the freeing of a VirtualSpaceNodes. |
2188 | 2135 |
2189 // Have to update before the chunks_in_use lists are emptied | 2136 // Have to update before the chunks_in_use lists are emptied |
2190 // below. | 2137 // below. |
2191 chunk_manager->inc_free_chunks_total(allocated_chunks_words(), | 2138 chunk_manager()->inc_free_chunks_total(allocated_chunks_words(), |
2192 sum_count_in_chunks_in_use()); | 2139 sum_count_in_chunks_in_use()); |
2193 | 2140 |
2194 // Add all the chunks in use by this space manager | 2141 // Add all the chunks in use by this space manager |
2195 // to the global list of free chunks. | 2142 // to the global list of free chunks. |
2196 | 2143 |
2197 // Follow each list of chunks-in-use and add them to the | 2144 // Follow each list of chunks-in-use and add them to the |
2202 gclog_or_tty->print_cr("returned %d %s chunks to freelist", | 2149 gclog_or_tty->print_cr("returned %d %s chunks to freelist", |
2203 sum_count_in_chunks_in_use(i), | 2150 sum_count_in_chunks_in_use(i), |
2204 chunk_size_name(i)); | 2151 chunk_size_name(i)); |
2205 } | 2152 } |
2206 Metachunk* chunks = chunks_in_use(i); | 2153 Metachunk* chunks = chunks_in_use(i); |
2207 chunk_manager->return_chunks(i, chunks); | 2154 chunk_manager()->return_chunks(i, chunks); |
2208 set_chunks_in_use(i, NULL); | 2155 set_chunks_in_use(i, NULL); |
2209 if (TraceMetadataChunkAllocation && Verbose) { | 2156 if (TraceMetadataChunkAllocation && Verbose) { |
2210 gclog_or_tty->print_cr("updated freelist count %d %s", | 2157 gclog_or_tty->print_cr("updated freelist count %d %s", |
2211 chunk_manager->free_chunks(i)->count(), | 2158 chunk_manager()->free_chunks(i)->count(), |
2212 chunk_size_name(i)); | 2159 chunk_size_name(i)); |
2213 } | 2160 } |
2214 assert(i != HumongousIndex, "Humongous chunks are handled explicitly later"); | 2161 assert(i != HumongousIndex, "Humongous chunks are handled explicitly later"); |
2215 } | 2162 } |
2216 | 2163 |
2243 err_msg("Humongous chunk size is wrong: word size " SIZE_FORMAT | 2190 err_msg("Humongous chunk size is wrong: word size " SIZE_FORMAT |
2244 " granularity %d", | 2191 " granularity %d", |
2245 humongous_chunks->word_size(), HumongousChunkGranularity)); | 2192 humongous_chunks->word_size(), HumongousChunkGranularity)); |
2246 Metachunk* next_humongous_chunks = humongous_chunks->next(); | 2193 Metachunk* next_humongous_chunks = humongous_chunks->next(); |
2247 humongous_chunks->container()->dec_container_count(); | 2194 humongous_chunks->container()->dec_container_count(); |
2248 chunk_manager->humongous_dictionary()->return_chunk(humongous_chunks); | 2195 chunk_manager()->humongous_dictionary()->return_chunk(humongous_chunks); |
2249 humongous_chunks = next_humongous_chunks; | 2196 humongous_chunks = next_humongous_chunks; |
2250 } | 2197 } |
2251 if (TraceMetadataChunkAllocation && Verbose) { | 2198 if (TraceMetadataChunkAllocation && Verbose) { |
2252 gclog_or_tty->print_cr(""); | 2199 gclog_or_tty->print_cr(""); |
2253 gclog_or_tty->print_cr("updated dictionary count %d %s", | 2200 gclog_or_tty->print_cr("updated dictionary count %d %s", |
2254 chunk_manager->humongous_dictionary()->total_count(), | 2201 chunk_manager()->humongous_dictionary()->total_count(), |
2255 chunk_size_name(HumongousIndex)); | 2202 chunk_size_name(HumongousIndex)); |
2256 } | 2203 } |
2257 chunk_manager->slow_locked_verify(); | 2204 chunk_manager()->slow_locked_verify(); |
2258 } | 2205 } |
2259 | 2206 |
2260 const char* SpaceManager::chunk_size_name(ChunkIndex index) const { | 2207 const char* SpaceManager::chunk_size_name(ChunkIndex index) const { |
2261 switch (index) { | 2208 switch (index) { |
2262 case SpecializedIndex: | 2209 case SpecializedIndex: |
2341 assert(new_chunk->is_empty(), "Not ready for reuse"); | 2288 assert(new_chunk->is_empty(), "Not ready for reuse"); |
2342 if (TraceMetadataChunkAllocation && Verbose) { | 2289 if (TraceMetadataChunkAllocation && Verbose) { |
2343 gclog_or_tty->print("SpaceManager::add_chunk: %d) ", | 2290 gclog_or_tty->print("SpaceManager::add_chunk: %d) ", |
2344 sum_count_in_chunks_in_use()); | 2291 sum_count_in_chunks_in_use()); |
2345 new_chunk->print_on(gclog_or_tty); | 2292 new_chunk->print_on(gclog_or_tty); |
2346 if (vs_list() != NULL) { | 2293 chunk_manager()->locked_print_free_chunks(gclog_or_tty); |
2347 vs_list()->chunk_manager()->locked_print_free_chunks(gclog_or_tty); | |
2348 } | |
2349 } | 2294 } |
2350 } | 2295 } |
2351 | 2296 |
2352 void SpaceManager::retire_current_chunk() { | 2297 void SpaceManager::retire_current_chunk() { |
2353 if (current_chunk() != NULL) { | 2298 if (current_chunk() != NULL) { |
2359 } | 2304 } |
2360 } | 2305 } |
2361 | 2306 |
2362 Metachunk* SpaceManager::get_new_chunk(size_t word_size, | 2307 Metachunk* SpaceManager::get_new_chunk(size_t word_size, |
2363 size_t grow_chunks_by_words) { | 2308 size_t grow_chunks_by_words) { |
2364 | 2309 // Get a chunk from the chunk freelist |
2365 Metachunk* next = vs_list()->get_new_chunk(word_size, | 2310 Metachunk* next = chunk_manager()->chunk_freelist_allocate(grow_chunks_by_words); |
2366 grow_chunks_by_words, | 2311 |
2367 medium_chunk_bunch()); | 2312 if (next == NULL) { |
2313 next = vs_list()->get_new_chunk(word_size, | |
2314 grow_chunks_by_words, | |
2315 medium_chunk_bunch()); | |
2316 } | |
2368 | 2317 |
2369 if (TraceMetadataHumongousAllocation && next != NULL && | 2318 if (TraceMetadataHumongousAllocation && next != NULL && |
2370 SpaceManager::is_humongous(next->word_size())) { | 2319 SpaceManager::is_humongous(next->word_size())) { |
2371 gclog_or_tty->print_cr(" new humongous chunk word size " | 2320 gclog_or_tty->print_cr(" new humongous chunk word size " |
2372 PTR_FORMAT, next->word_size()); | 2321 PTR_FORMAT, next->word_size()); |
2642 } | 2591 } |
2643 | 2592 |
2644 size_t MetaspaceAux::min_chunk_size_words() { return Metaspace::first_chunk_word_size(); } | 2593 size_t MetaspaceAux::min_chunk_size_words() { return Metaspace::first_chunk_word_size(); } |
2645 | 2594 |
2646 size_t MetaspaceAux::free_chunks_total_words(Metaspace::MetadataType mdtype) { | 2595 size_t MetaspaceAux::free_chunks_total_words(Metaspace::MetadataType mdtype) { |
2647 VirtualSpaceList* list = Metaspace::get_space_list(mdtype); | 2596 ChunkManager* chunk_manager = Metaspace::get_chunk_manager(mdtype); |
2648 if (list == NULL) { | 2597 if (chunk_manager == NULL) { |
2649 return 0; | 2598 return 0; |
2650 } | 2599 } |
2651 ChunkManager* chunk = list->chunk_manager(); | 2600 chunk_manager->slow_verify(); |
2652 chunk->slow_verify(); | 2601 return chunk_manager->free_chunks_total_words(); |
2653 return chunk->free_chunks_total_words(); | |
2654 } | 2602 } |
2655 | 2603 |
2656 size_t MetaspaceAux::free_chunks_total_bytes(Metaspace::MetadataType mdtype) { | 2604 size_t MetaspaceAux::free_chunks_total_bytes(Metaspace::MetadataType mdtype) { |
2657 return free_chunks_total_words(mdtype) * BytesPerWord; | 2605 return free_chunks_total_words(mdtype) * BytesPerWord; |
2658 } | 2606 } |
2799 out->print("class space: "); print_on(out, Metaspace::ClassType); | 2747 out->print("class space: "); print_on(out, Metaspace::ClassType); |
2800 print_waste(out); | 2748 print_waste(out); |
2801 } | 2749 } |
2802 | 2750 |
2803 void MetaspaceAux::verify_free_chunks() { | 2751 void MetaspaceAux::verify_free_chunks() { |
2804 Metaspace::space_list()->chunk_manager()->verify(); | 2752 Metaspace::chunk_manager_metadata()->verify(); |
2805 if (Metaspace::using_class_space()) { | 2753 if (Metaspace::using_class_space()) { |
2806 Metaspace::class_space_list()->chunk_manager()->verify(); | 2754 Metaspace::chunk_manager_class()->verify(); |
2807 } | 2755 } |
2808 } | 2756 } |
2809 | 2757 |
2810 void MetaspaceAux::verify_capacity() { | 2758 void MetaspaceAux::verify_capacity() { |
2811 #ifdef ASSERT | 2759 #ifdef ASSERT |
2872 } | 2820 } |
2873 | 2821 |
2874 VirtualSpaceList* Metaspace::_space_list = NULL; | 2822 VirtualSpaceList* Metaspace::_space_list = NULL; |
2875 VirtualSpaceList* Metaspace::_class_space_list = NULL; | 2823 VirtualSpaceList* Metaspace::_class_space_list = NULL; |
2876 | 2824 |
2825 ChunkManager* Metaspace::_chunk_manager_metadata = NULL; | |
2826 ChunkManager* Metaspace::_chunk_manager_class = NULL; | |
2827 | |
2877 #define VIRTUALSPACEMULTIPLIER 2 | 2828 #define VIRTUALSPACEMULTIPLIER 2 |
2878 | 2829 |
2879 #ifdef _LP64 | 2830 #ifdef _LP64 |
2880 void Metaspace::set_narrow_klass_base_and_shift(address metaspace_base, address cds_base) { | 2831 void Metaspace::set_narrow_klass_base_and_shift(address metaspace_base, address cds_base) { |
2881 // Figure out the narrow_klass_base and the narrow_klass_shift. The | 2832 // Figure out the narrow_klass_base and the narrow_klass_shift. The |
2979 // The reserved space size may be bigger because of alignment, esp with UseLargePages | 2930 // The reserved space size may be bigger because of alignment, esp with UseLargePages |
2980 assert(rs.size() >= CompressedClassSpaceSize, | 2931 assert(rs.size() >= CompressedClassSpaceSize, |
2981 err_msg(SIZE_FORMAT " != " UINTX_FORMAT, rs.size(), CompressedClassSpaceSize)); | 2932 err_msg(SIZE_FORMAT " != " UINTX_FORMAT, rs.size(), CompressedClassSpaceSize)); |
2982 assert(using_class_space(), "Must be using class space"); | 2933 assert(using_class_space(), "Must be using class space"); |
2983 _class_space_list = new VirtualSpaceList(rs); | 2934 _class_space_list = new VirtualSpaceList(rs); |
2935 _chunk_manager_class = new ChunkManager(SpecializedChunk, ClassSmallChunk, ClassMediumChunk); | |
2984 } | 2936 } |
2985 | 2937 |
2986 #endif | 2938 #endif |
2987 | 2939 |
2988 void Metaspace::global_initialize() { | 2940 void Metaspace::global_initialize() { |
3004 // Initialize with the sum of the shared space sizes. The read-only | 2956 // Initialize with the sum of the shared space sizes. The read-only |
3005 // and read write metaspace chunks will be allocated out of this and the | 2957 // and read write metaspace chunks will be allocated out of this and the |
3006 // remainder is the misc code and data chunks. | 2958 // remainder is the misc code and data chunks. |
3007 cds_total = FileMapInfo::shared_spaces_size(); | 2959 cds_total = FileMapInfo::shared_spaces_size(); |
3008 _space_list = new VirtualSpaceList(cds_total/wordSize); | 2960 _space_list = new VirtualSpaceList(cds_total/wordSize); |
2961 _chunk_manager_metadata = new ChunkManager(SpecializedChunk, SmallChunk, MediumChunk); | |
3009 | 2962 |
3010 #ifdef _LP64 | 2963 #ifdef _LP64 |
3011 // Set the compressed klass pointer base so that decoding of these pointers works | 2964 // Set the compressed klass pointer base so that decoding of these pointers works |
3012 // properly when creating the shared archive. | 2965 // properly when creating the shared archive. |
3013 assert(UseCompressedOops && UseCompressedClassPointers, | 2966 assert(UseCompressedOops && UseCompressedClassPointers, |
3071 // Arbitrarily set the initial virtual space to a multiple | 3024 // Arbitrarily set the initial virtual space to a multiple |
3072 // of the boot class loader size. | 3025 // of the boot class loader size. |
3073 size_t word_size = VIRTUALSPACEMULTIPLIER * first_chunk_word_size(); | 3026 size_t word_size = VIRTUALSPACEMULTIPLIER * first_chunk_word_size(); |
3074 // Initialize the list of virtual spaces. | 3027 // Initialize the list of virtual spaces. |
3075 _space_list = new VirtualSpaceList(word_size); | 3028 _space_list = new VirtualSpaceList(word_size); |
3076 } | 3029 _chunk_manager_metadata = new ChunkManager(SpecializedChunk, SmallChunk, MediumChunk); |
3030 } | |
3031 } | |
3032 | |
3033 Metachunk* Metaspace::get_initialization_chunk(MetadataType mdtype, | |
3034 size_t chunk_word_size, | |
3035 size_t chunk_bunch) { | |
3036 // Get a chunk from the chunk freelist | |
3037 Metachunk* chunk = get_chunk_manager(mdtype)->chunk_freelist_allocate(chunk_word_size); | |
3038 if (chunk != NULL) { | |
3039 return chunk; | |
3040 } | |
3041 | |
3042 return get_space_list(mdtype)->get_initialization_chunk(chunk_word_size, chunk_bunch); | |
3077 } | 3043 } |
3078 | 3044 |
3079 void Metaspace::initialize(Mutex* lock, MetaspaceType type) { | 3045 void Metaspace::initialize(Mutex* lock, MetaspaceType type) { |
3080 | 3046 |
3081 assert(space_list() != NULL, | 3047 assert(space_list() != NULL, |
3082 "Metadata VirtualSpaceList has not been initialized"); | 3048 "Metadata VirtualSpaceList has not been initialized"); |
3083 | 3049 assert(chunk_manager_metadata() != NULL, |
3084 _vsm = new SpaceManager(NonClassType, lock, space_list()); | 3050 "Metadata ChunkManager has not been initialized"); |
3051 | |
3052 _vsm = new SpaceManager(NonClassType, lock); | |
3085 if (_vsm == NULL) { | 3053 if (_vsm == NULL) { |
3086 return; | 3054 return; |
3087 } | 3055 } |
3088 size_t word_size; | 3056 size_t word_size; |
3089 size_t class_word_size; | 3057 size_t class_word_size; |
3090 vsm()->get_initial_chunk_sizes(type, &word_size, &class_word_size); | 3058 vsm()->get_initial_chunk_sizes(type, &word_size, &class_word_size); |
3091 | 3059 |
3092 if (using_class_space()) { | 3060 if (using_class_space()) { |
3093 assert(class_space_list() != NULL, | 3061 assert(class_space_list() != NULL, |
3094 "Class VirtualSpaceList has not been initialized"); | 3062 "Class VirtualSpaceList has not been initialized"); |
3063 assert(chunk_manager_class() != NULL, | |
3064 "Class ChunkManager has not been initialized"); | |
3095 | 3065 |
3096 // Allocate SpaceManager for classes. | 3066 // Allocate SpaceManager for classes. |
3097 _class_vsm = new SpaceManager(ClassType, lock, class_space_list()); | 3067 _class_vsm = new SpaceManager(ClassType, lock); |
3098 if (_class_vsm == NULL) { | 3068 if (_class_vsm == NULL) { |
3099 return; | 3069 return; |
3100 } | 3070 } |
3101 } | 3071 } |
3102 | 3072 |
3103 MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag); | 3073 MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag); |
3104 | 3074 |
3105 // Allocate chunk for metadata objects | 3075 // Allocate chunk for metadata objects |
3106 Metachunk* new_chunk = | 3076 Metachunk* new_chunk = get_initialization_chunk(NonClassType, |
3107 space_list()->get_initialization_chunk(word_size, | 3077 word_size, |
3108 vsm()->medium_chunk_bunch()); | 3078 vsm()->medium_chunk_bunch()); |
3109 assert(!DumpSharedSpaces || new_chunk != NULL, "should have enough space for both chunks"); | 3079 assert(!DumpSharedSpaces || new_chunk != NULL, "should have enough space for both chunks"); |
3110 if (new_chunk != NULL) { | 3080 if (new_chunk != NULL) { |
3111 // Add to this manager's list of chunks in use and current_chunk(). | 3081 // Add to this manager's list of chunks in use and current_chunk(). |
3112 vsm()->add_chunk(new_chunk, true); | 3082 vsm()->add_chunk(new_chunk, true); |
3113 } | 3083 } |
3114 | 3084 |
3115 // Allocate chunk for class metadata objects | 3085 // Allocate chunk for class metadata objects |
3116 if (using_class_space()) { | 3086 if (using_class_space()) { |
3117 Metachunk* class_chunk = | 3087 Metachunk* class_chunk = get_initialization_chunk(ClassType, |
3118 class_space_list()->get_initialization_chunk(class_word_size, | 3088 class_word_size, |
3119 class_vsm()->medium_chunk_bunch()); | 3089 class_vsm()->medium_chunk_bunch()); |
3120 if (class_chunk != NULL) { | 3090 if (class_chunk != NULL) { |
3121 class_vsm()->add_chunk(class_chunk, true); | 3091 class_vsm()->add_chunk(class_chunk, true); |
3122 } | 3092 } |
3123 } | 3093 } |
3124 | 3094 |
3132 } | 3102 } |
3133 | 3103 |
3134 MetaWord* Metaspace::allocate(size_t word_size, MetadataType mdtype) { | 3104 MetaWord* Metaspace::allocate(size_t word_size, MetadataType mdtype) { |
3135 // DumpSharedSpaces doesn't use class metadata area (yet) | 3105 // DumpSharedSpaces doesn't use class metadata area (yet) |
3136 // Also, don't use class_vsm() unless UseCompressedClassPointers is true. | 3106 // Also, don't use class_vsm() unless UseCompressedClassPointers is true. |
3137 if (mdtype == ClassType && using_class_space()) { | 3107 if (is_class_space_allocation(mdtype)) { |
3138 return class_vsm()->allocate(word_size); | 3108 return class_vsm()->allocate(word_size); |
3139 } else { | 3109 } else { |
3140 return vsm()->allocate(word_size); | 3110 return vsm()->allocate(word_size); |
3141 } | 3111 } |
3142 } | 3112 } |
3280 SIZE_FORMAT, word_size); | 3250 SIZE_FORMAT, word_size); |
3281 if (loader_data->metaspace_or_null() != NULL) loader_data->dump(gclog_or_tty); | 3251 if (loader_data->metaspace_or_null() != NULL) loader_data->dump(gclog_or_tty); |
3282 MetaspaceAux::dump(gclog_or_tty); | 3252 MetaspaceAux::dump(gclog_or_tty); |
3283 } | 3253 } |
3284 // -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError support | 3254 // -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError support |
3285 const char* space_string = (mdtype == ClassType) ? "Compressed class space" : | 3255 const char* space_string = is_class_space_allocation(mdtype) ? "Compressed class space" : |
3286 "Metadata space"; | 3256 "Metadata space"; |
3287 report_java_out_of_memory(space_string); | 3257 report_java_out_of_memory(space_string); |
3288 | 3258 |
3289 if (JvmtiExport::should_post_resource_exhausted()) { | 3259 if (JvmtiExport::should_post_resource_exhausted()) { |
3290 JvmtiExport::post_resource_exhausted( | 3260 JvmtiExport::post_resource_exhausted( |
3291 JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR, | 3261 JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR, |
3292 space_string); | 3262 space_string); |
3293 } | 3263 } |
3294 if (mdtype == ClassType) { | 3264 if (is_class_space_allocation(mdtype)) { |
3295 THROW_OOP_0(Universe::out_of_memory_error_class_metaspace()); | 3265 THROW_OOP_0(Universe::out_of_memory_error_class_metaspace()); |
3296 } else { | 3266 } else { |
3297 THROW_OOP_0(Universe::out_of_memory_error_metaspace()); | 3267 THROW_OOP_0(Universe::out_of_memory_error_metaspace()); |
3298 } | 3268 } |
3299 } | 3269 } |
3331 if (last_addr < top) { | 3301 if (last_addr < top) { |
3332 closure->doit(last_addr, MetaspaceObj::UnknownType, top - last_addr); | 3302 closure->doit(last_addr, MetaspaceObj::UnknownType, top - last_addr); |
3333 } | 3303 } |
3334 } | 3304 } |
3335 | 3305 |
3306 void Metaspace::purge(MetadataType mdtype) { | |
3307 get_space_list(mdtype)->purge(get_chunk_manager(mdtype)); | |
3308 } | |
3309 | |
3336 void Metaspace::purge() { | 3310 void Metaspace::purge() { |
3337 MutexLockerEx cl(SpaceManager::expand_lock(), | 3311 MutexLockerEx cl(SpaceManager::expand_lock(), |
3338 Mutex::_no_safepoint_check_flag); | 3312 Mutex::_no_safepoint_check_flag); |
3339 space_list()->purge(); | 3313 purge(NonClassType); |
3340 if (using_class_space()) { | 3314 if (using_class_space()) { |
3341 class_space_list()->purge(); | 3315 purge(ClassType); |
3342 } | 3316 } |
3343 } | 3317 } |
3344 | 3318 |
3345 void Metaspace::print_on(outputStream* out) const { | 3319 void Metaspace::print_on(outputStream* out) const { |
3346 // Print both class virtual space counts and metaspace. | 3320 // Print both class virtual space counts and metaspace. |
3383 | 3357 |
3384 /////////////// Unit tests /////////////// | 3358 /////////////// Unit tests /////////////// |
3385 | 3359 |
3386 #ifndef PRODUCT | 3360 #ifndef PRODUCT |
3387 | 3361 |
3388 class MetaspaceAuxTest : AllStatic { | 3362 class TestMetaspaceAuxTest : AllStatic { |
3389 public: | 3363 public: |
3390 static void test_reserved() { | 3364 static void test_reserved() { |
3391 size_t reserved = MetaspaceAux::reserved_bytes(); | 3365 size_t reserved = MetaspaceAux::reserved_bytes(); |
3392 | 3366 |
3393 assert(reserved > 0, "assert"); | 3367 assert(reserved > 0, "assert"); |
3423 assert(committed_class > 0, "assert"); | 3397 assert(committed_class > 0, "assert"); |
3424 assert(committed_class < committed, "assert"); | 3398 assert(committed_class < committed, "assert"); |
3425 } | 3399 } |
3426 } | 3400 } |
3427 | 3401 |
3402 static void test_virtual_space_list_large_chunk() { | |
3403 VirtualSpaceList* vs_list = new VirtualSpaceList(os::vm_allocation_granularity()); | |
3404 MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag); | |
3405 // A size larger than VirtualSpaceSize (256k) and add one page to make it _not_ be | |
3406 // vm_allocation_granularity aligned on Windows. | |
3407 size_t large_size = (size_t)(2*256*K + (os::vm_page_size()/BytesPerWord)); | |
3408 large_size += (os::vm_page_size()/BytesPerWord); | |
3409 vs_list->get_new_chunk(large_size, large_size, 0); | |
3410 } | |
3411 | |
3428 static void test() { | 3412 static void test() { |
3429 test_reserved(); | 3413 test_reserved(); |
3430 test_committed(); | 3414 test_committed(); |
3415 test_virtual_space_list_large_chunk(); | |
3431 } | 3416 } |
3432 }; | 3417 }; |
3433 | 3418 |
3434 void MetaspaceAux_test() { | 3419 void TestMetaspaceAux_test() { |
3435 MetaspaceAuxTest::test(); | 3420 TestMetaspaceAuxTest::test(); |
3436 } | 3421 } |
3437 | 3422 |
3438 #endif | 3423 #endif |