< prev index next >

src/share/vm/memory/metaspace.cpp

Print this page




 774     assert(raw_word_size * BytesPerWord == raw_bytes_size, "Size problem");
 775 
 776     return raw_word_size;
 777   }
 778 };
 779 
 780 uint const SpaceManager::_small_chunk_limit = 4;
 781 
 782 const char* SpaceManager::_expand_lock_name =
 783   "SpaceManager chunk allocation lock";
 784 const int SpaceManager::_expand_lock_rank = Monitor::leaf - 1;
 785 Mutex* const SpaceManager::_expand_lock =
 786   new Mutex(SpaceManager::_expand_lock_rank,
 787             SpaceManager::_expand_lock_name,
 788             Mutex::_allow_vm_block_flag,
 789             Monitor::_safepoint_check_never);
 790 
 791 void VirtualSpaceNode::inc_container_count() {
 792   assert_lock_strong(SpaceManager::expand_lock());
 793   _container_count++;
 794   DEBUG_ONLY(verify_container_count();)
 795 }
 796 
 797 void VirtualSpaceNode::dec_container_count() {
 798   assert_lock_strong(SpaceManager::expand_lock());
 799   _container_count--;
 800 }
 801 
 802 #ifdef ASSERT
 803 void VirtualSpaceNode::verify_container_count() {
 804   assert(_container_count == container_count_slow(),
 805          "Inconsistency in container_count _container_count " UINTX_FORMAT
 806          " container_count_slow() " UINTX_FORMAT, _container_count, container_count_slow());
 807 }
 808 #endif
 809 
 810 // BlockFreelist methods
 811 
 812 BlockFreelist::BlockFreelist() : _dictionary(new BlockTreeDictionary()) {}
 813 
 814 BlockFreelist::~BlockFreelist() {


1056     humongous_dictionary()->remove_chunk(chunk);
1057   }
1058 
1059   // Chunk is being removed from the chunks free list.
1060   dec_free_chunks_total(chunk->word_size());
1061 }
1062 
1063 // Walk the list of VirtualSpaceNodes and delete
1064 // nodes with a 0 container_count.  Remove Metachunks in
1065 // the node from their respective freelists.
1066 void VirtualSpaceList::purge(ChunkManager* chunk_manager) {
1067   assert(SafepointSynchronize::is_at_safepoint(), "must be called at safepoint for contains to work");
1068   assert_lock_strong(SpaceManager::expand_lock());
1069   // Don't use a VirtualSpaceListIterator because this
1070   // list is being changed and a straightforward use of an iterator is not safe.
1071   VirtualSpaceNode* purged_vsl = NULL;
1072   VirtualSpaceNode* prev_vsl = virtual_space_list();
1073   VirtualSpaceNode* next_vsl = prev_vsl;
1074   while (next_vsl != NULL) {
1075     VirtualSpaceNode* vsl = next_vsl;

1076     next_vsl = vsl->next();
1077     // Don't free the current virtual space since it will likely
1078     // be needed soon.
1079     if (vsl->container_count() == 0 && vsl != current_virtual_space()) {
1080       // Unlink it from the list
1081       if (prev_vsl == vsl) {
1082         // This is the case of the current node being the first node.
1083         assert(vsl == virtual_space_list(), "Expected to be the first node");
1084         set_virtual_space_list(vsl->next());
1085       } else {
1086         prev_vsl->set_next(vsl->next());
1087       }
1088 
1089       vsl->purge(chunk_manager);
1090       dec_reserved_words(vsl->reserved_words());
1091       dec_committed_words(vsl->committed_words());
1092       dec_virtual_space_count();
1093       purged_vsl = vsl;
1094       delete vsl;
1095     } else {


1120     VirtualSpaceNode* vsn = iter.get_next();
1121     if (vsn->contains(ptr)) {
1122       return true;
1123     }
1124   }
1125   return false;
1126 }
1127 
1128 void VirtualSpaceList::retire_current_virtual_space() {
1129   assert_lock_strong(SpaceManager::expand_lock());
1130 
1131   VirtualSpaceNode* vsn = current_virtual_space();
1132 
1133   ChunkManager* cm = is_class() ? Metaspace::chunk_manager_class() :
1134                                   Metaspace::chunk_manager_metadata();
1135 
1136   vsn->retire(cm);
1137 }
1138 
1139 void VirtualSpaceNode::retire(ChunkManager* chunk_manager) {

1140   for (int i = (int)MediumIndex; i >= (int)ZeroIndex; --i) {
1141     ChunkIndex index = (ChunkIndex)i;
1142     size_t chunk_size = chunk_manager->free_chunks(index)->size();
1143 
1144     while (free_words_in_vs() >= chunk_size) {
1145       DEBUG_ONLY(verify_container_count();)
1146       Metachunk* chunk = get_chunk_vs(chunk_size);
1147       assert(chunk != NULL, "allocation should have been successful");
1148 
1149       chunk_manager->return_chunks(index, chunk);
1150       chunk_manager->inc_free_chunks_total(chunk_size);
1151       DEBUG_ONLY(verify_container_count();)
1152     }

1153   }
1154   assert(free_words_in_vs() == 0, "should be empty now");
1155 }
1156 
1157 VirtualSpaceList::VirtualSpaceList(size_t word_size) :
1158                                    _is_class(false),
1159                                    _virtual_space_list(NULL),
1160                                    _current_virtual_space(NULL),
1161                                    _reserved_words(0),
1162                                    _committed_words(0),
1163                                    _virtual_space_count(0) {
1164   MutexLockerEx cl(SpaceManager::expand_lock(),
1165                    Mutex::_no_safepoint_check_flag);
1166   create_new_virtual_space(word_size);
1167 }
1168 
1169 VirtualSpaceList::VirtualSpaceList(ReservedSpace rs) :
1170                                    _is_class(true),
1171                                    _virtual_space_list(NULL),
1172                                    _current_virtual_space(NULL),




 774     assert(raw_word_size * BytesPerWord == raw_bytes_size, "Size problem");
 775 
 776     return raw_word_size;
 777   }
 778 };
 779 
 780 uint const SpaceManager::_small_chunk_limit = 4;
 781 
 782 const char* SpaceManager::_expand_lock_name =
 783   "SpaceManager chunk allocation lock";
 784 const int SpaceManager::_expand_lock_rank = Monitor::leaf - 1;
 785 Mutex* const SpaceManager::_expand_lock =
 786   new Mutex(SpaceManager::_expand_lock_rank,
 787             SpaceManager::_expand_lock_name,
 788             Mutex::_allow_vm_block_flag,
 789             Monitor::_safepoint_check_never);
 790 
 791 void VirtualSpaceNode::inc_container_count() {
 792   assert_lock_strong(SpaceManager::expand_lock());
 793   _container_count++;

 794 }
 795 
 796 void VirtualSpaceNode::dec_container_count() {
 797   assert_lock_strong(SpaceManager::expand_lock());
 798   _container_count--;
 799 }
 800 
 801 #ifdef ASSERT
 802 void VirtualSpaceNode::verify_container_count() {
 803   assert(_container_count == container_count_slow(),
 804          "Inconsistency in container_count _container_count " UINTX_FORMAT
 805          " container_count_slow() " UINTX_FORMAT, _container_count, container_count_slow());
 806 }
 807 #endif
 808 
 809 // BlockFreelist methods
 810 
 811 BlockFreelist::BlockFreelist() : _dictionary(new BlockTreeDictionary()) {}
 812 
 813 BlockFreelist::~BlockFreelist() {


1055     humongous_dictionary()->remove_chunk(chunk);
1056   }
1057 
1058   // Chunk is being removed from the chunks free list.
1059   dec_free_chunks_total(chunk->word_size());
1060 }
1061 
1062 // Walk the list of VirtualSpaceNodes and delete
1063 // nodes with a 0 container_count.  Remove Metachunks in
1064 // the node from their respective freelists.
1065 void VirtualSpaceList::purge(ChunkManager* chunk_manager) {
1066   assert(SafepointSynchronize::is_at_safepoint(), "must be called at safepoint for contains to work");
1067   assert_lock_strong(SpaceManager::expand_lock());
1068   // Don't use a VirtualSpaceListIterator because this
1069   // list is being changed and a straightforward use of an iterator is not safe.
1070   VirtualSpaceNode* purged_vsl = NULL;
1071   VirtualSpaceNode* prev_vsl = virtual_space_list();
1072   VirtualSpaceNode* next_vsl = prev_vsl;
1073   while (next_vsl != NULL) {
1074     VirtualSpaceNode* vsl = next_vsl;
1075     DEBUG_ONLY(vsl->verify_container_count();)
1076     next_vsl = vsl->next();
1077     // Don't free the current virtual space since it will likely
1078     // be needed soon.
1079     if (vsl->container_count() == 0 && vsl != current_virtual_space()) {
1080       // Unlink it from the list
1081       if (prev_vsl == vsl) {
1082         // This is the case of the current node being the first node.
1083         assert(vsl == virtual_space_list(), "Expected to be the first node");
1084         set_virtual_space_list(vsl->next());
1085       } else {
1086         prev_vsl->set_next(vsl->next());
1087       }
1088 
1089       vsl->purge(chunk_manager);
1090       dec_reserved_words(vsl->reserved_words());
1091       dec_committed_words(vsl->committed_words());
1092       dec_virtual_space_count();
1093       purged_vsl = vsl;
1094       delete vsl;
1095     } else {


1120     VirtualSpaceNode* vsn = iter.get_next();
1121     if (vsn->contains(ptr)) {
1122       return true;
1123     }
1124   }
1125   return false;
1126 }
1127 
1128 void VirtualSpaceList::retire_current_virtual_space() {
1129   assert_lock_strong(SpaceManager::expand_lock());
1130 
1131   VirtualSpaceNode* vsn = current_virtual_space();
1132 
1133   ChunkManager* cm = is_class() ? Metaspace::chunk_manager_class() :
1134                                   Metaspace::chunk_manager_metadata();
1135 
1136   vsn->retire(cm);
1137 }
1138 
1139 void VirtualSpaceNode::retire(ChunkManager* chunk_manager) {
1140   DEBUG_ONLY(verify_container_count();)
1141   for (int i = (int)MediumIndex; i >= (int)ZeroIndex; --i) {
1142     ChunkIndex index = (ChunkIndex)i;
1143     size_t chunk_size = chunk_manager->free_chunks(index)->size();
1144 
1145     while (free_words_in_vs() >= chunk_size) {

1146       Metachunk* chunk = get_chunk_vs(chunk_size);
1147       assert(chunk != NULL, "allocation should have been successful");
1148 
1149       chunk_manager->return_chunks(index, chunk);
1150       chunk_manager->inc_free_chunks_total(chunk_size);

1151     }
1152     DEBUG_ONLY(verify_container_count();)
1153   }
1154   assert(free_words_in_vs() == 0, "should be empty now");
1155 }
1156 
1157 VirtualSpaceList::VirtualSpaceList(size_t word_size) :
1158                                    _is_class(false),
1159                                    _virtual_space_list(NULL),
1160                                    _current_virtual_space(NULL),
1161                                    _reserved_words(0),
1162                                    _committed_words(0),
1163                                    _virtual_space_count(0) {
1164   MutexLockerEx cl(SpaceManager::expand_lock(),
1165                    Mutex::_no_safepoint_check_flag);
1166   create_new_virtual_space(word_size);
1167 }
1168 
1169 VirtualSpaceList::VirtualSpaceList(ReservedSpace rs) :
1170                                    _is_class(true),
1171                                    _virtual_space_list(NULL),
1172                                    _current_virtual_space(NULL),


< prev index next >