< prev index next >

src/share/vm/memory/metaspace.cpp

Print this page

        

*** 151,161 **** // add or delete (return) a chunk to the global freelist. Metachunk* chunk_freelist_allocate(size_t word_size); // Map a size to a list index assuming that there are lists // for special, small, medium, and humongous chunks. ! static ChunkIndex list_index(size_t size); // Remove the chunk from its freelist. It is // expected to be on one of the _free_chunks[] lists. void remove_chunk(Metachunk* chunk); --- 151,161 ---- // add or delete (return) a chunk to the global freelist. Metachunk* chunk_freelist_allocate(size_t word_size); // Map a size to a list index assuming that there are lists // for special, small, medium, and humongous chunks. ! ChunkIndex list_index(size_t size); // Remove the chunk from its freelist. It is // expected to be on one of the _free_chunks[] lists. void remove_chunk(Metachunk* chunk);
*** 1781,1791 **** --- 1781,1795 ---- void ChunkManager::locked_print_sum_free_chunks(outputStream* st) { assert_lock_strong(SpaceManager::expand_lock()); st->print_cr("Sum free chunk total " SIZE_FORMAT " count " SIZE_FORMAT, sum_free_chunks(), sum_free_chunks_count()); } + ChunkList* ChunkManager::free_chunks(ChunkIndex index) { + assert(index == SpecializedIndex || index == SmallIndex || index == MediumIndex, + "Bad index: %d", (int)index); + return &_free_chunks[index]; } // These methods that sum the free chunk lists are used in printing // methods that are used in product builds.
*** 1885,1895 **** if (chunk == NULL) { return NULL; } assert((word_size <= chunk->word_size()) || ! list_index(chunk->word_size() == HumongousIndex), "Non-humongous variable sized chunk"); Log(gc, metaspace, freelist) log; if (log.is_debug()) { size_t list_count; if (list_index(word_size) < HumongousIndex) { --- 1889,1899 ---- if (chunk == NULL) { return NULL; } assert((word_size <= chunk->word_size()) || ! (list_index(chunk->word_size()) == HumongousIndex), "Non-humongous variable sized chunk"); Log(gc, metaspace, freelist) log; if (log.is_debug()) { size_t list_count; if (list_index(word_size) < HumongousIndex) {
*** 2336,2361 **** return NULL; } } ChunkIndex ChunkManager::list_index(size_t size) { ! switch (size) { ! case SpecializedChunk: ! assert(SpecializedChunk == ClassSpecializedChunk, ! "Need branch for ClassSpecializedChunk"); return SpecializedIndex; ! case SmallChunk: ! case ClassSmallChunk: return SmallIndex; ! case MediumChunk: ! case ClassMediumChunk: return MediumIndex; - default: - assert(size > MediumChunk || size > ClassMediumChunk, - "Not a humongous chunk"); - return HumongousIndex; } } void SpaceManager::deallocate(MetaWord* p, size_t word_size) { assert_lock_strong(_lock); // Allocations and deallocations are in raw_word_size --- 2340,2361 ---- return NULL; } } ChunkIndex ChunkManager::list_index(size_t size) { ! if (free_chunks(SpecializedIndex)->size() == size) { return SpecializedIndex; ! } ! if (free_chunks(SmallIndex)->size() == size) { return SmallIndex; ! } ! if (free_chunks(MediumIndex)->size() == size) { return MediumIndex; } + + assert(size > free_chunks(MediumIndex)->size(), "Not a humongous chunk"); + return HumongousIndex; } void SpaceManager::deallocate(MetaWord* p, size_t word_size) { assert_lock_strong(_lock); // Allocations and deallocations are in raw_word_size
*** 2375,2385 **** new_chunk->reset_empty(); // Find the correct list and and set the current // chunk for that list. ! ChunkIndex index = ChunkManager::list_index(new_chunk->word_size()); if (index != HumongousIndex) { retire_current_chunk(); set_current_chunk(new_chunk); new_chunk->set_next(chunks_in_use(index)); --- 2375,2385 ---- new_chunk->reset_empty(); // Find the correct list and and set the current // chunk for that list. ! ChunkIndex index = chunk_manager()->list_index(new_chunk->word_size()); if (index != HumongousIndex) { retire_current_chunk(); set_current_chunk(new_chunk); new_chunk->set_next(chunks_in_use(index));
*** 4011,4016 **** --- 4011,4053 ---- void TestVirtualSpaceNode_test() { TestVirtualSpaceNodeTest::test(); TestVirtualSpaceNodeTest::test_is_available(); } + + // The following test is placed here instead of a gtest / unittest file + // because the ChunkManager class is only available in this file. + void ChunkManager_test_list_index() { + ChunkManager manager(ClassSpecializedChunk, ClassSmallChunk, ClassMediumChunk); + + // Test previous bug where a query for a humongous class metachunk, + // incorrectly matched the non-class medium metachunk size. + { + assert(MediumChunk > ClassMediumChunk, "Precondition for test"); + + ChunkIndex index = manager.list_index(MediumChunk); + + assert(index == HumongousIndex, + "Requested size is larger than ClassMediumChunk," + " so should return HumongousIndex. Got index: %d", (int)index); + } + + // Check the specified sizes as well. + { + ChunkIndex index = manager.list_index(ClassSpecializedChunk); + assert(index == SpecializedIndex, "Wrong index returned. Got index: %d", (int)index); + } + { + ChunkIndex index = manager.list_index(ClassSmallChunk); + assert(index == SmallIndex, "Wrong index returned. Got index: %d", (int)index); + } + { + ChunkIndex index = manager.list_index(ClassMediumChunk); + assert(index == MediumIndex, "Wrong index returned. Got index: %d", (int)index); + } + { + ChunkIndex index = manager.list_index(ClassMediumChunk + 1); + assert(index == HumongousIndex, "Wrong index returned. Got index: %d", (int)index); + } + } + #endif
< prev index next >