1 /* 2 * Copyright (c) 2020, 2024, 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 #include "memory/metaspace/binList.hpp" 28 #include "memory/metaspace/counters.hpp" 29 //#define LOG_PLEASE 30 #include "metaspaceGtestCommon.hpp" 31 32 using metaspace::BinList32; 33 using metaspace::BinListImpl; 34 using metaspace::MemRangeCounter; 35 36 #define CHECK_BL_CONTENT(bl, expected_num, expected_size) { \ 37 EXPECT_EQ(bl.count(), (unsigned)expected_num); \ 38 EXPECT_EQ(bl.total_size(), (size_t)expected_size); \ 39 if (expected_num == 0) { \ 40 EXPECT_TRUE(bl.is_empty()); \ 41 } else { \ 42 EXPECT_FALSE(bl.is_empty()); \ 43 } \ 44 } 45 46 template <class BINLISTTYPE> 47 struct BinListBasicTest { 48 49 static const size_t maxws; 50 51 static void basic_test() { 52 53 BINLISTTYPE bl; 54 55 CHECK_BL_CONTENT(bl, 0, 0); 56 57 MetaWord arr[1000]; 58 59 size_t innocous_size = MAX2((size_t)1, maxws / 2); 60 61 // Try to get a block from an empty list. 62 size_t real_size = 4711; 63 MetaWord* p = bl.remove_block(innocous_size, &real_size); 64 EXPECT_EQ(p, (MetaWord*)nullptr); 65 EXPECT_EQ((size_t)0, real_size); 66 67 // Add a block... 68 bl.add_block(arr, innocous_size); 69 CHECK_BL_CONTENT(bl, 1, innocous_size); 70 DEBUG_ONLY(bl.verify();) 71 72 // And retrieve it. 73 real_size = 4711; 74 p = bl.remove_block(innocous_size, &real_size); 75 EXPECT_EQ(p, arr); 76 EXPECT_EQ((size_t)innocous_size, real_size); 77 CHECK_BL_CONTENT(bl, 0, 0); 78 DEBUG_ONLY(bl.verify();) 79 80 } 81 82 static void basic_test_2() { 83 84 BINLISTTYPE bl; 85 86 CHECK_BL_CONTENT(bl, 0, 0); 87 88 MetaWord arr[1000]; 89 90 for (size_t s1 = 1; s1 <= maxws; s1++) { 91 for (size_t s2 = 1; s2 <= maxws; s2++) { 92 93 bl.add_block(arr, s1); 94 CHECK_BL_CONTENT(bl, 1, s1); 95 DEBUG_ONLY(bl.verify();) 96 97 size_t real_size = 4711; 98 MetaWord* p = bl.remove_block(s2, &real_size); 99 if (s1 >= s2) { 100 EXPECT_EQ(p, arr); 101 EXPECT_EQ((size_t)s1, real_size); 102 CHECK_BL_CONTENT(bl, 0, 0); 103 DEBUG_ONLY(bl.verify();) 104 } else { 105 EXPECT_EQ(p, (MetaWord*)nullptr); 106 EXPECT_EQ((size_t)0, real_size); 107 CHECK_BL_CONTENT(bl, 1, s1); 108 DEBUG_ONLY(bl.verify();) 109 // drain bl 110 p = bl.remove_block(1, &real_size); 111 EXPECT_EQ(p, arr); 112 EXPECT_EQ((size_t)s1, real_size); 113 CHECK_BL_CONTENT(bl, 0, 0); 114 } 115 } 116 } 117 } 118 119 static void random_test() { 120 121 BINLISTTYPE bl[2]; 122 MemRangeCounter cnt[2]; 123 124 #define CHECK_COUNTERS \ 125 ASSERT_EQ(cnt[0].count(), bl[0].count()); \ 126 ASSERT_EQ(cnt[1].count(), bl[1].count()); \ 127 ASSERT_EQ(cnt[0].total_size(), bl[0].total_size()); \ 128 ASSERT_EQ(cnt[1].total_size(), bl[1].total_size()); 129 130 FeederBuffer fb(1024); 131 RandSizeGenerator rgen(1, maxws + 1); 132 133 // feed all 134 int which = 0; 135 for (;;) { 136 size_t s = rgen.get(); 137 MetaWord* p = fb.get(s); 138 if (p != nullptr) { 139 bl[which].add_block(p, s); 140 cnt[which].add(s); 141 which = which == 0 ? 1 : 0; 142 } else { 143 break; 144 } 145 } 146 147 CHECK_COUNTERS; 148 DEBUG_ONLY(bl[0].verify();) 149 DEBUG_ONLY(bl[1].verify();) 150 151 // play pingpong 152 for (int iter = 0; iter < 1000; iter++) { 153 size_t s = rgen.get(); 154 int taker = iter % 2; 155 int giver = taker == 0 ? 1 : 0; 156 157 size_t real_size = 4711; 158 MetaWord* p = bl[giver].remove_block(s, &real_size); 159 if (p != nullptr) { 160 161 ASSERT_TRUE(fb.is_valid_range(p, real_size)); 162 ASSERT_GE(real_size, s); 163 cnt[giver].sub(real_size); 164 165 bl[taker].add_block(p, real_size); 166 cnt[taker].add(real_size); 167 168 } else { 169 ASSERT_EQ(real_size, (size_t)nullptr); 170 } 171 172 CHECK_COUNTERS; 173 174 } 175 176 CHECK_COUNTERS; 177 DEBUG_ONLY(bl[0].verify();) 178 DEBUG_ONLY(bl[1].verify();) 179 180 // drain both lists. 181 for (int which = 0; which < 2; which++) { 182 size_t last_size = 0; 183 while (bl[which].is_empty() == false) { 184 185 size_t real_size = 4711; 186 MetaWord* p = bl[which].remove_block(1, &real_size); 187 188 ASSERT_NE(p, (MetaWord*) nullptr); 189 ASSERT_GE(real_size, (size_t)1); 190 ASSERT_TRUE(fb.is_valid_range(p, real_size)); 191 192 // This must hold true since we always return the smallest fit. 193 ASSERT_GE(real_size, last_size); 194 if (real_size > last_size) { 195 last_size = real_size; 196 } 197 198 cnt[which].sub(real_size); 199 200 CHECK_COUNTERS; 201 } 202 } 203 204 } 205 }; 206 207 template <typename BINLISTTYPE> const size_t BinListBasicTest<BINLISTTYPE>::maxws = BINLISTTYPE::MaxWordSize; 208 209 TEST_VM(metaspace, BinList_basic_1) { BinListBasicTest< BinListImpl<1> >::basic_test(); } 210 TEST_VM(metaspace, BinList_basic_8) { BinListBasicTest< BinListImpl<8> >::basic_test(); } 211 TEST_VM(metaspace, BinList_basic_32) { BinListBasicTest<BinList32>::basic_test(); } 212 213 TEST_VM(metaspace, BinList_basic_2_1) { BinListBasicTest< BinListImpl<1> >::basic_test_2(); } 214 TEST_VM(metaspace, BinList_basic_2_8) { BinListBasicTest< BinListImpl<8> >::basic_test_2(); } 215 TEST_VM(metaspace, BinList_basic_2_32) { BinListBasicTest<BinList32>::basic_test_2(); } 216 217 TEST_VM(metaspace, BinList_basic_rand_1) { BinListBasicTest< BinListImpl<1> >::random_test(); } 218 TEST_VM(metaspace, BinList_basic_rand_8) { BinListBasicTest< BinListImpl<8> >::random_test(); } 219 TEST_VM(metaspace, BinList_basic_rand_32) { BinListBasicTest<BinList32>::random_test(); }