Mercurial > hg > graal-jvmci-8
comparison src/share/vm/memory/metaspace.cpp @ 10175:c23dbf0e8ab7
8011268: NPG: Free unused VirtualSpaceNodes
Reviewed-by: mgerdin, coleenp, johnc
author | jmasa |
---|---|
date | Fri, 01 Mar 2013 10:19:29 -0800 |
parents | df254344edf1 |
children | 868d87ed63c8 |
comparison
equal
deleted
inserted
replaced
10103:07a4efc5ed14 | 10175:c23dbf0e8ab7 |
---|---|
110 // count that includes all three | 110 // count that includes all three |
111 | 111 |
112 class ChunkManager VALUE_OBJ_CLASS_SPEC { | 112 class ChunkManager VALUE_OBJ_CLASS_SPEC { |
113 | 113 |
114 // Free list of chunks of different sizes. | 114 // Free list of chunks of different sizes. |
115 // SpecializedChunk | |
115 // SmallChunk | 116 // SmallChunk |
116 // MediumChunk | 117 // MediumChunk |
117 // HumongousChunk | 118 // HumongousChunk |
118 ChunkList _free_chunks[NumberOfFreeLists]; | 119 ChunkList _free_chunks[NumberOfFreeLists]; |
119 | 120 |
163 | 164 |
164 // Map a size to a list index assuming that there are lists | 165 // Map a size to a list index assuming that there are lists |
165 // for special, small, medium, and humongous chunks. | 166 // for special, small, medium, and humongous chunks. |
166 static ChunkIndex list_index(size_t size); | 167 static ChunkIndex list_index(size_t size); |
167 | 168 |
169 // Remove the chunk from its freelist. It is | |
170 // expected to be on one of the _free_chunks[] lists. | |
171 void remove_chunk(Metachunk* chunk); | |
172 | |
168 // Add the simple linked list of chunks to the freelist of chunks | 173 // Add the simple linked list of chunks to the freelist of chunks |
169 // of type index. | 174 // of type index. |
170 void return_chunks(ChunkIndex index, Metachunk* chunks); | 175 void return_chunks(ChunkIndex index, Metachunk* chunks); |
171 | 176 |
172 // Total of the space in the free chunks list | 177 // Total of the space in the free chunks list |
253 // total in the VirtualSpace | 258 // total in the VirtualSpace |
254 MemRegion _reserved; | 259 MemRegion _reserved; |
255 ReservedSpace _rs; | 260 ReservedSpace _rs; |
256 VirtualSpace _virtual_space; | 261 VirtualSpace _virtual_space; |
257 MetaWord* _top; | 262 MetaWord* _top; |
263 // count of chunks contained in this VirtualSpace | |
264 uintx _container_count; | |
258 | 265 |
259 // Convenience functions for logical bottom and end | 266 // Convenience functions for logical bottom and end |
260 MetaWord* bottom() const { return (MetaWord*) _virtual_space.low(); } | 267 MetaWord* bottom() const { return (MetaWord*) _virtual_space.low(); } |
261 MetaWord* end() const { return (MetaWord*) _virtual_space.high(); } | 268 MetaWord* end() const { return (MetaWord*) _virtual_space.high(); } |
262 | 269 |
263 // Convenience functions to access the _virtual_space | 270 // Convenience functions to access the _virtual_space |
264 char* low() const { return virtual_space()->low(); } | 271 char* low() const { return virtual_space()->low(); } |
265 char* high() const { return virtual_space()->high(); } | 272 char* high() const { return virtual_space()->high(); } |
266 | 273 |
274 // The first Metachunk will be allocated at the bottom of the | |
275 // VirtualSpace | |
276 Metachunk* first_chunk() { return (Metachunk*) bottom(); } | |
277 | |
278 void inc_container_count(); | |
279 #ifdef ASSERT | |
280 uint container_count_slow(); | |
281 #endif | |
282 | |
267 public: | 283 public: |
268 | 284 |
269 VirtualSpaceNode(size_t byte_size); | 285 VirtualSpaceNode(size_t byte_size); |
270 VirtualSpaceNode(ReservedSpace rs) : _top(NULL), _next(NULL), _rs(rs) {} | 286 VirtualSpaceNode(ReservedSpace rs) : _top(NULL), _next(NULL), _rs(rs), _container_count(0) {} |
271 ~VirtualSpaceNode(); | 287 ~VirtualSpaceNode(); |
272 | 288 |
273 // address of next available space in _virtual_space; | 289 // address of next available space in _virtual_space; |
274 // Accessors | 290 // Accessors |
275 VirtualSpaceNode* next() { return _next; } | 291 VirtualSpaceNode* next() { return _next; } |
286 bool is_available(size_t word_size) { return _top + word_size <= end(); } | 302 bool is_available(size_t word_size) { return _top + word_size <= end(); } |
287 | 303 |
288 MetaWord* top() const { return _top; } | 304 MetaWord* top() const { return _top; } |
289 void inc_top(size_t word_size) { _top += word_size; } | 305 void inc_top(size_t word_size) { _top += word_size; } |
290 | 306 |
307 uintx container_count() { return _container_count; } | |
308 void dec_container_count(); | |
309 #ifdef ASSERT | |
310 void verify_container_count(); | |
311 #endif | |
312 | |
291 // used and capacity in this single entry in the list | 313 // used and capacity in this single entry in the list |
292 size_t used_words_in_vs() const; | 314 size_t used_words_in_vs() const; |
293 size_t capacity_words_in_vs() const; | 315 size_t capacity_words_in_vs() const; |
294 | 316 |
295 bool initialize(); | 317 bool initialize(); |
303 | 325 |
304 // Expands/shrinks the committed space in a virtual space. Delegates | 326 // Expands/shrinks the committed space in a virtual space. Delegates |
305 // to Virtualspace | 327 // to Virtualspace |
306 bool expand_by(size_t words, bool pre_touch = false); | 328 bool expand_by(size_t words, bool pre_touch = false); |
307 bool shrink_by(size_t words); | 329 bool shrink_by(size_t words); |
330 | |
331 // In preparation for deleting this node, remove all the chunks | |
332 // in the node from any freelist. | |
333 void purge(ChunkManager* chunk_manager); | |
308 | 334 |
309 #ifdef ASSERT | 335 #ifdef ASSERT |
310 // Debug support | 336 // Debug support |
311 static void verify_virtual_space_total(); | 337 static void verify_virtual_space_total(); |
312 static void verify_virtual_space_count(); | 338 static void verify_virtual_space_count(); |
315 | 341 |
316 void print_on(outputStream* st) const; | 342 void print_on(outputStream* st) const; |
317 }; | 343 }; |
318 | 344 |
319 // byte_size is the size of the associated virtualspace. | 345 // byte_size is the size of the associated virtualspace. |
320 VirtualSpaceNode::VirtualSpaceNode(size_t byte_size) : _top(NULL), _next(NULL), _rs(0) { | 346 VirtualSpaceNode::VirtualSpaceNode(size_t byte_size) : _top(NULL), _next(NULL), _rs(0), _container_count(0) { |
321 // align up to vm allocation granularity | 347 // align up to vm allocation granularity |
322 byte_size = align_size_up(byte_size, os::vm_allocation_granularity()); | 348 byte_size = align_size_up(byte_size, os::vm_allocation_granularity()); |
323 | 349 |
324 // This allocates memory with mmap. For DumpSharedspaces, try to reserve | 350 // This allocates memory with mmap. For DumpSharedspaces, try to reserve |
325 // configurable address, generally at the top of the Java heap so other | 351 // configurable address, generally at the top of the Java heap so other |
339 } | 365 } |
340 | 366 |
341 MemTracker::record_virtual_memory_type((address)_rs.base(), mtClass); | 367 MemTracker::record_virtual_memory_type((address)_rs.base(), mtClass); |
342 } | 368 } |
343 | 369 |
370 void VirtualSpaceNode::purge(ChunkManager* chunk_manager) { | |
371 Metachunk* chunk = first_chunk(); | |
372 Metachunk* invalid_chunk = (Metachunk*) top(); | |
373 while (chunk < invalid_chunk ) { | |
374 assert(chunk->is_free(), "Should be marked free"); | |
375 MetaWord* next = ((MetaWord*)chunk) + chunk->word_size(); | |
376 chunk_manager->remove_chunk(chunk); | |
377 assert(chunk->next() == NULL && | |
378 chunk->prev() == NULL, | |
379 "Was not removed from its list"); | |
380 chunk = (Metachunk*) next; | |
381 } | |
382 } | |
383 | |
384 #ifdef ASSERT | |
385 uint VirtualSpaceNode::container_count_slow() { | |
386 uint count = 0; | |
387 Metachunk* chunk = first_chunk(); | |
388 Metachunk* invalid_chunk = (Metachunk*) top(); | |
389 while (chunk < invalid_chunk ) { | |
390 MetaWord* next = ((MetaWord*)chunk) + chunk->word_size(); | |
391 // Don't count the chunks on the free lists. Those are | |
392 // still part of the VirtualSpaceNode but not currently | |
393 // counted. | |
394 if (!chunk->is_free()) { | |
395 count++; | |
396 } | |
397 chunk = (Metachunk*) next; | |
398 } | |
399 return count; | |
400 } | |
401 #endif | |
402 | |
344 // List of VirtualSpaces for metadata allocation. | 403 // List of VirtualSpaces for metadata allocation. |
345 // It has a _next link for singly linked list and a MemRegion | 404 // It has a _next link for singly linked list and a MemRegion |
346 // for total space in the VirtualSpace. | 405 // for total space in the VirtualSpace. |
347 class VirtualSpaceList : public CHeapObj<mtClass> { | 406 class VirtualSpaceList : public CHeapObj<mtClass> { |
348 friend class VirtualSpaceNode; | 407 friend class VirtualSpaceNode; |
408 | 467 |
409 // Allocate the first virtualspace. | 468 // Allocate the first virtualspace. |
410 void initialize(size_t word_size); | 469 void initialize(size_t word_size); |
411 | 470 |
412 size_t virtual_space_total() { return _virtual_space_total; } | 471 size_t virtual_space_total() { return _virtual_space_total; } |
413 void inc_virtual_space_total(size_t v) { | 472 |
414 Atomic::add_ptr(v, &_virtual_space_total); | 473 void inc_virtual_space_total(size_t v); |
415 } | 474 void dec_virtual_space_total(size_t v); |
416 | 475 void inc_virtual_space_count(); |
417 size_t virtual_space_count() { return _virtual_space_count; } | 476 void dec_virtual_space_count(); |
418 void inc_virtual_space_count() { | 477 |
419 Atomic::inc_ptr(&_virtual_space_count); | 478 // Unlink empty VirtualSpaceNodes and free it. |
420 } | 479 void purge(); |
421 | 480 |
422 // Used and capacity in the entire list of virtual spaces. | 481 // Used and capacity in the entire list of virtual spaces. |
423 // These are global values shared by all Metaspaces | 482 // These are global values shared by all Metaspaces |
424 size_t capacity_words_sum(); | 483 size_t capacity_words_sum(); |
425 size_t capacity_bytes_sum() { return capacity_words_sum() * BytesPerWord; } | 484 size_t capacity_bytes_sum() { return capacity_words_sum() * BytesPerWord; } |
639 Mutex* const SpaceManager::_expand_lock = | 698 Mutex* const SpaceManager::_expand_lock = |
640 new Mutex(SpaceManager::_expand_lock_rank, | 699 new Mutex(SpaceManager::_expand_lock_rank, |
641 SpaceManager::_expand_lock_name, | 700 SpaceManager::_expand_lock_name, |
642 Mutex::_allow_vm_block_flag); | 701 Mutex::_allow_vm_block_flag); |
643 | 702 |
703 void VirtualSpaceNode::inc_container_count() { | |
704 assert_lock_strong(SpaceManager::expand_lock()); | |
705 _container_count++; | |
706 assert(_container_count == container_count_slow(), | |
707 err_msg("Inconsistency in countainer_count _container_count " SIZE_FORMAT | |
708 "container_count_slow() " SIZE_FORMAT, | |
709 _container_count, container_count_slow())); | |
710 } | |
711 | |
712 void VirtualSpaceNode::dec_container_count() { | |
713 assert_lock_strong(SpaceManager::expand_lock()); | |
714 _container_count--; | |
715 } | |
716 | |
717 #ifdef ASSERT | |
718 void VirtualSpaceNode::verify_container_count() { | |
719 assert(_container_count == container_count_slow(), | |
720 err_msg("Inconsistency in countainer_count _container_count " SIZE_FORMAT | |
721 "container_count_slow() " SIZE_FORMAT, _container_count, container_count_slow())); | |
722 } | |
723 #endif | |
724 | |
644 // BlockFreelist methods | 725 // BlockFreelist methods |
645 | 726 |
646 BlockFreelist::BlockFreelist() : _dictionary(NULL) {} | 727 BlockFreelist::BlockFreelist() : _dictionary(NULL) {} |
647 | 728 |
648 BlockFreelist::~BlockFreelist() { | 729 BlockFreelist::~BlockFreelist() { |
699 | 780 |
700 // VirtualSpaceNode methods | 781 // VirtualSpaceNode methods |
701 | 782 |
702 VirtualSpaceNode::~VirtualSpaceNode() { | 783 VirtualSpaceNode::~VirtualSpaceNode() { |
703 _rs.release(); | 784 _rs.release(); |
785 #ifdef ASSERT | |
786 size_t word_size = sizeof(*this) / BytesPerWord; | |
787 Copy::fill_to_words((HeapWord*) this, word_size, 0xf1f1f1f1); | |
788 #endif | |
704 } | 789 } |
705 | 790 |
706 size_t VirtualSpaceNode::used_words_in_vs() const { | 791 size_t VirtualSpaceNode::used_words_in_vs() const { |
707 return pointer_delta(top(), bottom(), sizeof(MetaWord)); | 792 return pointer_delta(top(), bottom(), sizeof(MetaWord)); |
708 } | 793 } |
731 } | 816 } |
732 | 817 |
733 // Take the space (bump top on the current virtual space). | 818 // Take the space (bump top on the current virtual space). |
734 inc_top(chunk_word_size); | 819 inc_top(chunk_word_size); |
735 | 820 |
736 // Point the chunk at the space | 821 // Initialize the chunk |
737 Metachunk* result = Metachunk::initialize(chunk_limit, chunk_word_size); | 822 Metachunk* result = ::new (chunk_limit) Metachunk(chunk_word_size, this); |
738 return result; | 823 return result; |
739 } | 824 } |
740 | 825 |
741 | 826 |
742 // Expand the virtual space (commit more of the reserved space) | 827 // Expand the virtual space (commit more of the reserved space) |
760 | 845 |
761 // Add another chunk to the chunk list. | 846 // Add another chunk to the chunk list. |
762 | 847 |
763 Metachunk* VirtualSpaceNode::get_chunk_vs(size_t chunk_word_size) { | 848 Metachunk* VirtualSpaceNode::get_chunk_vs(size_t chunk_word_size) { |
764 assert_lock_strong(SpaceManager::expand_lock()); | 849 assert_lock_strong(SpaceManager::expand_lock()); |
765 Metachunk* result = NULL; | 850 Metachunk* result = take_from_committed(chunk_word_size); |
766 | 851 if (result != NULL) { |
767 return take_from_committed(chunk_word_size); | 852 inc_container_count(); |
853 } | |
854 return result; | |
768 } | 855 } |
769 | 856 |
770 Metachunk* VirtualSpaceNode::get_chunk_vs_with_expand(size_t chunk_word_size) { | 857 Metachunk* VirtualSpaceNode::get_chunk_vs_with_expand(size_t chunk_word_size) { |
771 assert_lock_strong(SpaceManager::expand_lock()); | 858 assert_lock_strong(SpaceManager::expand_lock()); |
772 | 859 |
839 VirtualSpaceListIterator iter(virtual_space_list()); | 926 VirtualSpaceListIterator iter(virtual_space_list()); |
840 while (iter.repeat()) { | 927 while (iter.repeat()) { |
841 VirtualSpaceNode* vsl = iter.get_next(); | 928 VirtualSpaceNode* vsl = iter.get_next(); |
842 delete vsl; | 929 delete vsl; |
843 } | 930 } |
931 } | |
932 | |
933 void VirtualSpaceList::inc_virtual_space_total(size_t v) { | |
934 assert_lock_strong(SpaceManager::expand_lock()); | |
935 _virtual_space_total = _virtual_space_total + v; | |
936 } | |
937 void VirtualSpaceList::dec_virtual_space_total(size_t v) { | |
938 assert_lock_strong(SpaceManager::expand_lock()); | |
939 _virtual_space_total = _virtual_space_total - v; | |
940 } | |
941 | |
942 void VirtualSpaceList::inc_virtual_space_count() { | |
943 assert_lock_strong(SpaceManager::expand_lock()); | |
944 _virtual_space_count++; | |
945 } | |
946 void VirtualSpaceList::dec_virtual_space_count() { | |
947 assert_lock_strong(SpaceManager::expand_lock()); | |
948 _virtual_space_count--; | |
949 } | |
950 | |
951 void ChunkManager::remove_chunk(Metachunk* chunk) { | |
952 size_t word_size = chunk->word_size(); | |
953 ChunkIndex index = list_index(word_size); | |
954 if (index != HumongousIndex) { | |
955 free_chunks(index)->remove_chunk(chunk); | |
956 } else { | |
957 humongous_dictionary()->remove_chunk(chunk); | |
958 } | |
959 | |
960 // Chunk is being removed from the chunks free list. | |
961 dec_free_chunks_total(chunk->capacity_word_size()); | |
962 } | |
963 | |
964 // Walk the list of VirtualSpaceNodes and delete | |
965 // nodes with a 0 container_count. Remove Metachunks in | |
966 // the node from their respective freelists. | |
967 void VirtualSpaceList::purge() { | |
968 assert_lock_strong(SpaceManager::expand_lock()); | |
969 // Don't use a VirtualSpaceListIterator because this | |
970 // list is being changed and a straightforward use of an iterator is not safe. | |
971 VirtualSpaceNode* purged_vsl = NULL; | |
972 VirtualSpaceNode* prev_vsl = virtual_space_list(); | |
973 VirtualSpaceNode* next_vsl = prev_vsl; | |
974 while (next_vsl != NULL) { | |
975 VirtualSpaceNode* vsl = next_vsl; | |
976 next_vsl = vsl->next(); | |
977 // Don't free the current virtual space since it will likely | |
978 // be needed soon. | |
979 if (vsl->container_count() == 0 && vsl != current_virtual_space()) { | |
980 // Unlink it from the list | |
981 if (prev_vsl == vsl) { | |
982 // This is the case of the current note being the first note. | |
983 assert(vsl == virtual_space_list(), "Expected to be the first note"); | |
984 set_virtual_space_list(vsl->next()); | |
985 } else { | |
986 prev_vsl->set_next(vsl->next()); | |
987 } | |
988 | |
989 vsl->purge(chunk_manager()); | |
990 dec_virtual_space_total(vsl->reserved()->word_size()); | |
991 dec_virtual_space_count(); | |
992 purged_vsl = vsl; | |
993 delete vsl; | |
994 } else { | |
995 prev_vsl = vsl; | |
996 } | |
997 } | |
998 #ifdef ASSERT | |
999 if (purged_vsl != NULL) { | |
1000 // List should be stable enough to use an iterator here. | |
1001 VirtualSpaceListIterator iter(virtual_space_list()); | |
1002 while (iter.repeat()) { | |
1003 VirtualSpaceNode* vsl = iter.get_next(); | |
1004 assert(vsl != purged_vsl, "Purge of vsl failed"); | |
1005 } | |
1006 } | |
1007 #endif | |
844 } | 1008 } |
845 | 1009 |
846 size_t VirtualSpaceList::used_words_sum() { | 1010 size_t VirtualSpaceList::used_words_sum() { |
847 size_t allocated_by_vs = 0; | 1011 size_t allocated_by_vs = 0; |
848 VirtualSpaceListIterator iter(virtual_space_list()); | 1012 VirtualSpaceListIterator iter(virtual_space_list()); |
953 size_t medium_chunk_bunch) { | 1117 size_t medium_chunk_bunch) { |
954 | 1118 |
955 // Get a chunk from the chunk freelist | 1119 // Get a chunk from the chunk freelist |
956 Metachunk* next = chunk_manager()->chunk_freelist_allocate(grow_chunks_by_words); | 1120 Metachunk* next = chunk_manager()->chunk_freelist_allocate(grow_chunks_by_words); |
957 | 1121 |
958 // Allocate a chunk out of the current virtual space. | 1122 if (next != NULL) { |
959 if (next == NULL) { | 1123 next->container()->inc_container_count(); |
1124 } else { | |
1125 // Allocate a chunk out of the current virtual space. | |
960 next = current_virtual_space()->get_chunk_vs(grow_chunks_by_words); | 1126 next = current_virtual_space()->get_chunk_vs(grow_chunks_by_words); |
961 } | 1127 } |
962 | 1128 |
963 if (next == NULL) { | 1129 if (next == NULL) { |
964 // Not enough room in current virtual space. Try to commit | 1130 // Not enough room in current virtual space. Try to commit |
1565 " waste " SIZE_FORMAT, | 1731 " waste " SIZE_FORMAT, |
1566 chunk->word_size(), word_size, waste); | 1732 chunk->word_size(), word_size, waste); |
1567 } | 1733 } |
1568 // Chunk is being removed from the chunks free list. | 1734 // Chunk is being removed from the chunks free list. |
1569 dec_free_chunks_total(chunk->capacity_word_size()); | 1735 dec_free_chunks_total(chunk->capacity_word_size()); |
1570 #ifdef ASSERT | |
1571 chunk->set_is_free(false); | |
1572 #endif | |
1573 } else { | 1736 } else { |
1574 return NULL; | 1737 return NULL; |
1575 } | 1738 } |
1576 } | 1739 } |
1577 | 1740 |
1578 // Remove it from the links to this freelist | 1741 // Remove it from the links to this freelist |
1579 chunk->set_next(NULL); | 1742 chunk->set_next(NULL); |
1580 chunk->set_prev(NULL); | 1743 chunk->set_prev(NULL); |
1744 #ifdef ASSERT | |
1745 // Chunk is no longer on any freelist. Setting to false make container_count_slow() | |
1746 // work. | |
1747 chunk->set_is_free(false); | |
1748 #endif | |
1581 slow_locked_verify(); | 1749 slow_locked_verify(); |
1582 return chunk; | 1750 return chunk; |
1583 } | 1751 } |
1584 | 1752 |
1585 Metachunk* ChunkManager::chunk_freelist_allocate(size_t word_size) { | 1753 Metachunk* ChunkManager::chunk_freelist_allocate(size_t word_size) { |
1885 ChunkList* list = free_chunks(index); | 2053 ChunkList* list = free_chunks(index); |
1886 assert(list->size() == chunks->word_size(), "Mismatch in chunk sizes"); | 2054 assert(list->size() == chunks->word_size(), "Mismatch in chunk sizes"); |
1887 assert_lock_strong(SpaceManager::expand_lock()); | 2055 assert_lock_strong(SpaceManager::expand_lock()); |
1888 Metachunk* cur = chunks; | 2056 Metachunk* cur = chunks; |
1889 | 2057 |
1890 // This return chunks one at a time. If a new | 2058 // This returns chunks one at a time. If a new |
1891 // class List can be created that is a base class | 2059 // class List can be created that is a base class |
1892 // of FreeList then something like FreeList::prepend() | 2060 // of FreeList then something like FreeList::prepend() |
1893 // can be used in place of this loop | 2061 // can be used in place of this loop |
1894 while (cur != NULL) { | 2062 while (cur != NULL) { |
2063 assert(cur->container() != NULL, "Container should have been set"); | |
2064 cur->container()->dec_container_count(); | |
1895 // Capture the next link before it is changed | 2065 // Capture the next link before it is changed |
1896 // by the call to return_chunk_at_head(); | 2066 // by the call to return_chunk_at_head(); |
1897 Metachunk* next = cur->next(); | 2067 Metachunk* next = cur->next(); |
1898 cur->set_is_free(true); | 2068 cur->set_is_free(true); |
1899 list->return_chunk_at_head(cur); | 2069 list->return_chunk_at_head(cur); |
1915 if (TraceMetadataChunkAllocation && Verbose) { | 2085 if (TraceMetadataChunkAllocation && Verbose) { |
1916 gclog_or_tty->print_cr("~SpaceManager(): " PTR_FORMAT, this); | 2086 gclog_or_tty->print_cr("~SpaceManager(): " PTR_FORMAT, this); |
1917 locked_print_chunks_in_use_on(gclog_or_tty); | 2087 locked_print_chunks_in_use_on(gclog_or_tty); |
1918 } | 2088 } |
1919 | 2089 |
1920 // Mangle freed memory. | 2090 // Do not mangle freed Metachunks. The chunk size inside Metachunks |
1921 NOT_PRODUCT(mangle_freed_chunks();) | 2091 // is during the freeing of a VirtualSpaceNodes. |
1922 | 2092 |
1923 // Have to update before the chunks_in_use lists are emptied | 2093 // Have to update before the chunks_in_use lists are emptied |
1924 // below. | 2094 // below. |
1925 chunk_manager->inc_free_chunks_total(in_use_before, | 2095 chunk_manager->inc_free_chunks_total(in_use_before, |
1926 sum_count_in_chunks_in_use()); | 2096 sum_count_in_chunks_in_use()); |
1976 HumongousChunkGranularity), | 2146 HumongousChunkGranularity), |
1977 err_msg("Humongous chunk size is wrong: word size " SIZE_FORMAT | 2147 err_msg("Humongous chunk size is wrong: word size " SIZE_FORMAT |
1978 " granularity %d", | 2148 " granularity %d", |
1979 humongous_chunks->word_size(), HumongousChunkGranularity)); | 2149 humongous_chunks->word_size(), HumongousChunkGranularity)); |
1980 Metachunk* next_humongous_chunks = humongous_chunks->next(); | 2150 Metachunk* next_humongous_chunks = humongous_chunks->next(); |
2151 humongous_chunks->container()->dec_container_count(); | |
1981 chunk_manager->humongous_dictionary()->return_chunk(humongous_chunks); | 2152 chunk_manager->humongous_dictionary()->return_chunk(humongous_chunks); |
1982 humongous_chunks = next_humongous_chunks; | 2153 humongous_chunks = next_humongous_chunks; |
1983 } | 2154 } |
1984 if (TraceMetadataChunkAllocation && Verbose) { | 2155 if (TraceMetadataChunkAllocation && Verbose) { |
1985 gclog_or_tty->print_cr(""); | 2156 gclog_or_tty->print_cr(""); |
2714 } | 2885 } |
2715 } | 2886 } |
2716 return Metablock::initialize(result, word_size); | 2887 return Metablock::initialize(result, word_size); |
2717 } | 2888 } |
2718 | 2889 |
2890 void Metaspace::purge() { | |
2891 MutexLockerEx cl(SpaceManager::expand_lock(), | |
2892 Mutex::_no_safepoint_check_flag); | |
2893 space_list()->purge(); | |
2894 class_space_list()->purge(); | |
2895 } | |
2896 | |
2719 void Metaspace::print_on(outputStream* out) const { | 2897 void Metaspace::print_on(outputStream* out) const { |
2720 // Print both class virtual space counts and metaspace. | 2898 // Print both class virtual space counts and metaspace. |
2721 if (Verbose) { | 2899 if (Verbose) { |
2722 vsm()->print_on(out); | 2900 vsm()->print_on(out); |
2723 class_vsm()->print_on(out); | 2901 class_vsm()->print_on(out); |
2731 // This is checked while unlocked. As long as the virtualspaces are added | 2909 // This is checked while unlocked. As long as the virtualspaces are added |
2732 // at the end, the pointer will be in one of them. The virtual spaces | 2910 // at the end, the pointer will be in one of them. The virtual spaces |
2733 // aren't deleted presently. When they are, some sort of locking might | 2911 // aren't deleted presently. When they are, some sort of locking might |
2734 // be needed. Note, locking this can cause inversion problems with the | 2912 // be needed. Note, locking this can cause inversion problems with the |
2735 // caller in MetaspaceObj::is_metadata() function. | 2913 // caller in MetaspaceObj::is_metadata() function. |
2736 return space_list()->contains(ptr) || class_space_list()->contains(ptr); | 2914 return space_list()->contains(ptr) || |
2915 class_space_list()->contains(ptr); | |
2737 } | 2916 } |
2738 | 2917 |
2739 void Metaspace::verify() { | 2918 void Metaspace::verify() { |
2740 vsm()->verify(); | 2919 vsm()->verify(); |
2741 class_vsm()->verify(); | 2920 class_vsm()->verify(); |