comparison src/share/vm/memory/metaspace.cpp @ 17935:7384f6a12fc1

8038212: Method::is_valid_method() check has performance regression impact for stackwalking Summary: Only prune metaspace virtual spaces at safepoint so walking them is safe outside a safepoint. Reviewed-by: mgerdin, mgronlun, hseigel, stefank
author coleenp
date Thu, 15 May 2014 18:23:26 -0400
parents 270d7cb38f40
children 78bbf4d43a14
comparison
equal deleted inserted replaced
17934:366c198c896d 17935:7384f6a12fc1
312 312
313 // Convenience functions for logical bottom and end 313 // Convenience functions for logical bottom and end
314 MetaWord* bottom() const { return (MetaWord*) _virtual_space.low(); } 314 MetaWord* bottom() const { return (MetaWord*) _virtual_space.low(); }
315 MetaWord* end() const { return (MetaWord*) _virtual_space.high(); } 315 MetaWord* end() const { return (MetaWord*) _virtual_space.high(); }
316 316
317 bool contains(const void* ptr) { return ptr >= low() && ptr < high(); }
318
317 size_t reserved_words() const { return _virtual_space.reserved_size() / BytesPerWord; } 319 size_t reserved_words() const { return _virtual_space.reserved_size() / BytesPerWord; }
318 size_t committed_words() const { return _virtual_space.actual_committed_size() / BytesPerWord; } 320 size_t committed_words() const { return _virtual_space.actual_committed_size() / BytesPerWord; }
319 321
320 bool is_pre_committed() const { return _virtual_space.special(); } 322 bool is_pre_committed() const { return _virtual_space.special(); }
321 323
553 void inc_committed_words(size_t v); 555 void inc_committed_words(size_t v);
554 void dec_committed_words(size_t v); 556 void dec_committed_words(size_t v);
555 void inc_virtual_space_count(); 557 void inc_virtual_space_count();
556 void dec_virtual_space_count(); 558 void dec_virtual_space_count();
557 559
560 bool contains(const void* ptr);
561
558 // Unlink empty VirtualSpaceNodes and free it. 562 // Unlink empty VirtualSpaceNodes and free it.
559 void purge(ChunkManager* chunk_manager); 563 void purge(ChunkManager* chunk_manager);
560 564
561 void print_on(outputStream* st) const; 565 void print_on(outputStream* st) const;
562 566
637 641
638 private: 642 private:
639 // Accessors 643 // Accessors
640 Metachunk* chunks_in_use(ChunkIndex index) const { return _chunks_in_use[index]; } 644 Metachunk* chunks_in_use(ChunkIndex index) const { return _chunks_in_use[index]; }
641 void set_chunks_in_use(ChunkIndex index, Metachunk* v) { 645 void set_chunks_in_use(ChunkIndex index, Metachunk* v) {
642 // ensure lock-free iteration sees fully initialized node
643 OrderAccess::storestore();
644 _chunks_in_use[index] = v; 646 _chunks_in_use[index] = v;
645 } 647 }
646 648
647 BlockFreelist* block_freelists() const { 649 BlockFreelist* block_freelists() const {
648 return (BlockFreelist*) &_block_freelists; 650 return (BlockFreelist*) &_block_freelists;
753 755
754 void dump(outputStream* const out) const; 756 void dump(outputStream* const out) const;
755 void print_on(outputStream* st) const; 757 void print_on(outputStream* st) const;
756 void locked_print_chunks_in_use_on(outputStream* st) const; 758 void locked_print_chunks_in_use_on(outputStream* st) const;
757 759
758 bool contains(const void *ptr);
759
760 void verify(); 760 void verify();
761 void verify_chunk_size(Metachunk* chunk); 761 void verify_chunk_size(Metachunk* chunk);
762 NOT_PRODUCT(void mangle_freed_chunks();) 762 NOT_PRODUCT(void mangle_freed_chunks();)
763 #ifdef ASSERT 763 #ifdef ASSERT
764 void verify_allocated_blocks_words(); 764 void verify_allocated_blocks_words();
1074 1074
1075 // Walk the list of VirtualSpaceNodes and delete 1075 // Walk the list of VirtualSpaceNodes and delete
1076 // nodes with a 0 container_count. Remove Metachunks in 1076 // nodes with a 0 container_count. Remove Metachunks in
1077 // the node from their respective freelists. 1077 // the node from their respective freelists.
1078 void VirtualSpaceList::purge(ChunkManager* chunk_manager) { 1078 void VirtualSpaceList::purge(ChunkManager* chunk_manager) {
1079 assert(SafepointSynchronize::is_at_safepoint(), "must be called at safepoint for contains to work");
1079 assert_lock_strong(SpaceManager::expand_lock()); 1080 assert_lock_strong(SpaceManager::expand_lock());
1080 // Don't use a VirtualSpaceListIterator because this 1081 // Don't use a VirtualSpaceListIterator because this
1081 // list is being changed and a straightforward use of an iterator is not safe. 1082 // list is being changed and a straightforward use of an iterator is not safe.
1082 VirtualSpaceNode* purged_vsl = NULL; 1083 VirtualSpaceNode* purged_vsl = NULL;
1083 VirtualSpaceNode* prev_vsl = virtual_space_list(); 1084 VirtualSpaceNode* prev_vsl = virtual_space_list();
1107 prev_vsl = vsl; 1108 prev_vsl = vsl;
1108 } 1109 }
1109 } 1110 }
1110 #ifdef ASSERT 1111 #ifdef ASSERT
1111 if (purged_vsl != NULL) { 1112 if (purged_vsl != NULL) {
1112 // List should be stable enough to use an iterator here. 1113 // List should be stable enough to use an iterator here.
1113 VirtualSpaceListIterator iter(virtual_space_list()); 1114 VirtualSpaceListIterator iter(virtual_space_list());
1114 while (iter.repeat()) { 1115 while (iter.repeat()) {
1115 VirtualSpaceNode* vsl = iter.get_next(); 1116 VirtualSpaceNode* vsl = iter.get_next();
1116 assert(vsl != purged_vsl, "Purge of vsl failed"); 1117 assert(vsl != purged_vsl, "Purge of vsl failed");
1117 } 1118 }
1118 } 1119 }
1119 #endif 1120 #endif
1121 }
1122
1123
1124 // This function looks at the mmap regions in the metaspace without locking.
1125 // The chunks are added with store ordering and not deleted except for at
1126 // unloading time during a safepoint.
1127 bool VirtualSpaceList::contains(const void* ptr) {
1128 // List should be stable enough to use an iterator here because removing virtual
1129 // space nodes is only allowed at a safepoint.
1130 VirtualSpaceListIterator iter(virtual_space_list());
1131 while (iter.repeat()) {
1132 VirtualSpaceNode* vsn = iter.get_next();
1133 if (vsn->contains(ptr)) {
1134 return true;
1135 }
1136 }
1137 return false;
1120 } 1138 }
1121 1139
1122 void VirtualSpaceList::retire_current_virtual_space() { 1140 void VirtualSpaceList::retire_current_virtual_space() {
1123 assert_lock_strong(SpaceManager::expand_lock()); 1141 assert_lock_strong(SpaceManager::expand_lock());
1124 1142
1206 delete new_entry; 1224 delete new_entry;
1207 return false; 1225 return false;
1208 } else { 1226 } else {
1209 assert(new_entry->reserved_words() == vs_word_size, 1227 assert(new_entry->reserved_words() == vs_word_size,
1210 "Reserved memory size differs from requested memory size"); 1228 "Reserved memory size differs from requested memory size");
1229 // ensure lock-free iteration sees fully initialized node
1230 OrderAccess::storestore();
1211 link_vs(new_entry); 1231 link_vs(new_entry);
1212 return true; 1232 return true;
1213 } 1233 }
1214 } 1234 }
1215 1235
2429 } 2449 }
2430 2450
2431 return result; 2451 return result;
2432 } 2452 }
2433 2453
2434 // This function looks at the chunks in the metaspace without locking.
2435 // The chunks are added with store ordering and not deleted except for at
2436 // unloading time.
2437 bool SpaceManager::contains(const void *ptr) {
2438 for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i))
2439 {
2440 Metachunk* curr = chunks_in_use(i);
2441 while (curr != NULL) {
2442 if (curr->contains(ptr)) return true;
2443 curr = curr->next();
2444 }
2445 }
2446 return false;
2447 }
2448
2449 void SpaceManager::verify() { 2454 void SpaceManager::verify() {
2450 // If there are blocks in the dictionary, then 2455 // If there are blocks in the dictionary, then
2451 // verfication of chunks does not work since 2456 // verfication of chunks does not work since
2452 // being in the dictionary alters a chunk. 2457 // being in the dictionary alters a chunk.
2453 if (block_freelists()->total_size() == 0) { 2458 if (block_freelists()->total_size() == 0) {
3548 } 3553 }
3549 } 3554 }
3550 } 3555 }
3551 3556
3552 bool Metaspace::contains(const void* ptr) { 3557 bool Metaspace::contains(const void* ptr) {
3553 if (vsm()->contains(ptr)) return true; 3558 if (UseSharedSpaces && MetaspaceShared::is_in_shared_space(ptr)) {
3554 if (using_class_space()) { 3559 return true;
3555 return class_vsm()->contains(ptr); 3560 }
3556 } 3561
3557 return false; 3562 if (using_class_space() && get_space_list(ClassType)->contains(ptr)) {
3563 return true;
3564 }
3565
3566 return get_space_list(NonClassType)->contains(ptr);
3558 } 3567 }
3559 3568
3560 void Metaspace::verify() { 3569 void Metaspace::verify() {
3561 vsm()->verify(); 3570 vsm()->verify();
3562 if (using_class_space()) { 3571 if (using_class_space()) {
3797 3806
3798 void TestVirtualSpaceNode_test() { 3807 void TestVirtualSpaceNode_test() {
3799 TestVirtualSpaceNodeTest::test(); 3808 TestVirtualSpaceNodeTest::test();
3800 TestVirtualSpaceNodeTest::test_is_available(); 3809 TestVirtualSpaceNodeTest::test_is_available();
3801 } 3810 }
3802
3803 #endif 3811 #endif