1720 *class_chunk_word_size = Metaspace::first_class_chunk_word_size();
1721 break;
1722 case Metaspace::ROMetaspaceType:
1723 *chunk_word_size = SharedReadOnlySize / wordSize;
1724 *class_chunk_word_size = ClassSpecializedChunk;
1725 break;
1726 case Metaspace::ReadWriteMetaspaceType:
1727 *chunk_word_size = SharedReadWriteSize / wordSize;
1728 *class_chunk_word_size = ClassSpecializedChunk;
1729 break;
1730 case Metaspace::AnonymousMetaspaceType:
1731 case Metaspace::ReflectionMetaspaceType:
1732 *chunk_word_size = SpecializedChunk;
1733 *class_chunk_word_size = ClassSpecializedChunk;
1734 break;
1735 default:
1736 *chunk_word_size = SmallChunk;
1737 *class_chunk_word_size = ClassSmallChunk;
1738 break;
1739 }
1740 assert(chunk_word_size != 0 && class_chunk_word_size != 0,
1741 err_msg("Initial chunks sizes bad: data " SIZE_FORMAT
1742 " class " SIZE_FORMAT,
1743 chunk_word_size, class_chunk_word_size));
1744 }
1745
1746 size_t SpaceManager::sum_free_in_chunks_in_use() const {
1747 MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag);
1748 size_t free = 0;
1749 for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) {
1750 Metachunk* chunk = chunks_in_use(i);
1751 while (chunk != NULL) {
1752 free += chunk->free_word_size();
1753 chunk = chunk->next();
1754 }
1755 }
1756 return free;
1757 }
1758
1759 size_t SpaceManager::sum_waste_in_chunks_in_use() const {
1760 MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag);
1761 size_t result = 0;
1762 for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) {
1763 result += sum_waste_in_chunks_in_use(i);
2023 sum_count_in_chunks_in_use(HumongousIndex),
2024 chunk_size_name(HumongousIndex));
2025 gclog_or_tty->print("Humongous chunk dictionary: ");
2026 }
2027 // Humongous chunks are never the current chunk.
2028 Metachunk* humongous_chunks = chunks_in_use(HumongousIndex);
2029
2030 while (humongous_chunks != NULL) {
2031 #ifdef ASSERT
2032 humongous_chunks->set_is_free(true);
2033 #endif
2034 if (TraceMetadataChunkAllocation && Verbose) {
2035 gclog_or_tty->print(PTR_FORMAT " (" SIZE_FORMAT ") ",
2036 humongous_chunks,
2037 humongous_chunks->word_size());
2038 }
2039 assert(humongous_chunks->word_size() == (size_t)
2040 align_size_up(humongous_chunks->word_size(),
2041 HumongousChunkGranularity),
2042 err_msg("Humongous chunk size is wrong: word size " SIZE_FORMAT
2043 " granularity " SIZE_FORMAT,
2044 humongous_chunks->word_size(), HumongousChunkGranularity));
2045 Metachunk* next_humongous_chunks = humongous_chunks->next();
2046 chunk_manager->humongous_dictionary()->return_chunk(humongous_chunks);
2047 humongous_chunks = next_humongous_chunks;
2048 }
2049 if (TraceMetadataChunkAllocation && Verbose) {
2050 gclog_or_tty->print_cr("");
2051 gclog_or_tty->print_cr("updated dictionary count %d %s",
2052 chunk_manager->humongous_dictionary()->total_count(),
2053 chunk_size_name(HumongousIndex));
2054 }
2055 set_chunks_in_use(HumongousIndex, NULL);
2056 chunk_manager->slow_locked_verify();
2057 }
2058
2059 const char* SpaceManager::chunk_size_name(ChunkIndex index) const {
2060 switch (index) {
2061 case SpecializedIndex:
2062 return "Specialized";
2063 case SmallIndex:
2247 assert(is_humongous(chunk->word_size()) ||
2248 chunk->word_size() == medium_chunk_size() ||
2249 chunk->word_size() == small_chunk_size() ||
2250 chunk->word_size() == specialized_chunk_size(),
2251 "Chunk size is wrong");
2252 return;
2253 }
2254
2255 #ifdef ASSERT
2256 void SpaceManager::verify_allocation_total() {
2257 // Verification is only guaranteed at a safepoint.
2258 if (SafepointSynchronize::is_at_safepoint()) {
2259 gclog_or_tty->print_cr("Chunk " PTR_FORMAT " allocation_total " SIZE_FORMAT
2260 " sum_used_in_chunks_in_use " SIZE_FORMAT,
2261 this,
2262 allocation_total(),
2263 sum_used_in_chunks_in_use());
2264 }
2265 MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag);
2266 assert(allocation_total() == sum_used_in_chunks_in_use(),
2267 err_msg("allocation total is not consistent %d vs %d",
2268 allocation_total(), sum_used_in_chunks_in_use()));
2269 }
2270
2271 #endif
2272
2273 void SpaceManager::dump(outputStream* const out) const {
2274 size_t curr_total = 0;
2275 size_t waste = 0;
2276 uint i = 0;
2277 size_t used = 0;
2278 size_t capacity = 0;
2279
2280 // Add up statistics for all chunks in this SpaceManager.
2281 for (ChunkIndex index = ZeroIndex;
2282 index < NumberOfInUseLists;
2283 index = next_chunk_index(index)) {
2284 for (Metachunk* curr = chunks_in_use(index);
2285 curr != NULL;
2286 curr = curr->next()) {
2287 out->print("%d) ", i++);
2561 _first_chunk_word_size = align_word_size_up(_first_chunk_word_size);
2562 // Make the first class chunk bigger than a medium chunk so it's not put
2563 // on the medium chunk list. The next chunk will be small and progress
2564 // from there. This size calculated by -version.
2565 _first_class_chunk_word_size = MIN2((size_t)MediumChunk*6,
2566 (ClassMetaspaceSize/BytesPerWord)*2);
2567 _first_class_chunk_word_size = align_word_size_up(_first_class_chunk_word_size);
2568 // Arbitrarily set the initial virtual space to a multiple
2569 // of the boot class loader size.
2570 size_t word_size = VIRTUALSPACEMULTIPLIER * first_chunk_word_size();
2571 // Initialize the list of virtual spaces.
2572 _space_list = new VirtualSpaceList(word_size);
2573 }
2574 }
2575
2576 // For UseCompressedKlassPointers the class space is reserved as a piece of the
2577 // Java heap because the compression algorithm is the same for each. The
2578 // argument passed in is at the top of the compressed space
2579 void Metaspace::initialize_class_space(ReservedSpace rs) {
2580 // The reserved space size may be bigger because of alignment, esp with UseLargePages
2581 assert(rs.size() >= ClassMetaspaceSize, err_msg("%d != %d", rs.size(), ClassMetaspaceSize));
2582 _class_space_list = new VirtualSpaceList(rs);
2583 }
2584
2585 void Metaspace::initialize(Mutex* lock,
2586 MetaspaceType type) {
2587
2588 assert(space_list() != NULL,
2589 "Metadata VirtualSpaceList has not been initialized");
2590
2591 _vsm = new SpaceManager(lock, space_list());
2592 if (_vsm == NULL) {
2593 return;
2594 }
2595 size_t word_size;
2596 size_t class_word_size;
2597 vsm()->get_initial_chunk_sizes(type,
2598 &word_size,
2599 &class_word_size);
2600
2601 assert(class_space_list() != NULL,
|
1720 *class_chunk_word_size = Metaspace::first_class_chunk_word_size();
1721 break;
1722 case Metaspace::ROMetaspaceType:
1723 *chunk_word_size = SharedReadOnlySize / wordSize;
1724 *class_chunk_word_size = ClassSpecializedChunk;
1725 break;
1726 case Metaspace::ReadWriteMetaspaceType:
1727 *chunk_word_size = SharedReadWriteSize / wordSize;
1728 *class_chunk_word_size = ClassSpecializedChunk;
1729 break;
1730 case Metaspace::AnonymousMetaspaceType:
1731 case Metaspace::ReflectionMetaspaceType:
1732 *chunk_word_size = SpecializedChunk;
1733 *class_chunk_word_size = ClassSpecializedChunk;
1734 break;
1735 default:
1736 *chunk_word_size = SmallChunk;
1737 *class_chunk_word_size = ClassSmallChunk;
1738 break;
1739 }
1740 assert(*chunk_word_size != 0 && *class_chunk_word_size != 0,
1741 err_msg("Initial chunks sizes bad: data " SIZE_FORMAT
1742 " class " SIZE_FORMAT,
1743 *chunk_word_size, *class_chunk_word_size));
1744 }
1745
1746 size_t SpaceManager::sum_free_in_chunks_in_use() const {
1747 MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag);
1748 size_t free = 0;
1749 for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) {
1750 Metachunk* chunk = chunks_in_use(i);
1751 while (chunk != NULL) {
1752 free += chunk->free_word_size();
1753 chunk = chunk->next();
1754 }
1755 }
1756 return free;
1757 }
1758
1759 size_t SpaceManager::sum_waste_in_chunks_in_use() const {
1760 MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag);
1761 size_t result = 0;
1762 for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) {
1763 result += sum_waste_in_chunks_in_use(i);
2023 sum_count_in_chunks_in_use(HumongousIndex),
2024 chunk_size_name(HumongousIndex));
2025 gclog_or_tty->print("Humongous chunk dictionary: ");
2026 }
2027 // Humongous chunks are never the current chunk.
2028 Metachunk* humongous_chunks = chunks_in_use(HumongousIndex);
2029
2030 while (humongous_chunks != NULL) {
2031 #ifdef ASSERT
2032 humongous_chunks->set_is_free(true);
2033 #endif
2034 if (TraceMetadataChunkAllocation && Verbose) {
2035 gclog_or_tty->print(PTR_FORMAT " (" SIZE_FORMAT ") ",
2036 humongous_chunks,
2037 humongous_chunks->word_size());
2038 }
2039 assert(humongous_chunks->word_size() == (size_t)
2040 align_size_up(humongous_chunks->word_size(),
2041 HumongousChunkGranularity),
2042 err_msg("Humongous chunk size is wrong: word size " SIZE_FORMAT
2043 " granularity %d",
2044 humongous_chunks->word_size(), HumongousChunkGranularity));
2045 Metachunk* next_humongous_chunks = humongous_chunks->next();
2046 chunk_manager->humongous_dictionary()->return_chunk(humongous_chunks);
2047 humongous_chunks = next_humongous_chunks;
2048 }
2049 if (TraceMetadataChunkAllocation && Verbose) {
2050 gclog_or_tty->print_cr("");
2051 gclog_or_tty->print_cr("updated dictionary count %d %s",
2052 chunk_manager->humongous_dictionary()->total_count(),
2053 chunk_size_name(HumongousIndex));
2054 }
2055 set_chunks_in_use(HumongousIndex, NULL);
2056 chunk_manager->slow_locked_verify();
2057 }
2058
2059 const char* SpaceManager::chunk_size_name(ChunkIndex index) const {
2060 switch (index) {
2061 case SpecializedIndex:
2062 return "Specialized";
2063 case SmallIndex:
2247 assert(is_humongous(chunk->word_size()) ||
2248 chunk->word_size() == medium_chunk_size() ||
2249 chunk->word_size() == small_chunk_size() ||
2250 chunk->word_size() == specialized_chunk_size(),
2251 "Chunk size is wrong");
2252 return;
2253 }
2254
2255 #ifdef ASSERT
2256 void SpaceManager::verify_allocation_total() {
2257 // Verification is only guaranteed at a safepoint.
2258 if (SafepointSynchronize::is_at_safepoint()) {
2259 gclog_or_tty->print_cr("Chunk " PTR_FORMAT " allocation_total " SIZE_FORMAT
2260 " sum_used_in_chunks_in_use " SIZE_FORMAT,
2261 this,
2262 allocation_total(),
2263 sum_used_in_chunks_in_use());
2264 }
2265 MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag);
2266 assert(allocation_total() == sum_used_in_chunks_in_use(),
2267 err_msg("allocation total is not consistent " SIZE_FORMAT
2268 " vs " SIZE_FORMAT,
2269 allocation_total(), sum_used_in_chunks_in_use()));
2270 }
2271
2272 #endif
2273
2274 void SpaceManager::dump(outputStream* const out) const {
2275 size_t curr_total = 0;
2276 size_t waste = 0;
2277 uint i = 0;
2278 size_t used = 0;
2279 size_t capacity = 0;
2280
2281 // Add up statistics for all chunks in this SpaceManager.
2282 for (ChunkIndex index = ZeroIndex;
2283 index < NumberOfInUseLists;
2284 index = next_chunk_index(index)) {
2285 for (Metachunk* curr = chunks_in_use(index);
2286 curr != NULL;
2287 curr = curr->next()) {
2288 out->print("%d) ", i++);
2562 _first_chunk_word_size = align_word_size_up(_first_chunk_word_size);
2563 // Make the first class chunk bigger than a medium chunk so it's not put
2564 // on the medium chunk list. The next chunk will be small and progress
2565 // from there. This size calculated by -version.
2566 _first_class_chunk_word_size = MIN2((size_t)MediumChunk*6,
2567 (ClassMetaspaceSize/BytesPerWord)*2);
2568 _first_class_chunk_word_size = align_word_size_up(_first_class_chunk_word_size);
2569 // Arbitrarily set the initial virtual space to a multiple
2570 // of the boot class loader size.
2571 size_t word_size = VIRTUALSPACEMULTIPLIER * first_chunk_word_size();
2572 // Initialize the list of virtual spaces.
2573 _space_list = new VirtualSpaceList(word_size);
2574 }
2575 }
2576
2577 // For UseCompressedKlassPointers the class space is reserved as a piece of the
2578 // Java heap because the compression algorithm is the same for each. The
2579 // argument passed in is at the top of the compressed space
2580 void Metaspace::initialize_class_space(ReservedSpace rs) {
2581 // The reserved space size may be bigger because of alignment, esp with UseLargePages
2582 assert(rs.size() >= ClassMetaspaceSize,
2583 err_msg(SIZE_FORMAT " != " UINTX_FORMAT, rs.size(), ClassMetaspaceSize));
2584 _class_space_list = new VirtualSpaceList(rs);
2585 }
2586
2587 void Metaspace::initialize(Mutex* lock,
2588 MetaspaceType type) {
2589
2590 assert(space_list() != NULL,
2591 "Metadata VirtualSpaceList has not been initialized");
2592
2593 _vsm = new SpaceManager(lock, space_list());
2594 if (_vsm == NULL) {
2595 return;
2596 }
2597 size_t word_size;
2598 size_t class_word_size;
2599 vsm()->get_initial_chunk_sizes(type,
2600 &word_size,
2601 &class_word_size);
2602
2603 assert(class_space_list() != NULL,
|