1.1 --- a/src/share/vm/memory/metaspace.cpp Mon Dec 25 00:08:23 2017 -0500 1.2 +++ b/src/share/vm/memory/metaspace.cpp Wed Jan 03 03:17:10 2018 -0800 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -154,7 +154,7 @@ 1.11 1.12 // Map a size to a list index assuming that there are lists 1.13 // for special, small, medium, and humongous chunks. 1.14 - static ChunkIndex list_index(size_t size); 1.15 + ChunkIndex list_index(size_t size); 1.16 1.17 // Remove the chunk from its freelist. It is 1.18 // expected to be on one of the _free_chunks[] lists. 1.19 @@ -1752,7 +1752,11 @@ 1.20 st->print_cr("Sum free chunk total " SIZE_FORMAT " count " SIZE_FORMAT, 1.21 sum_free_chunks(), sum_free_chunks_count()); 1.22 } 1.23 + 1.24 ChunkList* ChunkManager::free_chunks(ChunkIndex index) { 1.25 + assert(index == SpecializedIndex || index == SmallIndex || index == MediumIndex, 1.26 + err_msg("Bad index: %d", (int)index)); 1.27 + 1.28 return &_free_chunks[index]; 1.29 } 1.30 1.31 @@ -1864,7 +1868,7 @@ 1.32 } 1.33 1.34 assert((word_size <= chunk->word_size()) || 1.35 - list_index(chunk->word_size() == HumongousIndex), 1.36 + (list_index(chunk->word_size()) == HumongousIndex), 1.37 "Non-humongous variable sized chunk"); 1.38 if (TraceMetadataChunkAllocation) { 1.39 size_t list_count; 1.40 @@ -2358,22 +2362,18 @@ 1.41 } 1.42 1.43 ChunkIndex ChunkManager::list_index(size_t size) { 1.44 - switch (size) { 1.45 - case SpecializedChunk: 1.46 - assert(SpecializedChunk == ClassSpecializedChunk, 1.47 - "Need branch for ClassSpecializedChunk"); 1.48 - return SpecializedIndex; 1.49 - case SmallChunk: 1.50 - case ClassSmallChunk: 1.51 - return SmallIndex; 1.52 - case MediumChunk: 1.53 - case ClassMediumChunk: 1.54 - return MediumIndex; 1.55 - default: 1.56 - assert(size > MediumChunk || size > ClassMediumChunk, 1.57 - "Not a humongous chunk"); 1.58 - return HumongousIndex; 1.59 + if (free_chunks(SpecializedIndex)->size() == size) { 1.60 + return SpecializedIndex; 1.61 } 1.62 + if (free_chunks(SmallIndex)->size() == size) { 1.63 + return SmallIndex; 1.64 + } 1.65 + if (free_chunks(MediumIndex)->size() == size) { 1.66 + return MediumIndex; 1.67 + } 1.68 + 1.69 + assert(size > free_chunks(MediumIndex)->size(), "Not a humongous chunk"); 1.70 + return HumongousIndex; 1.71 } 1.72 1.73 void SpaceManager::deallocate(MetaWord* p, size_t word_size) { 1.74 @@ -2395,7 +2395,7 @@ 1.75 1.76 // Find the correct list and and set the current 1.77 // chunk for that list. 1.78 - ChunkIndex index = ChunkManager::list_index(new_chunk->word_size()); 1.79 + ChunkIndex index = chunk_manager()->list_index(new_chunk->word_size()); 1.80 1.81 if (index != HumongousIndex) { 1.82 retire_current_chunk(); 1.83 @@ -4031,4 +4031,40 @@ 1.84 SpaceManagerTest::test_adjust_initial_chunk_size(); 1.85 } 1.86 1.87 +// The following test is placed here instead of a gtest / unittest file 1.88 +// because the ChunkManager class is only available in this file. 1.89 +void ChunkManager_test_list_index() { 1.90 + ChunkManager manager(ClassSpecializedChunk, ClassSmallChunk, ClassMediumChunk); 1.91 + 1.92 + // Test previous bug where a query for a humongous class metachunk, 1.93 + // incorrectly matched the non-class medium metachunk size. 1.94 + { 1.95 + assert(MediumChunk > ClassMediumChunk, "Precondition for test"); 1.96 + 1.97 + ChunkIndex index = manager.list_index(MediumChunk); 1.98 + 1.99 + assert(index == HumongousIndex, 1.100 + err_msg("Requested size is larger than ClassMediumChunk," 1.101 + " so should return HumongousIndex. Got index: %d", (int)index)); 1.102 + } 1.103 + 1.104 + // Check the specified sizes as well. 1.105 + { 1.106 + ChunkIndex index = manager.list_index(ClassSpecializedChunk); 1.107 + assert(index == SpecializedIndex, err_msg("Wrong index returned. Got index: %d", (int)index)); 1.108 + } 1.109 + { 1.110 + ChunkIndex index = manager.list_index(ClassSmallChunk); 1.111 + assert(index == SmallIndex, err_msg("Wrong index returned. Got index: %d", (int)index)); 1.112 + } 1.113 + { 1.114 + ChunkIndex index = manager.list_index(ClassMediumChunk); 1.115 + assert(index == MediumIndex, err_msg("Wrong index returned. Got index: %d", (int)index)); 1.116 + } 1.117 + { 1.118 + ChunkIndex index = manager.list_index(ClassMediumChunk + 1); 1.119 + assert(index == HumongousIndex, err_msg("Wrong index returned. Got index: %d", (int)index)); 1.120 + } 1.121 +} 1.122 + 1.123 #endif