# HG changeset patch # User stuefe # Date 1521455925 -3600 # Node ID c8ab058dcf1fd6f1c2e498ec79b36d1217edeac0 # Parent acb36277a784eee9adde0d83588b9ef1a9f6f93f 8199667: Unify metaspace list index handling and reinstantiate ChunkManager listindex gtest Reviewed-by: zgu, coleenp diff -r acb36277a784 -r c8ab058dcf1f src/hotspot/share/memory/metaspace.cpp --- a/src/hotspot/share/memory/metaspace.cpp Thu Mar 15 21:26:55 2018 +0100 +++ b/src/hotspot/share/memory/metaspace.cpp Mon Mar 19 11:38:45 2018 +0100 @@ -113,6 +113,7 @@ } else if (size == ClassMediumChunk) { return MediumIndex; } else if (size > ClassMediumChunk) { + // A valid humongous chunk size is a multiple of the smallest chunk size. assert(is_aligned(size, ClassSpecializedChunk), "Invalid chunk size"); return HumongousIndex; } @@ -124,6 +125,7 @@ } else if (size == MediumChunk) { return MediumIndex; } else if (size > MediumChunk) { + // A valid humongous chunk size is a multiple of the smallest chunk size. assert(is_aligned(size, SpecializedChunk), "Invalid chunk size"); return HumongousIndex; } @@ -299,10 +301,7 @@ Metachunk* free_chunks_get(size_t chunk_word_size); #define index_bounds_check(index) \ - assert(index == SpecializedIndex || \ - index == SmallIndex || \ - index == MediumIndex || \ - index == HumongousIndex, "Bad index: %d", (int) index) + assert(is_valid_chunktype(index), "Bad index: %d", (int) index) size_t num_free_chunks(ChunkIndex index) const { index_bounds_check(index); @@ -2648,25 +2647,13 @@ } ChunkIndex ChunkManager::list_index(size_t size) { - if (size_by_index(SpecializedIndex) == size) { - return SpecializedIndex; - } - if (size_by_index(SmallIndex) == size) { - return SmallIndex; - } - const size_t med_size = size_by_index(MediumIndex); - if (med_size == size) { - return MediumIndex; - } - - assert(size > med_size, "Not a humongous chunk"); - return HumongousIndex; + return get_chunk_type_by_size(size, is_class()); } size_t ChunkManager::size_by_index(ChunkIndex index) const { index_bounds_check(index); assert(index != HumongousIndex, "Do not call for humongous chunks."); - return _free_chunks[index].size(); + return get_size_for_nonhumongous_chunktype(index, is_class()); } void ChunkManager::locked_verify_free_chunks_total() { @@ -5244,37 +5231,39 @@ // 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(true); - - // 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); - } + // Test previous bug where a query for a humongous class metachunk, + // incorrectly matched the non-class medium metachunk size. + { + ChunkManager manager(true); + + 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. + { + ChunkManager manager(true); + assert(manager.list_index(ClassSpecializedChunk) == SpecializedIndex, "sanity"); + assert(manager.list_index(ClassSmallChunk) == SmallIndex, "sanity"); + assert(manager.list_index(ClassMediumChunk) == MediumIndex, "sanity"); + assert(manager.list_index(ClassMediumChunk + ClassSpecializedChunk) == HumongousIndex, "sanity"); + } + { + ChunkManager manager(false); + assert(manager.list_index(SpecializedChunk) == SpecializedIndex, "sanity"); + assert(manager.list_index(SmallChunk) == SmallIndex, "sanity"); + assert(manager.list_index(MediumChunk) == MediumIndex, "sanity"); + assert(manager.list_index(MediumChunk + SpecializedChunk) == HumongousIndex, "sanity"); + } + + } + } #endif // !PRODUCT diff -r acb36277a784 -r c8ab058dcf1f test/hotspot/gtest/memory/test_chunkManager.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/gtest/memory/test_chunkManager.cpp Mon Mar 19 11:38:45 2018 +0100 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2016, 2018 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include "precompiled.hpp" + +// The test function is only available in debug builds +#ifdef ASSERT + +#include "unittest.hpp" + +void ChunkManager_test_list_index(); + +TEST(ChunkManager, list_index) { + // The ChunkManager is only available in metaspace.cpp, + // so the test code is located in that file. + ChunkManager_test_list_index(); + +} + +#endif // ASSERT