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),
|