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