28 #include "memory/freeList.hpp" |
28 #include "memory/freeList.hpp" |
29 #include "memory/collectorPolicy.hpp" |
29 #include "memory/collectorPolicy.hpp" |
30 #include "memory/filemap.hpp" |
30 #include "memory/filemap.hpp" |
31 #include "memory/freeList.hpp" |
31 #include "memory/freeList.hpp" |
32 #include "memory/gcLocker.hpp" |
32 #include "memory/gcLocker.hpp" |
33 #include "memory/metablock.hpp" |
|
34 #include "memory/metachunk.hpp" |
33 #include "memory/metachunk.hpp" |
35 #include "memory/metaspace.hpp" |
34 #include "memory/metaspace.hpp" |
36 #include "memory/metaspaceShared.hpp" |
35 #include "memory/metaspaceShared.hpp" |
37 #include "memory/resourceArea.hpp" |
36 #include "memory/resourceArea.hpp" |
38 #include "memory/universe.hpp" |
37 #include "memory/universe.hpp" |
47 #include "utilities/copy.hpp" |
46 #include "utilities/copy.hpp" |
48 #include "utilities/debug.hpp" |
47 #include "utilities/debug.hpp" |
49 |
48 |
50 typedef BinaryTreeDictionary<Metablock, FreeList> BlockTreeDictionary; |
49 typedef BinaryTreeDictionary<Metablock, FreeList> BlockTreeDictionary; |
51 typedef BinaryTreeDictionary<Metachunk, FreeList> ChunkTreeDictionary; |
50 typedef BinaryTreeDictionary<Metachunk, FreeList> ChunkTreeDictionary; |
52 // Define this macro to enable slow integrity checking of |
51 |
53 // the free chunk lists |
52 // Set this constant to enable slow integrity checking of the free chunk lists |
54 const bool metaspace_slow_verify = false; |
53 const bool metaspace_slow_verify = false; |
55 |
54 |
56 // Parameters for stress mode testing |
55 // Parameters for stress mode testing |
57 const uint metadata_deallocate_a_lot_block = 10; |
56 const uint metadata_deallocate_a_lot_block = 10; |
58 const uint metadata_deallocate_a_lock_chunk = 3; |
57 const uint metadata_deallocate_a_lock_chunk = 3; |
90 |
89 |
91 volatile intptr_t MetaspaceGC::_capacity_until_GC = 0; |
90 volatile intptr_t MetaspaceGC::_capacity_until_GC = 0; |
92 uint MetaspaceGC::_shrink_factor = 0; |
91 uint MetaspaceGC::_shrink_factor = 0; |
93 bool MetaspaceGC::_should_concurrent_collect = false; |
92 bool MetaspaceGC::_should_concurrent_collect = false; |
94 |
93 |
95 // Blocks of space for metadata are allocated out of Metachunks. |
|
96 // |
|
97 // Metachunk are allocated out of MetadataVirtualspaces and once |
|
98 // allocated there is no explicit link between a Metachunk and |
|
99 // the MetadataVirtualspaces from which it was allocated. |
|
100 // |
|
101 // Each SpaceManager maintains a |
|
102 // list of the chunks it is using and the current chunk. The current |
|
103 // chunk is the chunk from which allocations are done. Space freed in |
|
104 // a chunk is placed on the free list of blocks (BlockFreelist) and |
|
105 // reused from there. |
|
106 |
|
107 typedef class FreeList<Metachunk> ChunkList; |
94 typedef class FreeList<Metachunk> ChunkList; |
108 |
95 |
109 // Manages the global free lists of chunks. |
96 // Manages the global free lists of chunks. |
110 // Has three lists of free chunks, and a total size and |
|
111 // count that includes all three |
|
112 |
|
113 class ChunkManager : public CHeapObj<mtInternal> { |
97 class ChunkManager : public CHeapObj<mtInternal> { |
114 |
98 |
115 // Free list of chunks of different sizes. |
99 // Free list of chunks of different sizes. |
116 // SpecializedChunk |
100 // SpecializedChunk |
117 // SmallChunk |
101 // SmallChunk |
118 // MediumChunk |
102 // MediumChunk |
119 // HumongousChunk |
103 // HumongousChunk |
120 ChunkList _free_chunks[NumberOfFreeLists]; |
104 ChunkList _free_chunks[NumberOfFreeLists]; |
121 |
|
122 |
105 |
123 // HumongousChunk |
106 // HumongousChunk |
124 ChunkTreeDictionary _humongous_dictionary; |
107 ChunkTreeDictionary _humongous_dictionary; |
125 |
108 |
126 // ChunkManager in all lists of this type |
109 // ChunkManager in all lists of this type |
228 |
211 |
229 // Used to manage the free list of Metablocks (a block corresponds |
212 // Used to manage the free list of Metablocks (a block corresponds |
230 // to the allocation of a quantum of metadata). |
213 // to the allocation of a quantum of metadata). |
231 class BlockFreelist VALUE_OBJ_CLASS_SPEC { |
214 class BlockFreelist VALUE_OBJ_CLASS_SPEC { |
232 BlockTreeDictionary* _dictionary; |
215 BlockTreeDictionary* _dictionary; |
233 static Metablock* initialize_free_chunk(MetaWord* p, size_t word_size); |
|
234 |
216 |
235 // Only allocate and split from freelist if the size of the allocation |
217 // Only allocate and split from freelist if the size of the allocation |
236 // is at least 1/4th the size of the available block. |
218 // is at least 1/4th the size of the available block. |
237 const static int WasteMultiplier = 4; |
219 const static int WasteMultiplier = 4; |
238 |
220 |
256 } |
238 } |
257 |
239 |
258 void print_on(outputStream* st) const; |
240 void print_on(outputStream* st) const; |
259 }; |
241 }; |
260 |
242 |
|
243 // A VirtualSpaceList node. |
261 class VirtualSpaceNode : public CHeapObj<mtClass> { |
244 class VirtualSpaceNode : public CHeapObj<mtClass> { |
262 friend class VirtualSpaceList; |
245 friend class VirtualSpaceList; |
263 |
246 |
264 // Link to next VirtualSpaceNode |
247 // Link to next VirtualSpaceNode |
265 VirtualSpaceNode* _next; |
248 VirtualSpaceNode* _next; |
412 |
395 |
413 void VirtualSpaceNode::purge(ChunkManager* chunk_manager) { |
396 void VirtualSpaceNode::purge(ChunkManager* chunk_manager) { |
414 Metachunk* chunk = first_chunk(); |
397 Metachunk* chunk = first_chunk(); |
415 Metachunk* invalid_chunk = (Metachunk*) top(); |
398 Metachunk* invalid_chunk = (Metachunk*) top(); |
416 while (chunk < invalid_chunk ) { |
399 while (chunk < invalid_chunk ) { |
417 assert(chunk->is_free(), "Should be marked free"); |
400 assert(chunk->is_tagged_free(), "Should be tagged free"); |
418 MetaWord* next = ((MetaWord*)chunk) + chunk->word_size(); |
401 MetaWord* next = ((MetaWord*)chunk) + chunk->word_size(); |
419 chunk_manager->remove_chunk(chunk); |
402 chunk_manager->remove_chunk(chunk); |
420 assert(chunk->next() == NULL && |
403 assert(chunk->next() == NULL && |
421 chunk->prev() == NULL, |
404 chunk->prev() == NULL, |
422 "Was not removed from its list"); |
405 "Was not removed from its list"); |
423 chunk = (Metachunk*) next; |
406 chunk = (Metachunk*) next; |
424 } |
407 } |
425 } |
408 } |
426 |
409 |
427 #ifdef ASSERT |
410 #ifdef ASSERT |
428 uint VirtualSpaceNode::container_count_slow() { |
411 uint VirtualSpaceNode::container_count_slow() { |
432 while (chunk < invalid_chunk ) { |
415 while (chunk < invalid_chunk ) { |
433 MetaWord* next = ((MetaWord*)chunk) + chunk->word_size(); |
416 MetaWord* next = ((MetaWord*)chunk) + chunk->word_size(); |
434 // Don't count the chunks on the free lists. Those are |
417 // Don't count the chunks on the free lists. Those are |
435 // still part of the VirtualSpaceNode but not currently |
418 // still part of the VirtualSpaceNode but not currently |
436 // counted. |
419 // counted. |
437 if (!chunk->is_free()) { |
420 if (!chunk->is_tagged_free()) { |
438 count++; |
421 count++; |
439 } |
422 } |
440 chunk = (Metachunk*) next; |
423 chunk = (Metachunk*) next; |
441 } |
424 } |
442 return count; |
425 return count; |
751 #ifdef ASSERT |
734 #ifdef ASSERT |
752 void verify_allocated_blocks_words(); |
735 void verify_allocated_blocks_words(); |
753 #endif |
736 #endif |
754 |
737 |
755 size_t get_raw_word_size(size_t word_size) { |
738 size_t get_raw_word_size(size_t word_size) { |
756 // If only the dictionary is going to be used (i.e., no |
|
757 // indexed free list), then there is a minimum size requirement. |
|
758 // MinChunkSize is a placeholder for the real minimum size JJJ |
|
759 size_t byte_size = word_size * BytesPerWord; |
739 size_t byte_size = word_size * BytesPerWord; |
760 |
740 |
761 size_t raw_bytes_size = MAX2(byte_size, |
741 size_t raw_bytes_size = MAX2(byte_size, sizeof(Metablock)); |
762 Metablock::min_block_byte_size()); |
742 raw_bytes_size = align_size_up(raw_bytes_size, Metachunk::object_alignment()); |
763 raw_bytes_size = ARENA_ALIGN(raw_bytes_size); |
743 |
764 size_t raw_word_size = raw_bytes_size / BytesPerWord; |
744 size_t raw_word_size = raw_bytes_size / BytesPerWord; |
765 assert(raw_word_size * BytesPerWord == raw_bytes_size, "Size problem"); |
745 assert(raw_word_size * BytesPerWord == raw_bytes_size, "Size problem"); |
766 |
746 |
767 return raw_word_size; |
747 return raw_word_size; |
768 } |
748 } |
811 } |
791 } |
812 delete _dictionary; |
792 delete _dictionary; |
813 } |
793 } |
814 } |
794 } |
815 |
795 |
816 Metablock* BlockFreelist::initialize_free_chunk(MetaWord* p, size_t word_size) { |
|
817 Metablock* block = (Metablock*) p; |
|
818 block->set_word_size(word_size); |
|
819 block->set_prev(NULL); |
|
820 block->set_next(NULL); |
|
821 |
|
822 return block; |
|
823 } |
|
824 |
|
825 void BlockFreelist::return_block(MetaWord* p, size_t word_size) { |
796 void BlockFreelist::return_block(MetaWord* p, size_t word_size) { |
826 Metablock* free_chunk = initialize_free_chunk(p, word_size); |
797 Metablock* free_chunk = ::new (p) Metablock(word_size); |
827 if (dictionary() == NULL) { |
798 if (dictionary() == NULL) { |
828 _dictionary = new BlockTreeDictionary(); |
799 _dictionary = new BlockTreeDictionary(); |
829 } |
800 } |
830 dictionary()->return_chunk(free_chunk); |
801 dictionary()->return_chunk(free_chunk); |
831 } |
802 } |
1067 } else { |
1038 } else { |
1068 humongous_dictionary()->remove_chunk(chunk); |
1039 humongous_dictionary()->remove_chunk(chunk); |
1069 } |
1040 } |
1070 |
1041 |
1071 // Chunk is being removed from the chunks free list. |
1042 // Chunk is being removed from the chunks free list. |
1072 dec_free_chunks_total(chunk->capacity_word_size()); |
1043 dec_free_chunks_total(chunk->word_size()); |
1073 } |
1044 } |
1074 |
1045 |
1075 // Walk the list of VirtualSpaceNodes and delete |
1046 // Walk the list of VirtualSpaceNodes and delete |
1076 // nodes with a 0 container_count. Remove Metachunks in |
1047 // nodes with a 0 container_count. Remove Metachunks in |
1077 // the node from their respective freelists. |
1048 // the node from their respective freelists. |
1758 assert_lock_strong(SpaceManager::expand_lock()); |
1729 assert_lock_strong(SpaceManager::expand_lock()); |
1759 ChunkList* free_list = find_free_chunks_list(chunk->word_size()); |
1730 ChunkList* free_list = find_free_chunks_list(chunk->word_size()); |
1760 chunk->set_next(free_list->head()); |
1731 chunk->set_next(free_list->head()); |
1761 free_list->set_head(chunk); |
1732 free_list->set_head(chunk); |
1762 // chunk is being returned to the chunk free list |
1733 // chunk is being returned to the chunk free list |
1763 inc_free_chunks_total(chunk->capacity_word_size()); |
1734 inc_free_chunks_total(chunk->word_size()); |
1764 slow_locked_verify(); |
1735 slow_locked_verify(); |
1765 } |
1736 } |
1766 |
1737 |
1767 void ChunkManager::chunk_freelist_deallocate(Metachunk* chunk) { |
1738 void ChunkManager::chunk_freelist_deallocate(Metachunk* chunk) { |
1768 // The deallocation of a chunk originates in the freelist |
1739 // The deallocation of a chunk originates in the freelist |
1820 chunk->word_size(), word_size, waste); |
1791 chunk->word_size(), word_size, waste); |
1821 } |
1792 } |
1822 } |
1793 } |
1823 |
1794 |
1824 // Chunk is being removed from the chunks free list. |
1795 // Chunk is being removed from the chunks free list. |
1825 dec_free_chunks_total(chunk->capacity_word_size()); |
1796 dec_free_chunks_total(chunk->word_size()); |
1826 |
1797 |
1827 // Remove it from the links to this freelist |
1798 // Remove it from the links to this freelist |
1828 chunk->set_next(NULL); |
1799 chunk->set_next(NULL); |
1829 chunk->set_prev(NULL); |
1800 chunk->set_prev(NULL); |
1830 #ifdef ASSERT |
1801 #ifdef ASSERT |
1831 // Chunk is no longer on any freelist. Setting to false make container_count_slow() |
1802 // Chunk is no longer on any freelist. Setting to false make container_count_slow() |
1832 // work. |
1803 // work. |
1833 chunk->set_is_free(false); |
1804 chunk->set_is_tagged_free(false); |
1834 #endif |
1805 #endif |
1835 chunk->container()->inc_container_count(); |
1806 chunk->container()->inc_container_count(); |
1836 |
1807 |
1837 slow_locked_verify(); |
1808 slow_locked_verify(); |
1838 return chunk; |
1809 return chunk; |
1960 MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag); |
1931 MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag); |
1961 size_t sum = 0; |
1932 size_t sum = 0; |
1962 for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { |
1933 for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { |
1963 Metachunk* chunk = chunks_in_use(i); |
1934 Metachunk* chunk = chunks_in_use(i); |
1964 while (chunk != NULL) { |
1935 while (chunk != NULL) { |
1965 sum += chunk->capacity_word_size(); |
1936 sum += chunk->word_size(); |
1966 chunk = chunk->next(); |
1937 chunk = chunk->next(); |
1967 } |
1938 } |
1968 } |
1939 } |
1969 return sum; |
1940 return sum; |
1970 } |
1941 } |
2208 assert(cur->container() != NULL, "Container should have been set"); |
2179 assert(cur->container() != NULL, "Container should have been set"); |
2209 cur->container()->dec_container_count(); |
2180 cur->container()->dec_container_count(); |
2210 // Capture the next link before it is changed |
2181 // Capture the next link before it is changed |
2211 // by the call to return_chunk_at_head(); |
2182 // by the call to return_chunk_at_head(); |
2212 Metachunk* next = cur->next(); |
2183 Metachunk* next = cur->next(); |
2213 cur->set_is_free(true); |
2184 DEBUG_ONLY(cur->set_is_tagged_free(true);) |
2214 list->return_chunk_at_head(cur); |
2185 list->return_chunk_at_head(cur); |
2215 cur = next; |
2186 cur = next; |
2216 } |
2187 } |
2217 } |
2188 } |
2218 |
2189 |
2280 // Humongous chunks are never the current chunk. |
2251 // Humongous chunks are never the current chunk. |
2281 Metachunk* humongous_chunks = chunks_in_use(HumongousIndex); |
2252 Metachunk* humongous_chunks = chunks_in_use(HumongousIndex); |
2282 |
2253 |
2283 while (humongous_chunks != NULL) { |
2254 while (humongous_chunks != NULL) { |
2284 #ifdef ASSERT |
2255 #ifdef ASSERT |
2285 humongous_chunks->set_is_free(true); |
2256 humongous_chunks->set_is_tagged_free(true); |
2286 #endif |
2257 #endif |
2287 if (TraceMetadataChunkAllocation && Verbose) { |
2258 if (TraceMetadataChunkAllocation && Verbose) { |
2288 gclog_or_tty->print(PTR_FORMAT " (" SIZE_FORMAT ") ", |
2259 gclog_or_tty->print(PTR_FORMAT " (" SIZE_FORMAT ") ", |
2289 humongous_chunks, |
2260 humongous_chunks, |
2290 humongous_chunks->word_size()); |
2261 humongous_chunks->word_size()); |
2543 curr = curr->next()) { |
2514 curr = curr->next()) { |
2544 out->print("%d) ", i++); |
2515 out->print("%d) ", i++); |
2545 curr->print_on(out); |
2516 curr->print_on(out); |
2546 curr_total += curr->word_size(); |
2517 curr_total += curr->word_size(); |
2547 used += curr->used_word_size(); |
2518 used += curr->used_word_size(); |
2548 capacity += curr->capacity_word_size(); |
2519 capacity += curr->word_size(); |
2549 waste += curr->free_word_size() + curr->overhead();; |
2520 waste += curr->free_word_size() + curr->overhead();; |
2550 } |
2521 } |
2551 } |
2522 } |
2552 |
2523 |
2553 if (TraceMetadataChunkAllocation && Verbose) { |
2524 if (TraceMetadataChunkAllocation && Verbose) { |
3394 } |
3365 } |
3395 } |
3366 } |
3396 } |
3367 } |
3397 |
3368 |
3398 |
3369 |
3399 Metablock* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size, |
3370 MetaWord* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size, |
3400 bool read_only, MetaspaceObj::Type type, TRAPS) { |
3371 bool read_only, MetaspaceObj::Type type, TRAPS) { |
3401 if (HAS_PENDING_EXCEPTION) { |
3372 if (HAS_PENDING_EXCEPTION) { |
3402 assert(false, "Should not allocate with exception pending"); |
3373 assert(false, "Should not allocate with exception pending"); |
3403 return NULL; // caller does a CHECK_NULL too |
3374 return NULL; // caller does a CHECK_NULL too |
3404 } |
3375 } |
3413 assert(type > MetaspaceObj::UnknownType && type < MetaspaceObj::_number_of_types, "sanity"); |
3384 assert(type > MetaspaceObj::UnknownType && type < MetaspaceObj::_number_of_types, "sanity"); |
3414 Metaspace* space = read_only ? loader_data->ro_metaspace() : loader_data->rw_metaspace(); |
3385 Metaspace* space = read_only ? loader_data->ro_metaspace() : loader_data->rw_metaspace(); |
3415 MetaWord* result = space->allocate(word_size, NonClassType); |
3386 MetaWord* result = space->allocate(word_size, NonClassType); |
3416 if (result == NULL) { |
3387 if (result == NULL) { |
3417 report_out_of_shared_space(read_only ? SharedReadOnly : SharedReadWrite); |
3388 report_out_of_shared_space(read_only ? SharedReadOnly : SharedReadWrite); |
3418 } else { |
3389 } |
3419 space->record_allocation(result, type, space->vsm()->get_raw_word_size(word_size)); |
3390 |
3420 } |
3391 space->record_allocation(result, type, space->vsm()->get_raw_word_size(word_size)); |
3421 return Metablock::initialize(result, word_size); |
3392 |
|
3393 // Zero initialize. |
|
3394 Copy::fill_to_aligned_words((HeapWord*)result, word_size, 0); |
|
3395 |
|
3396 return result; |
3422 } |
3397 } |
3423 |
3398 |
3424 MetadataType mdtype = (type == MetaspaceObj::ClassType) ? ClassType : NonClassType; |
3399 MetadataType mdtype = (type == MetaspaceObj::ClassType) ? ClassType : NonClassType; |
3425 |
3400 |
3426 // Try to allocate metadata. |
3401 // Try to allocate metadata. |
3441 report_metadata_oome(loader_data, word_size, mdtype, THREAD); |
3416 report_metadata_oome(loader_data, word_size, mdtype, THREAD); |
3442 // Will not reach here. |
3417 // Will not reach here. |
3443 return NULL; |
3418 return NULL; |
3444 } |
3419 } |
3445 |
3420 |
3446 return Metablock::initialize(result, word_size); |
3421 // Zero initialize. |
|
3422 Copy::fill_to_aligned_words((HeapWord*)result, word_size, 0); |
|
3423 |
|
3424 return result; |
3447 } |
3425 } |
3448 |
3426 |
3449 void Metaspace::report_metadata_oome(ClassLoaderData* loader_data, size_t word_size, MetadataType mdtype, TRAPS) { |
3427 void Metaspace::report_metadata_oome(ClassLoaderData* loader_data, size_t word_size, MetadataType mdtype, TRAPS) { |
3450 // If result is still null, we are out of memory. |
3428 // If result is still null, we are out of memory. |
3451 if (Verbose && TraceMetadataChunkAllocation) { |
3429 if (Verbose && TraceMetadataChunkAllocation) { |