1 /* 2 * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. 3 * Copyright (c) 2020 SAP SE. All rights reserved. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 * 24 */ 25 26 #include "precompiled.hpp" 27 28 #include "memory/metaspace/msBinList.hpp" 29 #include "memory/metaspace/msCounter.hpp" 30 31 //#define LOG_PLEASE 32 #include "metaspaceGtestCommon.hpp" 33 34 using metaspace::BinList32; 35 using metaspace::BinListImpl; 36 using metaspace::MemRangeCounter; 37 38 #define CHECK_BL_CONTENT(bl, expected_num, expected_size) { \ 39 EXPECT_EQ(bl.count(), (unsigned)expected_num); \ 40 EXPECT_EQ(bl.total_size(), (size_t)expected_size); \ 41 if (expected_num == 0) { \ 42 EXPECT_TRUE(bl.is_empty()); \ 43 } else { \ 44 EXPECT_FALSE(bl.is_empty()); \ 45 } \ 46 } 47 48 template <class BINLISTTYPE> 49 struct BinListBasicTest { 50 51 static const size_t minws; 52 static const size_t maxws; 53 54 static void basic_test() { 55 56 BINLISTTYPE bl; 57 58 CHECK_BL_CONTENT(bl, 0, 0); 59 60 MetaWord arr[1000]; 61 62 size_t innocous_size = minws + ((maxws - minws) / 2); 63 64 // Try to get a block from an empty list. 65 size_t real_size = 4711; 66 MetaWord* p = bl.remove_block(innocous_size, &real_size); 67 EXPECT_EQ(p, (MetaWord*)NULL); 68 EXPECT_EQ((size_t)0, real_size); 69 70 // Add a block... 71 bl.add_block(arr, innocous_size); 72 CHECK_BL_CONTENT(bl, 1, innocous_size); 73 DEBUG_ONLY(bl.verify();) 74 75 // And retrieve it. 76 real_size = 4711; 77 p = bl.remove_block(innocous_size, &real_size); 78 EXPECT_EQ(p, arr); 79 EXPECT_EQ((size_t)innocous_size, real_size); 80 CHECK_BL_CONTENT(bl, 0, 0); 81 DEBUG_ONLY(bl.verify();) 82 83 } 84 85 static void basic_test_2() { 86 87 BINLISTTYPE bl; 88 89 CHECK_BL_CONTENT(bl, 0, 0); 90 91 MetaWord arr[1000]; 92 93 for (size_t s1 = minws; s1 <= maxws; s1++) { 94 for (size_t s2 = minws; s2 <= maxws; s2++) { 95 96 bl.add_block(arr, s1); 97 CHECK_BL_CONTENT(bl, 1, s1); 98 DEBUG_ONLY(bl.verify();) 99 100 size_t real_size = 4711; 101 MetaWord* p = bl.remove_block(s2, &real_size); 102 if (s1 >= s2) { 103 EXPECT_EQ(p, arr); 104 EXPECT_EQ((size_t)s1, real_size); 105 CHECK_BL_CONTENT(bl, 0, 0); 106 DEBUG_ONLY(bl.verify();) 107 } else { 108 EXPECT_EQ(p, (MetaWord*)NULL); 109 EXPECT_EQ((size_t)0, real_size); 110 CHECK_BL_CONTENT(bl, 1, s1); 111 DEBUG_ONLY(bl.verify();) 112 // drain bl 113 p = bl.remove_block(minws, &real_size); 114 EXPECT_EQ(p, arr); 115 EXPECT_EQ((size_t)s1, real_size); 116 CHECK_BL_CONTENT(bl, 0, 0); 117 } 118 } 119 } 120 } 121 122 static void random_test() { 123 124 BINLISTTYPE bl[2]; 125 MemRangeCounter cnt[2]; 126 127 #define CHECK_COUNTERS \ 128 ASSERT_EQ(cnt[0].count(), bl[0].count()); \ 129 ASSERT_EQ(cnt[1].count(), bl[1].count()); \ 130 ASSERT_EQ(cnt[0].total_size(), bl[0].total_size()); \ 131 ASSERT_EQ(cnt[1].total_size(), bl[1].total_size()); 132 133 FeederBuffer fb(1024); 134 RandSizeGenerator rgen(minws, maxws + 1); 135 136 // feed all 137 int which = 0; 138 for (;;) { 139 size_t s = rgen.get(); 140 MetaWord* p = fb.get(s); 141 if (p != NULL) { 142 bl[which].add_block(p, s); 143 cnt[which].add(s); 144 which = which == 0 ? 1 : 0; 145 } else { 146 break; 147 } 148 } 149 150 CHECK_COUNTERS; 151 DEBUG_ONLY(bl[0].verify();) 152 DEBUG_ONLY(bl[1].verify();) 153 154 // play pingpong 155 for (int iter = 0; iter < 1000; iter++) { 156 size_t s = rgen.get(); 157 int taker = iter % 2; 158 int giver = taker == 0 ? 1 : 0; 159 160 size_t real_size = 4711; 161 MetaWord* p = bl[giver].remove_block(s, &real_size); 162 if (p != NULL) { 163 164 ASSERT_TRUE(fb.is_valid_range(p, real_size)); 165 ASSERT_GE(real_size, s); 166 cnt[giver].sub(real_size); 167 168 bl[taker].add_block(p, real_size); 169 cnt[taker].add(real_size); 170 171 } else { 172 ASSERT_EQ(real_size, (size_t)NULL); 173 } 174 175 CHECK_COUNTERS; 176 177 } 178 179 CHECK_COUNTERS; 180 DEBUG_ONLY(bl[0].verify();) 181 DEBUG_ONLY(bl[1].verify();) 182 183 // drain both lists. 184 for (int which = 0; which < 2; which++) { 185 size_t last_size = 0; 186 while (bl[which].is_empty() == false) { 187 188 size_t real_size = 4711; 189 MetaWord* p = bl[which].remove_block(minws, &real_size); 190 191 ASSERT_NE(p, (MetaWord*) NULL); 192 ASSERT_GE(real_size, minws); 193 ASSERT_TRUE(fb.is_valid_range(p, real_size)); 194 195 // This must hold true since we always return the smallest fit. 196 ASSERT_GE(real_size, last_size); 197 if (real_size > last_size) { 198 last_size = real_size; 199 } 200 201 cnt[which].sub(real_size); 202 203 CHECK_COUNTERS; 204 } 205 } 206 207 } 208 }; 209 210 template <typename BINLISTTYPE> const size_t BinListBasicTest<BINLISTTYPE>::minws = BINLISTTYPE::MinWordSize; 211 template <typename BINLISTTYPE> const size_t BinListBasicTest<BINLISTTYPE>::maxws = BINLISTTYPE::MaxWordSize; 212 213 TEST_VM(metaspace, BinList_basic_8) { BinListBasicTest< BinListImpl<2, 8> >::basic_test(); } 214 TEST_VM(metaspace, BinList_basic_16) { BinListBasicTest< BinListImpl<2, 16> >::basic_test(); } 215 TEST_VM(metaspace, BinList_basic_32) { BinListBasicTest<BinList32>::basic_test(); } 216 TEST_VM(metaspace, BinList_basic_1331) { BinListBasicTest< BinListImpl<13, 31> >::basic_test(); } 217 TEST_VM(metaspace, BinList_basic_131) { BinListBasicTest< BinListImpl<13, 1> >::basic_test(); } 218 219 TEST_VM(metaspace, BinList_basic2_8) { BinListBasicTest< BinListImpl<2, 8> >::basic_test_2(); } 220 TEST_VM(metaspace, BinList_basic2_16) { BinListBasicTest< BinListImpl<2, 16> >::basic_test_2(); } 221 TEST_VM(metaspace, BinList_basic2_32) { BinListBasicTest<BinList32 >::basic_test_2(); } 222 TEST_VM(metaspace, BinList_basic2_1331) { BinListBasicTest< BinListImpl<13, 31> >::basic_test_2(); } 223 TEST_VM(metaspace, BinList_basic2_131) { BinListBasicTest< BinListImpl<13, 1> >::basic_test_2(); } 224 225 TEST_VM(metaspace, BinList_random_test_8) { BinListBasicTest< BinListImpl<2, 8> >::random_test(); } 226 TEST_VM(metaspace, BinList_random_test_16) { BinListBasicTest< BinListImpl<2, 16> >::random_test(); } 227 TEST_VM(metaspace, BinList_random_test_32) { BinListBasicTest<BinList32>::random_test(); } 228 TEST_VM(metaspace, BinList_random_test_1331) { BinListBasicTest< BinListImpl<13, 31> >::random_test(); } 229 TEST_VM(metaspace, BinList_random_test_131) { BinListBasicTest< BinListImpl<13, 1> >::random_test(); } 230