1.1 --- a/src/share/vm/memory/metaspace.cpp Fri Sep 20 11:00:38 2013 +0200 1.2 +++ b/src/share/vm/memory/metaspace.cpp Sat Sep 21 10:09:42 2013 +0200 1.3 @@ -23,6 +23,7 @@ 1.4 */ 1.5 #include "precompiled.hpp" 1.6 #include "gc_interface/collectedHeap.hpp" 1.7 +#include "memory/allocation.hpp" 1.8 #include "memory/binaryTreeDictionary.hpp" 1.9 #include "memory/freeList.hpp" 1.10 #include "memory/collectorPolicy.hpp" 1.11 @@ -111,7 +112,7 @@ 1.12 // Has three lists of free chunks, and a total size and 1.13 // count that includes all three 1.14 1.15 -class ChunkManager VALUE_OBJ_CLASS_SPEC { 1.16 +class ChunkManager : public CHeapObj<mtInternal> { 1.17 1.18 // Free list of chunks of different sizes. 1.19 // SpecializedChunk 1.20 @@ -158,7 +159,12 @@ 1.21 1.22 public: 1.23 1.24 - ChunkManager() : _free_chunks_total(0), _free_chunks_count(0) {} 1.25 + ChunkManager(size_t specialized_size, size_t small_size, size_t medium_size) 1.26 + : _free_chunks_total(0), _free_chunks_count(0) { 1.27 + _free_chunks[SpecializedIndex].set_size(specialized_size); 1.28 + _free_chunks[SmallIndex].set_size(small_size); 1.29 + _free_chunks[MediumIndex].set_size(medium_size); 1.30 + } 1.31 1.32 // add or delete (return) a chunk to the global freelist. 1.33 Metachunk* chunk_freelist_allocate(size_t word_size); 1.34 @@ -219,7 +225,7 @@ 1.35 void locked_print_free_chunks(outputStream* st); 1.36 void locked_print_sum_free_chunks(outputStream* st); 1.37 1.38 - void print_on(outputStream* st); 1.39 + void print_on(outputStream* st) const; 1.40 }; 1.41 1.42 // Used to manage the free list of Metablocks (a block corresponds 1.43 @@ -276,11 +282,6 @@ 1.44 // VirtualSpace 1.45 Metachunk* first_chunk() { return (Metachunk*) bottom(); } 1.46 1.47 - void inc_container_count(); 1.48 -#ifdef ASSERT 1.49 - uint container_count_slow(); 1.50 -#endif 1.51 - 1.52 public: 1.53 1.54 VirtualSpaceNode(size_t byte_size); 1.55 @@ -314,8 +315,10 @@ 1.56 void inc_top(size_t word_size) { _top += word_size; } 1.57 1.58 uintx container_count() { return _container_count; } 1.59 + void inc_container_count(); 1.60 void dec_container_count(); 1.61 #ifdef ASSERT 1.62 + uint container_count_slow(); 1.63 void verify_container_count(); 1.64 #endif 1.65 1.66 @@ -421,8 +424,6 @@ 1.67 VirtualSpaceNode* _virtual_space_list; 1.68 // virtual space currently being used for allocations 1.69 VirtualSpaceNode* _current_virtual_space; 1.70 - // Free chunk list for all other metadata 1.71 - ChunkManager _chunk_manager; 1.72 1.73 // Can this virtual list allocate >1 spaces? Also, used to determine 1.74 // whether to allocate unlimited small chunks in this virtual space 1.75 @@ -475,7 +476,6 @@ 1.76 return _current_virtual_space; 1.77 } 1.78 1.79 - ChunkManager* chunk_manager() { return &_chunk_manager; } 1.80 bool is_class() const { return _is_class; } 1.81 1.82 // Allocate the first virtualspace. 1.83 @@ -494,14 +494,7 @@ 1.84 void dec_virtual_space_count(); 1.85 1.86 // Unlink empty VirtualSpaceNodes and free it. 1.87 - void purge(); 1.88 - 1.89 - // Used and capacity in the entire list of virtual spaces. 1.90 - // These are global values shared by all Metaspaces 1.91 - size_t capacity_words_sum(); 1.92 - size_t capacity_bytes_sum() { return capacity_words_sum() * BytesPerWord; } 1.93 - size_t used_words_sum(); 1.94 - size_t used_bytes_sum() { return used_words_sum() * BytesPerWord; } 1.95 + void purge(ChunkManager* chunk_manager); 1.96 1.97 bool contains(const void *ptr); 1.98 1.99 @@ -582,18 +575,12 @@ 1.100 // Type of metadata allocated. 1.101 Metaspace::MetadataType _mdtype; 1.102 1.103 - // Chunk related size 1.104 - size_t _medium_chunk_bunch; 1.105 - 1.106 // List of chunks in use by this SpaceManager. Allocations 1.107 // are done from the current chunk. The list is used for deallocating 1.108 // chunks when the SpaceManager is freed. 1.109 Metachunk* _chunks_in_use[NumberOfInUseLists]; 1.110 Metachunk* _current_chunk; 1.111 1.112 - // Virtual space where allocation comes from. 1.113 - VirtualSpaceList* _vs_list; 1.114 - 1.115 // Number of small chunks to allocate to a manager 1.116 // If class space manager, small chunks are unlimited 1.117 static uint const _small_chunk_limit; 1.118 @@ -626,7 +613,9 @@ 1.119 } 1.120 1.121 Metaspace::MetadataType mdtype() { return _mdtype; } 1.122 - VirtualSpaceList* vs_list() const { return _vs_list; } 1.123 + 1.124 + VirtualSpaceList* vs_list() const { return Metaspace::get_space_list(_mdtype); } 1.125 + ChunkManager* chunk_manager() const { return Metaspace::get_chunk_manager(_mdtype); } 1.126 1.127 Metachunk* current_chunk() const { return _current_chunk; } 1.128 void set_current_chunk(Metachunk* v) { 1.129 @@ -648,18 +637,19 @@ 1.130 1.131 public: 1.132 SpaceManager(Metaspace::MetadataType mdtype, 1.133 - Mutex* lock, 1.134 - VirtualSpaceList* vs_list); 1.135 + Mutex* lock); 1.136 ~SpaceManager(); 1.137 1.138 enum ChunkMultiples { 1.139 MediumChunkMultiple = 4 1.140 }; 1.141 1.142 + bool is_class() { return _mdtype == Metaspace::ClassType; } 1.143 + 1.144 // Accessors 1.145 size_t specialized_chunk_size() { return SpecializedChunk; } 1.146 - size_t small_chunk_size() { return (size_t) vs_list()->is_class() ? ClassSmallChunk : SmallChunk; } 1.147 - size_t medium_chunk_size() { return (size_t) vs_list()->is_class() ? ClassMediumChunk : MediumChunk; } 1.148 + size_t small_chunk_size() { return (size_t) is_class() ? ClassSmallChunk : SmallChunk; } 1.149 + size_t medium_chunk_size() { return (size_t) is_class() ? ClassMediumChunk : MediumChunk; } 1.150 size_t medium_chunk_bunch() { return medium_chunk_size() * MediumChunkMultiple; } 1.151 1.152 size_t allocated_blocks_words() const { return _allocated_blocks_words; } 1.153 @@ -762,7 +752,7 @@ 1.154 _container_count++; 1.155 assert(_container_count == container_count_slow(), 1.156 err_msg("Inconsistency in countainer_count _container_count " SIZE_FORMAT 1.157 - "container_count_slow() " SIZE_FORMAT, 1.158 + " container_count_slow() " SIZE_FORMAT, 1.159 _container_count, container_count_slow())); 1.160 } 1.161 1.162 @@ -775,7 +765,7 @@ 1.163 void VirtualSpaceNode::verify_container_count() { 1.164 assert(_container_count == container_count_slow(), 1.165 err_msg("Inconsistency in countainer_count _container_count " SIZE_FORMAT 1.166 - "container_count_slow() " SIZE_FORMAT, _container_count, container_count_slow())); 1.167 + " container_count_slow() " SIZE_FORMAT, _container_count, container_count_slow())); 1.168 } 1.169 #endif 1.170 1.171 @@ -1020,7 +1010,7 @@ 1.172 // Walk the list of VirtualSpaceNodes and delete 1.173 // nodes with a 0 container_count. Remove Metachunks in 1.174 // the node from their respective freelists. 1.175 -void VirtualSpaceList::purge() { 1.176 +void VirtualSpaceList::purge(ChunkManager* chunk_manager) { 1.177 assert_lock_strong(SpaceManager::expand_lock()); 1.178 // Don't use a VirtualSpaceListIterator because this 1.179 // list is being changed and a straightforward use of an iterator is not safe. 1.180 @@ -1042,7 +1032,7 @@ 1.181 prev_vsl->set_next(vsl->next()); 1.182 } 1.183 1.184 - vsl->purge(chunk_manager()); 1.185 + vsl->purge(chunk_manager); 1.186 dec_reserved_words(vsl->reserved_words()); 1.187 dec_committed_words(vsl->committed_words()); 1.188 dec_virtual_space_count(); 1.189 @@ -1064,36 +1054,6 @@ 1.190 #endif 1.191 } 1.192 1.193 -size_t VirtualSpaceList::used_words_sum() { 1.194 - size_t allocated_by_vs = 0; 1.195 - VirtualSpaceListIterator iter(virtual_space_list()); 1.196 - while (iter.repeat()) { 1.197 - VirtualSpaceNode* vsl = iter.get_next(); 1.198 - // Sum used region [bottom, top) in each virtualspace 1.199 - allocated_by_vs += vsl->used_words_in_vs(); 1.200 - } 1.201 - assert(allocated_by_vs >= chunk_manager()->free_chunks_total_words(), 1.202 - err_msg("Total in free chunks " SIZE_FORMAT 1.203 - " greater than total from virtual_spaces " SIZE_FORMAT, 1.204 - allocated_by_vs, chunk_manager()->free_chunks_total_words())); 1.205 - size_t used = 1.206 - allocated_by_vs - chunk_manager()->free_chunks_total_words(); 1.207 - return used; 1.208 -} 1.209 - 1.210 -// Space available in all MetadataVirtualspaces allocated 1.211 -// for metadata. This is the upper limit on the capacity 1.212 -// of chunks allocated out of all the MetadataVirtualspaces. 1.213 -size_t VirtualSpaceList::capacity_words_sum() { 1.214 - size_t capacity = 0; 1.215 - VirtualSpaceListIterator iter(virtual_space_list()); 1.216 - while (iter.repeat()) { 1.217 - VirtualSpaceNode* vsl = iter.get_next(); 1.218 - capacity += vsl->capacity_words_in_vs(); 1.219 - } 1.220 - return capacity; 1.221 -} 1.222 - 1.223 VirtualSpaceList::VirtualSpaceList(size_t word_size ) : 1.224 _is_class(false), 1.225 _virtual_space_list(NULL), 1.226 @@ -1104,10 +1064,6 @@ 1.227 MutexLockerEx cl(SpaceManager::expand_lock(), 1.228 Mutex::_no_safepoint_check_flag); 1.229 bool initialization_succeeded = grow_vs(word_size); 1.230 - 1.231 - _chunk_manager.free_chunks(SpecializedIndex)->set_size(SpecializedChunk); 1.232 - _chunk_manager.free_chunks(SmallIndex)->set_size(SmallChunk); 1.233 - _chunk_manager.free_chunks(MediumIndex)->set_size(MediumChunk); 1.234 assert(initialization_succeeded, 1.235 " VirtualSpaceList initialization should not fail"); 1.236 } 1.237 @@ -1123,9 +1079,6 @@ 1.238 Mutex::_no_safepoint_check_flag); 1.239 VirtualSpaceNode* class_entry = new VirtualSpaceNode(rs); 1.240 bool succeeded = class_entry->initialize(); 1.241 - _chunk_manager.free_chunks(SpecializedIndex)->set_size(SpecializedChunk); 1.242 - _chunk_manager.free_chunks(SmallIndex)->set_size(ClassSmallChunk); 1.243 - _chunk_manager.free_chunks(MediumIndex)->set_size(ClassMediumChunk); 1.244 assert(succeeded, " VirtualSpaceList initialization should not fail"); 1.245 link_vs(class_entry); 1.246 } 1.247 @@ -1195,15 +1148,8 @@ 1.248 size_t grow_chunks_by_words, 1.249 size_t medium_chunk_bunch) { 1.250 1.251 - // Get a chunk from the chunk freelist 1.252 - Metachunk* next = chunk_manager()->chunk_freelist_allocate(grow_chunks_by_words); 1.253 - 1.254 - if (next != NULL) { 1.255 - next->container()->inc_container_count(); 1.256 - } else { 1.257 - // Allocate a chunk out of the current virtual space. 1.258 - next = current_virtual_space()->get_chunk_vs(grow_chunks_by_words); 1.259 - } 1.260 + // Allocate a chunk out of the current virtual space. 1.261 + Metachunk* next = current_virtual_space()->get_chunk_vs(grow_chunks_by_words); 1.262 1.263 if (next == NULL) { 1.264 // Not enough room in current virtual space. Try to commit 1.265 @@ -1537,15 +1483,15 @@ 1.266 if (dummy_chunk == NULL) { 1.267 break; 1.268 } 1.269 - vsl->chunk_manager()->chunk_freelist_deallocate(dummy_chunk); 1.270 + sm->chunk_manager()->chunk_freelist_deallocate(dummy_chunk); 1.271 1.272 if (TraceMetadataChunkAllocation && Verbose) { 1.273 gclog_or_tty->print("Metadebug::deallocate_chunk_a_lot: %d) ", 1.274 sm->sum_count_in_chunks_in_use()); 1.275 dummy_chunk->print_on(gclog_or_tty); 1.276 gclog_or_tty->print_cr(" Free chunks total %d count %d", 1.277 - vsl->chunk_manager()->free_chunks_total_words(), 1.278 - vsl->chunk_manager()->free_chunks_count()); 1.279 + sm->chunk_manager()->free_chunks_total_words(), 1.280 + sm->chunk_manager()->free_chunks_count()); 1.281 } 1.282 } 1.283 } else { 1.284 @@ -1797,6 +1743,8 @@ 1.285 // work. 1.286 chunk->set_is_free(false); 1.287 #endif 1.288 + chunk->container()->inc_container_count(); 1.289 + 1.290 slow_locked_verify(); 1.291 return chunk; 1.292 } 1.293 @@ -1831,9 +1779,9 @@ 1.294 return chunk; 1.295 } 1.296 1.297 -void ChunkManager::print_on(outputStream* out) { 1.298 +void ChunkManager::print_on(outputStream* out) const { 1.299 if (PrintFLSStatistics != 0) { 1.300 - humongous_dictionary()->report_statistics(); 1.301 + const_cast<ChunkManager *>(this)->humongous_dictionary()->report_statistics(); 1.302 } 1.303 } 1.304 1.305 @@ -1980,8 +1928,8 @@ 1.306 } 1.307 } 1.308 1.309 - vs_list()->chunk_manager()->locked_print_free_chunks(st); 1.310 - vs_list()->chunk_manager()->locked_print_sum_free_chunks(st); 1.311 + chunk_manager()->locked_print_free_chunks(st); 1.312 + chunk_manager()->locked_print_sum_free_chunks(st); 1.313 } 1.314 1.315 size_t SpaceManager::calc_chunk_size(size_t word_size) { 1.316 @@ -2085,9 +2033,7 @@ 1.317 } 1.318 1.319 SpaceManager::SpaceManager(Metaspace::MetadataType mdtype, 1.320 - Mutex* lock, 1.321 - VirtualSpaceList* vs_list) : 1.322 - _vs_list(vs_list), 1.323 + Mutex* lock) : 1.324 _mdtype(mdtype), 1.325 _allocated_blocks_words(0), 1.326 _allocated_chunks_words(0), 1.327 @@ -2173,9 +2119,7 @@ 1.328 MutexLockerEx fcl(SpaceManager::expand_lock(), 1.329 Mutex::_no_safepoint_check_flag); 1.330 1.331 - ChunkManager* chunk_manager = vs_list()->chunk_manager(); 1.332 - 1.333 - chunk_manager->slow_locked_verify(); 1.334 + chunk_manager()->slow_locked_verify(); 1.335 1.336 dec_total_from_size_metrics(); 1.337 1.338 @@ -2189,8 +2133,8 @@ 1.339 1.340 // Have to update before the chunks_in_use lists are emptied 1.341 // below. 1.342 - chunk_manager->inc_free_chunks_total(allocated_chunks_words(), 1.343 - sum_count_in_chunks_in_use()); 1.344 + chunk_manager()->inc_free_chunks_total(allocated_chunks_words(), 1.345 + sum_count_in_chunks_in_use()); 1.346 1.347 // Add all the chunks in use by this space manager 1.348 // to the global list of free chunks. 1.349 @@ -2205,11 +2149,11 @@ 1.350 chunk_size_name(i)); 1.351 } 1.352 Metachunk* chunks = chunks_in_use(i); 1.353 - chunk_manager->return_chunks(i, chunks); 1.354 + chunk_manager()->return_chunks(i, chunks); 1.355 set_chunks_in_use(i, NULL); 1.356 if (TraceMetadataChunkAllocation && Verbose) { 1.357 gclog_or_tty->print_cr("updated freelist count %d %s", 1.358 - chunk_manager->free_chunks(i)->count(), 1.359 + chunk_manager()->free_chunks(i)->count(), 1.360 chunk_size_name(i)); 1.361 } 1.362 assert(i != HumongousIndex, "Humongous chunks are handled explicitly later"); 1.363 @@ -2246,16 +2190,16 @@ 1.364 humongous_chunks->word_size(), HumongousChunkGranularity)); 1.365 Metachunk* next_humongous_chunks = humongous_chunks->next(); 1.366 humongous_chunks->container()->dec_container_count(); 1.367 - chunk_manager->humongous_dictionary()->return_chunk(humongous_chunks); 1.368 + chunk_manager()->humongous_dictionary()->return_chunk(humongous_chunks); 1.369 humongous_chunks = next_humongous_chunks; 1.370 } 1.371 if (TraceMetadataChunkAllocation && Verbose) { 1.372 gclog_or_tty->print_cr(""); 1.373 gclog_or_tty->print_cr("updated dictionary count %d %s", 1.374 - chunk_manager->humongous_dictionary()->total_count(), 1.375 + chunk_manager()->humongous_dictionary()->total_count(), 1.376 chunk_size_name(HumongousIndex)); 1.377 } 1.378 - chunk_manager->slow_locked_verify(); 1.379 + chunk_manager()->slow_locked_verify(); 1.380 } 1.381 1.382 const char* SpaceManager::chunk_size_name(ChunkIndex index) const { 1.383 @@ -2344,9 +2288,7 @@ 1.384 gclog_or_tty->print("SpaceManager::add_chunk: %d) ", 1.385 sum_count_in_chunks_in_use()); 1.386 new_chunk->print_on(gclog_or_tty); 1.387 - if (vs_list() != NULL) { 1.388 - vs_list()->chunk_manager()->locked_print_free_chunks(gclog_or_tty); 1.389 - } 1.390 + chunk_manager()->locked_print_free_chunks(gclog_or_tty); 1.391 } 1.392 } 1.393 1.394 @@ -2362,10 +2304,14 @@ 1.395 1.396 Metachunk* SpaceManager::get_new_chunk(size_t word_size, 1.397 size_t grow_chunks_by_words) { 1.398 - 1.399 - Metachunk* next = vs_list()->get_new_chunk(word_size, 1.400 - grow_chunks_by_words, 1.401 - medium_chunk_bunch()); 1.402 + // Get a chunk from the chunk freelist 1.403 + Metachunk* next = chunk_manager()->chunk_freelist_allocate(grow_chunks_by_words); 1.404 + 1.405 + if (next == NULL) { 1.406 + next = vs_list()->get_new_chunk(word_size, 1.407 + grow_chunks_by_words, 1.408 + medium_chunk_bunch()); 1.409 + } 1.410 1.411 if (TraceMetadataHumongousAllocation && next != NULL && 1.412 SpaceManager::is_humongous(next->word_size())) { 1.413 @@ -2645,13 +2591,12 @@ 1.414 size_t MetaspaceAux::min_chunk_size_words() { return Metaspace::first_chunk_word_size(); } 1.415 1.416 size_t MetaspaceAux::free_chunks_total_words(Metaspace::MetadataType mdtype) { 1.417 - VirtualSpaceList* list = Metaspace::get_space_list(mdtype); 1.418 - if (list == NULL) { 1.419 + ChunkManager* chunk_manager = Metaspace::get_chunk_manager(mdtype); 1.420 + if (chunk_manager == NULL) { 1.421 return 0; 1.422 } 1.423 - ChunkManager* chunk = list->chunk_manager(); 1.424 - chunk->slow_verify(); 1.425 - return chunk->free_chunks_total_words(); 1.426 + chunk_manager->slow_verify(); 1.427 + return chunk_manager->free_chunks_total_words(); 1.428 } 1.429 1.430 size_t MetaspaceAux::free_chunks_total_bytes(Metaspace::MetadataType mdtype) { 1.431 @@ -2802,9 +2747,9 @@ 1.432 } 1.433 1.434 void MetaspaceAux::verify_free_chunks() { 1.435 - Metaspace::space_list()->chunk_manager()->verify(); 1.436 + Metaspace::chunk_manager_metadata()->verify(); 1.437 if (Metaspace::using_class_space()) { 1.438 - Metaspace::class_space_list()->chunk_manager()->verify(); 1.439 + Metaspace::chunk_manager_class()->verify(); 1.440 } 1.441 } 1.442 1.443 @@ -2875,6 +2820,9 @@ 1.444 VirtualSpaceList* Metaspace::_space_list = NULL; 1.445 VirtualSpaceList* Metaspace::_class_space_list = NULL; 1.446 1.447 +ChunkManager* Metaspace::_chunk_manager_metadata = NULL; 1.448 +ChunkManager* Metaspace::_chunk_manager_class = NULL; 1.449 + 1.450 #define VIRTUALSPACEMULTIPLIER 2 1.451 1.452 #ifdef _LP64 1.453 @@ -2982,6 +2930,7 @@ 1.454 err_msg(SIZE_FORMAT " != " UINTX_FORMAT, rs.size(), CompressedClassSpaceSize)); 1.455 assert(using_class_space(), "Must be using class space"); 1.456 _class_space_list = new VirtualSpaceList(rs); 1.457 + _chunk_manager_class = new ChunkManager(SpecializedChunk, ClassSmallChunk, ClassMediumChunk); 1.458 } 1.459 1.460 #endif 1.461 @@ -3007,6 +2956,7 @@ 1.462 // remainder is the misc code and data chunks. 1.463 cds_total = FileMapInfo::shared_spaces_size(); 1.464 _space_list = new VirtualSpaceList(cds_total/wordSize); 1.465 + _chunk_manager_metadata = new ChunkManager(SpecializedChunk, SmallChunk, MediumChunk); 1.466 1.467 #ifdef _LP64 1.468 // Set the compressed klass pointer base so that decoding of these pointers works 1.469 @@ -3074,15 +3024,30 @@ 1.470 size_t word_size = VIRTUALSPACEMULTIPLIER * first_chunk_word_size(); 1.471 // Initialize the list of virtual spaces. 1.472 _space_list = new VirtualSpaceList(word_size); 1.473 + _chunk_manager_metadata = new ChunkManager(SpecializedChunk, SmallChunk, MediumChunk); 1.474 } 1.475 } 1.476 1.477 +Metachunk* Metaspace::get_initialization_chunk(MetadataType mdtype, 1.478 + size_t chunk_word_size, 1.479 + size_t chunk_bunch) { 1.480 + // Get a chunk from the chunk freelist 1.481 + Metachunk* chunk = get_chunk_manager(mdtype)->chunk_freelist_allocate(chunk_word_size); 1.482 + if (chunk != NULL) { 1.483 + return chunk; 1.484 + } 1.485 + 1.486 + return get_space_list(mdtype)->get_initialization_chunk(chunk_word_size, chunk_bunch); 1.487 +} 1.488 + 1.489 void Metaspace::initialize(Mutex* lock, MetaspaceType type) { 1.490 1.491 assert(space_list() != NULL, 1.492 "Metadata VirtualSpaceList has not been initialized"); 1.493 - 1.494 - _vsm = new SpaceManager(NonClassType, lock, space_list()); 1.495 + assert(chunk_manager_metadata() != NULL, 1.496 + "Metadata ChunkManager has not been initialized"); 1.497 + 1.498 + _vsm = new SpaceManager(NonClassType, lock); 1.499 if (_vsm == NULL) { 1.500 return; 1.501 } 1.502 @@ -3091,11 +3056,13 @@ 1.503 vsm()->get_initial_chunk_sizes(type, &word_size, &class_word_size); 1.504 1.505 if (using_class_space()) { 1.506 - assert(class_space_list() != NULL, 1.507 - "Class VirtualSpaceList has not been initialized"); 1.508 + assert(class_space_list() != NULL, 1.509 + "Class VirtualSpaceList has not been initialized"); 1.510 + assert(chunk_manager_class() != NULL, 1.511 + "Class ChunkManager has not been initialized"); 1.512 1.513 // Allocate SpaceManager for classes. 1.514 - _class_vsm = new SpaceManager(ClassType, lock, class_space_list()); 1.515 + _class_vsm = new SpaceManager(ClassType, lock); 1.516 if (_class_vsm == NULL) { 1.517 return; 1.518 } 1.519 @@ -3104,9 +3071,9 @@ 1.520 MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag); 1.521 1.522 // Allocate chunk for metadata objects 1.523 - Metachunk* new_chunk = 1.524 - space_list()->get_initialization_chunk(word_size, 1.525 - vsm()->medium_chunk_bunch()); 1.526 + Metachunk* new_chunk = get_initialization_chunk(NonClassType, 1.527 + word_size, 1.528 + vsm()->medium_chunk_bunch()); 1.529 assert(!DumpSharedSpaces || new_chunk != NULL, "should have enough space for both chunks"); 1.530 if (new_chunk != NULL) { 1.531 // Add to this manager's list of chunks in use and current_chunk(). 1.532 @@ -3115,9 +3082,9 @@ 1.533 1.534 // Allocate chunk for class metadata objects 1.535 if (using_class_space()) { 1.536 - Metachunk* class_chunk = 1.537 - class_space_list()->get_initialization_chunk(class_word_size, 1.538 - class_vsm()->medium_chunk_bunch()); 1.539 + Metachunk* class_chunk = get_initialization_chunk(ClassType, 1.540 + class_word_size, 1.541 + class_vsm()->medium_chunk_bunch()); 1.542 if (class_chunk != NULL) { 1.543 class_vsm()->add_chunk(class_chunk, true); 1.544 } 1.545 @@ -3334,12 +3301,16 @@ 1.546 } 1.547 } 1.548 1.549 +void Metaspace::purge(MetadataType mdtype) { 1.550 + get_space_list(mdtype)->purge(get_chunk_manager(mdtype)); 1.551 +} 1.552 + 1.553 void Metaspace::purge() { 1.554 MutexLockerEx cl(SpaceManager::expand_lock(), 1.555 Mutex::_no_safepoint_check_flag); 1.556 - space_list()->purge(); 1.557 + purge(NonClassType); 1.558 if (using_class_space()) { 1.559 - class_space_list()->purge(); 1.560 + purge(ClassType); 1.561 } 1.562 } 1.563