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 #ifndef GTEST_METASPACE_METASPACEGTESTCOMMON_HPP
  27 #define GTEST_METASPACE_METASPACEGTESTCOMMON_HPP
  28 
  29 #include "memory/allocation.hpp"
  30 #include "utilities/globalDefinitions.hpp"
  31 #include "runtime/os.hpp"
  32 
  33 #include "unittest.hpp"
  34 
  35 /////////////////////////////////////////////////////////////////////
  36 // A little mockup to mimick and test the CommitMask in various tests
  37 
  38 class TestMap {
  39   const size_t _len;
  40   char* _arr;
  41 public:
  42   TestMap(size_t len) : _len(len), _arr(NULL) {
  43     _arr = NEW_C_HEAP_ARRAY(char, len, mtInternal);
  44     memset(_arr, 0, _len);
  45   }
  46   ~TestMap() { FREE_C_HEAP_ARRAY(char, _arr); }
  47 
  48   int get_num_set(size_t from, size_t to) const {
  49     int result = 0;
  50     for(size_t i = from; i < to; i++) {
  51       if (_arr[i] > 0) {
  52         result++;
  53       }
  54     }
  55     return result;
  56   }
  57 
  58   size_t get_num_set() const { return get_num_set(0, _len); }
  59 
  60   void set_range(size_t from, size_t to) {
  61     memset(_arr + from, 1, to - from);
  62   }
  63 
  64   void clear_range(size_t from, size_t to) {
  65     memset(_arr + from, 0, to - from);
  66   }
  67 
  68   bool at(size_t pos) const {
  69     return _arr[pos] == 1;
  70   }
  71 
  72 };
  73 
  74 ///////////////////////////////////////////////////////////
  75 // Helper class for generating random allocation sizes
  76 class RandSizeGenerator {
  77   const size_t _min; // [
  78   const size_t _max; // )
  79   const float _outlier_chance; // 0.0 -- 1.0
  80   const size_t _outlier_min; // [
  81   const size_t _outlier_max; // )
  82 public:
  83   RandSizeGenerator(size_t min, size_t max)
  84     : _min(min), _max(max), _outlier_chance(0.0), _outlier_min(min), _outlier_max(max)
  85   {}
  86 
  87   RandSizeGenerator(size_t min, size_t max, float outlier_chance, size_t outlier_min, size_t outlier_max)
  88     : _min(min), _max(max), _outlier_chance(outlier_chance), _outlier_min(outlier_min), _outlier_max(outlier_max)
  89   {}
  90 
  91   size_t min() const { return _min; }
  92   size_t max() const { return _max; }
  93 
  94   size_t get() const {
  95     size_t l1 = _min;
  96     size_t l2 = _max;
  97     int r = os::random() % 1000;
  98     if ((float)r < _outlier_chance * 1000.0) {
  99       l1 = _outlier_min;
 100       l2 = _outlier_max;
 101     }
 102     const size_t d = l2 - l1;
 103     return l1 + (os::random() % d);
 104   }
 105 
 106 }; // end RandSizeGenerator
 107 
 108 size_t get_random_size(size_t min, size_t max);
 109 
 110 ///////////////////////////////////////////////////////////
 111 // Function to test-access a memory range
 112 
 113 void zap_range(MetaWord* p, size_t word_size);
 114 
 115 // "fill_range_with_pattern" fills a range of heap words with pointers to itself.
 116 //
 117 // The idea is to fill a memory range with a pattern which is both marked clearly to the caller
 118 // and cannot be moved without becoming invalid.
 119 //
 120 // The filled range can be checked with check_range_for_pattern. One also can only check
 121 // a sub range of the original range.
 122 void fill_range_with_pattern(MetaWord* p, uintx pattern, size_t word_size);
 123 void check_range_for_pattern(const MetaWord* p, uintx pattern, size_t word_size);
 124 
 125 // Writes a uniqe pattern to p
 126 void mark_address(MetaWord* p, uintx pattern);
 127 // checks pattern at address
 128 void check_marked_address(const MetaWord* p, uintx pattern);
 129 
 130 // Similar to fill_range_with_pattern, but only marks start and end. This is optimized for cases
 131 // where fill_range_with_pattern just is too slow.
 132 // Use check_marked_range to check the range. In contrast to check_range_for_pattern, only the original
 133 // range can be checked.
 134 void mark_range(MetaWord* p, uintx pattern, size_t word_size);
 135 void check_marked_range(const MetaWord* p, uintx pattern, size_t word_size);
 136 
 137 void mark_range(MetaWord* p, size_t word_size);
 138 void check_marked_range(const MetaWord* p, size_t word_size);
 139 
 140 //////////////////////////////////////////////////////////
 141 // Some helpers to avoid typing out those annoying casts for NULL
 142 
 143 #define ASSERT_NOT_NULL(ptr)      ASSERT_NE((void*)NULL, (void*)ptr)
 144 #define ASSERT_NULL(ptr)          ASSERT_EQ((void*)NULL, (void*)ptr)
 145 #define EXPECT_NOT_NULL(ptr)      EXPECT_NE((void*)NULL, (void*)ptr)
 146 #define EXPECT_NULL(ptr)          EXPECT_EQ((void*)NULL, (void*)ptr)
 147 
 148 #define ASSERT_0(v)               ASSERT_EQ((intptr_t)0, (intptr_t)v)
 149 #define ASSERT_NOT_0(v)           ASSERT_NE((intptr_t)0, (intptr_t)v)
 150 #define EXPECT_0(v)               EXPECT_EQ((intptr_t)0, (intptr_t)v)
 151 #define EXPECT_NOT_0(v)           EXPECT_NE((intptr_t)0, (intptr_t)v)
 152 #define ASSERT_GT0(v)             ASSERT_GT((intptr_t)v, (intptr_t)0)
 153 #define EXPECT_GT0(v)             EXPECT_GT((intptr_t)v, (intptr_t)0)
 154 
 155 //////////////////////////////////////////////////////////
 156 // logging
 157 
 158 // Define "LOG_PLEASE" to switch on logging for a particular test before inclusion of this header.
 159 #ifdef LOG_PLEASE
 160   #define LOG(...) { printf(__VA_ARGS__); printf("\n"); fflush(stdout); }
 161 #else
 162   #define LOG(...)
 163 #endif
 164 
 165 //////////////////////////////////////////////////////////
 166 // Helper
 167 
 168 size_t get_workingset_size();
 169 
 170 // A simple preallocated buffer used to "feed" someone.
 171 // Mimicks chunk retirement leftover blocks.
 172 class FeederBuffer {
 173 
 174   MetaWord* _buf;
 175 
 176   // Buffer capacity in size of words.
 177   const size_t _cap;
 178 
 179   // Used words.
 180   size_t _used;
 181 
 182 public:
 183 
 184   FeederBuffer(size_t size) : _buf(NULL), _cap(size), _used(0) {
 185     _buf = NEW_C_HEAP_ARRAY(MetaWord, _cap, mtInternal);
 186   }
 187 
 188   ~FeederBuffer() {
 189     FREE_C_HEAP_ARRAY(MetaWord, _buf);
 190   }
 191 
 192   MetaWord* get(size_t word_size) {
 193     if (_used + word_size > _cap) {
 194       return NULL;
 195     }
 196     MetaWord* p = _buf + _used;
 197     _used += word_size;
 198     return p;
 199   }
 200 
 201   bool is_valid_pointer(MetaWord* p) const {
 202     return p >= _buf && p < _buf + _used;
 203   }
 204 
 205   bool is_valid_range(MetaWord* p, size_t word_size) const {
 206     return is_valid_pointer(p) &&
 207            word_size > 0 ? is_valid_pointer(p + word_size - 1) : true;
 208   }
 209 
 210 };
 211 
 212 #endif // GTEST_METASPACE_METASPACEGTESTCOMMON_HPP