< prev index next >

src/share/vm/memory/metaspace.cpp

Print this page

        

*** 109,118 **** --- 109,121 ---- // ChunkManager in all lists of this type size_t _free_chunks_total; size_t _free_chunks_count; + // Return the fixed chunk size for the given list index + size_t list_chunk_size(ChunkIndex index) const; + void dec_free_chunks_total(size_t v) { assert(_free_chunks_count > 0 && _free_chunks_total > 0, "About to go negative"); Atomic::add_ptr(-1, &_free_chunks_count);
*** 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); --- 154,164 ---- // 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) const; // Remove the chunk from its freelist. It is // expected to be on one of the _free_chunks[] lists. void remove_chunk(Metachunk* chunk);
*** 247,256 **** --- 250,293 ---- void locked_print_sum_free_chunks(outputStream* st); void print_on(outputStream* st) const; }; + 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); + } + } + class SmallBlocks : public CHeapObj<mtClass> { const static uint _small_block_max_size = sizeof(TreeChunk<Metablock, FreeList<Metablock> >)/HeapWordSize; const static uint _small_block_min_size = sizeof(Metablock)/HeapWordSize; private:
*** 2335,2361 **** default: 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 --- 2372,2401 ---- default: return NULL; } } ! size_t ChunkManager::list_chunk_size(ChunkIndex index) const { ! assert(index == SpecializedIndex || index == SmallIndex || index == MediumIndex, ! "Bad index: %d", (int)index); ! ! return _free_chunks[index].size(); ! } ! ! ChunkIndex ChunkManager::list_index(size_t size) const { ! if (list_chunk_size(SpecializedIndex) == size) { return SpecializedIndex; ! } ! if (list_chunk_size(SmallIndex) == size) { return SmallIndex; ! } ! if (list_chunk_size(MediumIndex) == size) { return MediumIndex; } + + assert(size > list_chunk_size(MediumIndex), "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)); --- 2415,2425 ---- 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));
< prev index next >