44 #include "services/memTracker.hpp" |
44 #include "services/memTracker.hpp" |
45 #include "services/memoryService.hpp" |
45 #include "services/memoryService.hpp" |
46 #include "utilities/copy.hpp" |
46 #include "utilities/copy.hpp" |
47 #include "utilities/debug.hpp" |
47 #include "utilities/debug.hpp" |
48 |
48 |
49 typedef BinaryTreeDictionary<Metablock, FreeList> BlockTreeDictionary; |
49 typedef BinaryTreeDictionary<Metablock, FreeList<Metablock> > BlockTreeDictionary; |
50 typedef BinaryTreeDictionary<Metachunk, FreeList> ChunkTreeDictionary; |
50 typedef BinaryTreeDictionary<Metachunk, FreeList<Metachunk> > ChunkTreeDictionary; |
51 |
51 |
52 // Set this constant to enable slow integrity checking of the free chunk lists |
52 // Set this constant to enable slow integrity checking of the free chunk lists |
53 const bool metaspace_slow_verify = false; |
53 const bool metaspace_slow_verify = false; |
54 |
54 |
55 size_t const allocation_from_dictionary_limit = 4 * K; |
55 size_t const allocation_from_dictionary_limit = 4 * K; |
788 MetaWord* BlockFreelist::get_block(size_t word_size) { |
788 MetaWord* BlockFreelist::get_block(size_t word_size) { |
789 if (dictionary() == NULL) { |
789 if (dictionary() == NULL) { |
790 return NULL; |
790 return NULL; |
791 } |
791 } |
792 |
792 |
793 if (word_size < TreeChunk<Metablock, FreeList>::min_size()) { |
793 if (word_size < TreeChunk<Metablock, FreeList<Metablock> >::min_size()) { |
794 // Dark matter. Too small for dictionary. |
794 // Dark matter. Too small for dictionary. |
795 return NULL; |
795 return NULL; |
796 } |
796 } |
797 |
797 |
798 Metablock* free_block = |
798 Metablock* free_block = |
808 } |
808 } |
809 |
809 |
810 MetaWord* new_block = (MetaWord*)free_block; |
810 MetaWord* new_block = (MetaWord*)free_block; |
811 assert(block_size >= word_size, "Incorrect size of block from freelist"); |
811 assert(block_size >= word_size, "Incorrect size of block from freelist"); |
812 const size_t unused = block_size - word_size; |
812 const size_t unused = block_size - word_size; |
813 if (unused >= TreeChunk<Metablock, FreeList>::min_size()) { |
813 if (unused >= TreeChunk<Metablock, FreeList<Metablock> >::min_size()) { |
814 return_block(new_block + word_size, unused); |
814 return_block(new_block + word_size, unused); |
815 } |
815 } |
816 |
816 |
817 return new_block; |
817 return new_block; |
818 } |
818 } |
2237 } |
2237 } |
2238 |
2238 |
2239 void SpaceManager::deallocate(MetaWord* p, size_t word_size) { |
2239 void SpaceManager::deallocate(MetaWord* p, size_t word_size) { |
2240 assert_lock_strong(_lock); |
2240 assert_lock_strong(_lock); |
2241 size_t raw_word_size = get_raw_word_size(word_size); |
2241 size_t raw_word_size = get_raw_word_size(word_size); |
2242 size_t min_size = TreeChunk<Metablock, FreeList>::min_size(); |
2242 size_t min_size = TreeChunk<Metablock, FreeList<Metablock> >::min_size(); |
2243 assert(raw_word_size >= min_size, |
2243 assert(raw_word_size >= min_size, |
2244 err_msg("Should not deallocate dark matter " SIZE_FORMAT "<" SIZE_FORMAT, word_size, min_size)); |
2244 err_msg("Should not deallocate dark matter " SIZE_FORMAT "<" SIZE_FORMAT, word_size, min_size)); |
2245 block_freelists()->return_block(p, raw_word_size); |
2245 block_freelists()->return_block(p, raw_word_size); |
2246 } |
2246 } |
2247 |
2247 |
2293 } |
2293 } |
2294 |
2294 |
2295 void SpaceManager::retire_current_chunk() { |
2295 void SpaceManager::retire_current_chunk() { |
2296 if (current_chunk() != NULL) { |
2296 if (current_chunk() != NULL) { |
2297 size_t remaining_words = current_chunk()->free_word_size(); |
2297 size_t remaining_words = current_chunk()->free_word_size(); |
2298 if (remaining_words >= TreeChunk<Metablock, FreeList>::min_size()) { |
2298 if (remaining_words >= TreeChunk<Metablock, FreeList<Metablock> >::min_size()) { |
2299 block_freelists()->return_block(current_chunk()->allocate(remaining_words), remaining_words); |
2299 block_freelists()->return_block(current_chunk()->allocate(remaining_words), remaining_words); |
2300 inc_used_metrics(remaining_words); |
2300 inc_used_metrics(remaining_words); |
2301 } |
2301 } |
2302 } |
2302 } |
2303 } |
2303 } |
3276 void Metaspace::deallocate(MetaWord* ptr, size_t word_size, bool is_class) { |
3276 void Metaspace::deallocate(MetaWord* ptr, size_t word_size, bool is_class) { |
3277 if (SafepointSynchronize::is_at_safepoint()) { |
3277 if (SafepointSynchronize::is_at_safepoint()) { |
3278 assert(Thread::current()->is_VM_thread(), "should be the VM thread"); |
3278 assert(Thread::current()->is_VM_thread(), "should be the VM thread"); |
3279 // Don't take Heap_lock |
3279 // Don't take Heap_lock |
3280 MutexLockerEx ml(vsm()->lock(), Mutex::_no_safepoint_check_flag); |
3280 MutexLockerEx ml(vsm()->lock(), Mutex::_no_safepoint_check_flag); |
3281 if (word_size < TreeChunk<Metablock, FreeList>::min_size()) { |
3281 if (word_size < TreeChunk<Metablock, FreeList<Metablock> >::min_size()) { |
3282 // Dark matter. Too small for dictionary. |
3282 // Dark matter. Too small for dictionary. |
3283 #ifdef ASSERT |
3283 #ifdef ASSERT |
3284 Copy::fill_to_words((HeapWord*)ptr, word_size, 0xf5f5f5f5); |
3284 Copy::fill_to_words((HeapWord*)ptr, word_size, 0xf5f5f5f5); |
3285 #endif |
3285 #endif |
3286 return; |
3286 return; |
3291 vsm()->deallocate(ptr, word_size); |
3291 vsm()->deallocate(ptr, word_size); |
3292 } |
3292 } |
3293 } else { |
3293 } else { |
3294 MutexLockerEx ml(vsm()->lock(), Mutex::_no_safepoint_check_flag); |
3294 MutexLockerEx ml(vsm()->lock(), Mutex::_no_safepoint_check_flag); |
3295 |
3295 |
3296 if (word_size < TreeChunk<Metablock, FreeList>::min_size()) { |
3296 if (word_size < TreeChunk<Metablock, FreeList<Metablock> >::min_size()) { |
3297 // Dark matter. Too small for dictionary. |
3297 // Dark matter. Too small for dictionary. |
3298 #ifdef ASSERT |
3298 #ifdef ASSERT |
3299 Copy::fill_to_words((HeapWord*)ptr, word_size, 0xf5f5f5f5); |
3299 Copy::fill_to_words((HeapWord*)ptr, word_size, 0xf5f5f5f5); |
3300 #endif |
3300 #endif |
3301 return; |
3301 return; |