comparison src/share/vm/memory/metaspace.cpp @ 14518:d8041d695d19

Merged with jdk9/dev/hotspot changeset 3812c088b945
author twisti
date Tue, 11 Mar 2014 18:45:59 -0700
parents aa8fab3bed11
children 4ca6dc0799b6
comparison
equal deleted inserted replaced
14141:f97c5ec83832 14518:d8041d695d19
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;
511 void dec_virtual_space_count(); 511 void dec_virtual_space_count();
512 512
513 // Unlink empty VirtualSpaceNodes and free it. 513 // Unlink empty VirtualSpaceNodes and free it.
514 void purge(ChunkManager* chunk_manager); 514 void purge(ChunkManager* chunk_manager);
515 515
516 bool contains(const void *ptr);
517
518 void print_on(outputStream* st) const; 516 void print_on(outputStream* st) const;
519 517
520 class VirtualSpaceListIterator : public StackObj { 518 class VirtualSpaceListIterator : public StackObj {
521 VirtualSpaceNode* _virtual_spaces; 519 VirtualSpaceNode* _virtual_spaces;
522 public: 520 public:
556 friend class Metaspace; 554 friend class Metaspace;
557 friend class Metadebug; 555 friend class Metadebug;
558 556
559 private: 557 private:
560 558
561 // protects allocations and contains. 559 // protects allocations
562 Mutex* const _lock; 560 Mutex* const _lock;
563 561
564 // Type of metadata allocated. 562 // Type of metadata allocated.
565 Metaspace::MetadataType _mdtype; 563 Metaspace::MetadataType _mdtype;
566 564
593 static Mutex* const _expand_lock; 591 static Mutex* const _expand_lock;
594 592
595 private: 593 private:
596 // Accessors 594 // Accessors
597 Metachunk* chunks_in_use(ChunkIndex index) const { return _chunks_in_use[index]; } 595 Metachunk* chunks_in_use(ChunkIndex index) const { return _chunks_in_use[index]; }
598 void set_chunks_in_use(ChunkIndex index, Metachunk* v) { _chunks_in_use[index] = v; } 596 void set_chunks_in_use(ChunkIndex index, Metachunk* v) {
597 // ensure lock-free iteration sees fully initialized node
598 OrderAccess::storestore();
599 _chunks_in_use[index] = v;
600 }
599 601
600 BlockFreelist* block_freelists() const { 602 BlockFreelist* block_freelists() const {
601 return (BlockFreelist*) &_block_freelists; 603 return (BlockFreelist*) &_block_freelists;
602 } 604 }
603 605
706 708
707 void dump(outputStream* const out) const; 709 void dump(outputStream* const out) const;
708 void print_on(outputStream* st) const; 710 void print_on(outputStream* st) const;
709 void locked_print_chunks_in_use_on(outputStream* st) const; 711 void locked_print_chunks_in_use_on(outputStream* st) const;
710 712
713 bool contains(const void *ptr);
714
711 void verify(); 715 void verify();
712 void verify_chunk_size(Metachunk* chunk); 716 void verify_chunk_size(Metachunk* chunk);
713 NOT_PRODUCT(void mangle_freed_chunks();) 717 NOT_PRODUCT(void mangle_freed_chunks();)
714 #ifdef ASSERT 718 #ifdef ASSERT
715 void verify_allocated_blocks_words(); 719 void verify_allocated_blocks_words();
740 744
741 void VirtualSpaceNode::inc_container_count() { 745 void VirtualSpaceNode::inc_container_count() {
742 assert_lock_strong(SpaceManager::expand_lock()); 746 assert_lock_strong(SpaceManager::expand_lock());
743 _container_count++; 747 _container_count++;
744 assert(_container_count == container_count_slow(), 748 assert(_container_count == container_count_slow(),
745 err_msg("Inconsistency in countainer_count _container_count " SIZE_FORMAT 749 err_msg("Inconsistency in container_count _container_count " SIZE_FORMAT
746 " container_count_slow() " SIZE_FORMAT, 750 " container_count_slow() " SIZE_FORMAT,
747 _container_count, container_count_slow())); 751 _container_count, container_count_slow()));
748 } 752 }
749 753
750 void VirtualSpaceNode::dec_container_count() { 754 void VirtualSpaceNode::dec_container_count() {
753 } 757 }
754 758
755 #ifdef ASSERT 759 #ifdef ASSERT
756 void VirtualSpaceNode::verify_container_count() { 760 void VirtualSpaceNode::verify_container_count() {
757 assert(_container_count == container_count_slow(), 761 assert(_container_count == container_count_slow(),
758 err_msg("Inconsistency in countainer_count _container_count " SIZE_FORMAT 762 err_msg("Inconsistency in container_count _container_count " SIZE_FORMAT
759 " container_count_slow() " SIZE_FORMAT, _container_count, container_count_slow())); 763 " container_count_slow() " SIZE_FORMAT, _container_count, container_count_slow()));
760 } 764 }
761 #endif 765 #endif
762 766
763 // BlockFreelist methods 767 // BlockFreelist methods
784 MetaWord* BlockFreelist::get_block(size_t word_size) { 788 MetaWord* BlockFreelist::get_block(size_t word_size) {
785 if (dictionary() == NULL) { 789 if (dictionary() == NULL) {
786 return NULL; 790 return NULL;
787 } 791 }
788 792
789 if (word_size < TreeChunk<Metablock, FreeList>::min_size()) { 793 if (word_size < TreeChunk<Metablock, FreeList<Metablock> >::min_size()) {
790 // Dark matter. Too small for dictionary. 794 // Dark matter. Too small for dictionary.
791 return NULL; 795 return NULL;
792 } 796 }
793 797
794 Metablock* free_block = 798 Metablock* free_block =
804 } 808 }
805 809
806 MetaWord* new_block = (MetaWord*)free_block; 810 MetaWord* new_block = (MetaWord*)free_block;
807 assert(block_size >= word_size, "Incorrect size of block from freelist"); 811 assert(block_size >= word_size, "Incorrect size of block from freelist");
808 const size_t unused = block_size - word_size; 812 const size_t unused = block_size - word_size;
809 if (unused >= TreeChunk<Metablock, FreeList>::min_size()) { 813 if (unused >= TreeChunk<Metablock, FreeList<Metablock> >::min_size()) {
810 return_block(new_block + word_size, unused); 814 return_block(new_block + word_size, unused);
811 } 815 }
812 816
813 return new_block; 817 return new_block;
814 } 818 }
1157 delete new_entry; 1161 delete new_entry;
1158 return false; 1162 return false;
1159 } else { 1163 } else {
1160 assert(new_entry->reserved_words() == vs_word_size, 1164 assert(new_entry->reserved_words() == vs_word_size,
1161 "Reserved memory size differs from requested memory size"); 1165 "Reserved memory size differs from requested memory size");
1162 // ensure lock-free iteration sees fully initialized node
1163 OrderAccess::storestore();
1164 link_vs(new_entry); 1166 link_vs(new_entry);
1165 return true; 1167 return true;
1166 } 1168 }
1167 } 1169 }
1168 1170
1284 VirtualSpaceNode* node = iter.get_next(); 1286 VirtualSpaceNode* node = iter.get_next();
1285 node->print_on(st); 1287 node->print_on(st);
1286 } 1288 }
1287 } 1289 }
1288 } 1290 }
1289
1290 bool VirtualSpaceList::contains(const void *ptr) {
1291 VirtualSpaceNode* list = virtual_space_list();
1292 VirtualSpaceListIterator iter(list);
1293 while (iter.repeat()) {
1294 VirtualSpaceNode* node = iter.get_next();
1295 if (node->reserved()->contains(ptr)) {
1296 return true;
1297 }
1298 }
1299 return false;
1300 }
1301
1302 1291
1303 // MetaspaceGC methods 1292 // MetaspaceGC methods
1304 1293
1305 // VM_CollectForMetadataAllocation is the vm operation used to GC. 1294 // VM_CollectForMetadataAllocation is the vm operation used to GC.
1306 // Within the VM operation after the GC the attempt to allocate the metadata 1295 // Within the VM operation after the GC the attempt to allocate the metadata
1464 return; 1453 return;
1465 } 1454 }
1466 1455
1467 // No expansion, now see if we want to shrink 1456 // No expansion, now see if we want to shrink
1468 // We would never want to shrink more than this 1457 // We would never want to shrink more than this
1458 assert(capacity_until_GC >= minimum_desired_capacity,
1459 err_msg(SIZE_FORMAT " >= " SIZE_FORMAT,
1460 capacity_until_GC, minimum_desired_capacity));
1469 size_t max_shrink_bytes = capacity_until_GC - minimum_desired_capacity; 1461 size_t max_shrink_bytes = capacity_until_GC - minimum_desired_capacity;
1470 assert(max_shrink_bytes >= 0, err_msg("max_shrink_bytes " SIZE_FORMAT,
1471 max_shrink_bytes));
1472 1462
1473 // Should shrinking be considered? 1463 // Should shrinking be considered?
1474 if (MaxMetaspaceFreeRatio < 100) { 1464 if (MaxMetaspaceFreeRatio < 100) {
1475 const double maximum_free_percentage = MaxMetaspaceFreeRatio / 100.0; 1465 const double maximum_free_percentage = MaxMetaspaceFreeRatio / 100.0;
1476 const double minimum_used_percentage = 1.0 - maximum_free_percentage; 1466 const double minimum_used_percentage = 1.0 - maximum_free_percentage;
2248 } 2238 }
2249 2239
2250 void SpaceManager::deallocate(MetaWord* p, size_t word_size) { 2240 void SpaceManager::deallocate(MetaWord* p, size_t word_size) {
2251 assert_lock_strong(_lock); 2241 assert_lock_strong(_lock);
2252 size_t raw_word_size = get_raw_word_size(word_size); 2242 size_t raw_word_size = get_raw_word_size(word_size);
2253 size_t min_size = TreeChunk<Metablock, FreeList>::min_size(); 2243 size_t min_size = TreeChunk<Metablock, FreeList<Metablock> >::min_size();
2254 assert(raw_word_size >= min_size, 2244 assert(raw_word_size >= min_size,
2255 err_msg("Should not deallocate dark matter " SIZE_FORMAT "<" SIZE_FORMAT, word_size, min_size)); 2245 err_msg("Should not deallocate dark matter " SIZE_FORMAT "<" SIZE_FORMAT, word_size, min_size));
2256 block_freelists()->return_block(p, raw_word_size); 2246 block_freelists()->return_block(p, raw_word_size);
2257 } 2247 }
2258 2248
2304 } 2294 }
2305 2295
2306 void SpaceManager::retire_current_chunk() { 2296 void SpaceManager::retire_current_chunk() {
2307 if (current_chunk() != NULL) { 2297 if (current_chunk() != NULL) {
2308 size_t remaining_words = current_chunk()->free_word_size(); 2298 size_t remaining_words = current_chunk()->free_word_size();
2309 if (remaining_words >= TreeChunk<Metablock, FreeList>::min_size()) { 2299 if (remaining_words >= TreeChunk<Metablock, FreeList<Metablock> >::min_size()) {
2310 block_freelists()->return_block(current_chunk()->allocate(remaining_words), remaining_words); 2300 block_freelists()->return_block(current_chunk()->allocate(remaining_words), remaining_words);
2311 inc_used_metrics(remaining_words); 2301 inc_used_metrics(remaining_words);
2312 } 2302 }
2313 } 2303 }
2314 } 2304 }
2390 } 2380 }
2391 2381
2392 return result; 2382 return result;
2393 } 2383 }
2394 2384
2385 // This function looks at the chunks in the metaspace without locking.
2386 // The chunks are added with store ordering and not deleted except for at
2387 // unloading time.
2388 bool SpaceManager::contains(const void *ptr) {
2389 for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i))
2390 {
2391 Metachunk* curr = chunks_in_use(i);
2392 while (curr != NULL) {
2393 if (curr->contains(ptr)) return true;
2394 curr = curr->next();
2395 }
2396 }
2397 return false;
2398 }
2399
2395 void SpaceManager::verify() { 2400 void SpaceManager::verify() {
2396 // If there are blocks in the dictionary, then 2401 // If there are blocks in the dictionary, then
2397 // verfication of chunks does not work since 2402 // verification of chunks does not work since
2398 // being in the dictionary alters a chunk. 2403 // being in the dictionary alters a chunk.
2399 if (block_freelists()->total_size() == 0) { 2404 if (block_freelists()->total_size() == 0) {
2400 for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { 2405 for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) {
2401 Metachunk* curr = chunks_in_use(i); 2406 Metachunk* curr = chunks_in_use(i);
2402 while (curr != NULL) { 2407 while (curr != NULL) {
2861 lower_base = metaspace_base; 2866 lower_base = metaspace_base;
2862 2867
2863 uint64_t klass_encoding_max = UnscaledClassSpaceMax << LogKlassAlignmentInBytes; 2868 uint64_t klass_encoding_max = UnscaledClassSpaceMax << LogKlassAlignmentInBytes;
2864 // If compressed class space fits in lower 32G, we don't need a base. 2869 // If compressed class space fits in lower 32G, we don't need a base.
2865 if (higher_address <= (address)klass_encoding_max) { 2870 if (higher_address <= (address)klass_encoding_max) {
2866 lower_base = 0; // effectively lower base is zero. 2871 lower_base = 0; // Effectively lower base is zero.
2867 } 2872 }
2868 } 2873 }
2869 2874
2870 Universe::set_narrow_klass_base(lower_base); 2875 Universe::set_narrow_klass_base(lower_base);
2871 2876
3272 void Metaspace::deallocate(MetaWord* ptr, size_t word_size, bool is_class) { 3277 void Metaspace::deallocate(MetaWord* ptr, size_t word_size, bool is_class) {
3273 if (SafepointSynchronize::is_at_safepoint()) { 3278 if (SafepointSynchronize::is_at_safepoint()) {
3274 assert(Thread::current()->is_VM_thread(), "should be the VM thread"); 3279 assert(Thread::current()->is_VM_thread(), "should be the VM thread");
3275 // Don't take Heap_lock 3280 // Don't take Heap_lock
3276 MutexLockerEx ml(vsm()->lock(), Mutex::_no_safepoint_check_flag); 3281 MutexLockerEx ml(vsm()->lock(), Mutex::_no_safepoint_check_flag);
3277 if (word_size < TreeChunk<Metablock, FreeList>::min_size()) { 3282 if (word_size < TreeChunk<Metablock, FreeList<Metablock> >::min_size()) {
3278 // Dark matter. Too small for dictionary. 3283 // Dark matter. Too small for dictionary.
3279 #ifdef ASSERT 3284 #ifdef ASSERT
3280 Copy::fill_to_words((HeapWord*)ptr, word_size, 0xf5f5f5f5); 3285 Copy::fill_to_words((HeapWord*)ptr, word_size, 0xf5f5f5f5);
3281 #endif 3286 #endif
3282 return; 3287 return;
3287 vsm()->deallocate(ptr, word_size); 3292 vsm()->deallocate(ptr, word_size);
3288 } 3293 }
3289 } else { 3294 } else {
3290 MutexLockerEx ml(vsm()->lock(), Mutex::_no_safepoint_check_flag); 3295 MutexLockerEx ml(vsm()->lock(), Mutex::_no_safepoint_check_flag);
3291 3296
3292 if (word_size < TreeChunk<Metablock, FreeList>::min_size()) { 3297 if (word_size < TreeChunk<Metablock, FreeList<Metablock> >::min_size()) {
3293 // Dark matter. Too small for dictionary. 3298 // Dark matter. Too small for dictionary.
3294 #ifdef ASSERT 3299 #ifdef ASSERT
3295 Copy::fill_to_words((HeapWord*)ptr, word_size, 0xf5f5f5f5); 3300 Copy::fill_to_words((HeapWord*)ptr, word_size, 0xf5f5f5f5);
3296 #endif 3301 #endif
3297 return; 3302 return;
3461 class_vsm()->print_on(out); 3466 class_vsm()->print_on(out);
3462 } 3467 }
3463 } 3468 }
3464 } 3469 }
3465 3470
3466 bool Metaspace::contains(const void * ptr) { 3471 bool Metaspace::contains(const void* ptr) {
3467 if (MetaspaceShared::is_in_shared_space(ptr)) { 3472 if (vsm()->contains(ptr)) return true;
3468 return true; 3473 if (using_class_space()) {
3469 } 3474 return class_vsm()->contains(ptr);
3470 // This is checked while unlocked. As long as the virtualspaces are added 3475 }
3471 // at the end, the pointer will be in one of them. The virtual spaces 3476 return false;
3472 // aren't deleted presently. When they are, some sort of locking might
3473 // be needed. Note, locking this can cause inversion problems with the
3474 // caller in MetaspaceObj::is_metadata() function.
3475 return space_list()->contains(ptr) ||
3476 (using_class_space() && class_space_list()->contains(ptr));
3477 } 3477 }
3478 3478
3479 void Metaspace::verify() { 3479 void Metaspace::verify() {
3480 vsm()->verify(); 3480 vsm()->verify();
3481 if (using_class_space()) { 3481 if (using_class_space()) {