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 #ifndef GTEST_METASPACE_METASPACETESTCOMMON_HPP 27 #define GTEST_METASPACE_METASPACETESTCOMMON_HPP 28 29 #include "memory/allocation.hpp" 30 31 32 #include "memory/metaspace/arenaGrowthPolicy.hpp" 33 #include "memory/metaspace/binlist.hpp" 34 #include "memory/metaspace/blocktree.hpp" 35 #include "memory/metaspace/chunkHeaderPool.hpp" 36 #include "memory/metaspace/chunkLevel.hpp" 37 #include "memory/metaspace/chunkManager.hpp" 38 #include "memory/metaspace/counter.hpp" 39 #include "memory/metaspace/commitLimiter.hpp" 40 #include "memory/metaspace/commitMask.hpp" 41 #include "memory/metaspace/freeBlocks.hpp" 42 #include "memory/metaspace/freeChunkList.hpp" 43 #include "memory/metaspace/internStat.hpp" 44 #include "memory/metaspace/metachunk.hpp" 45 #include "memory/metaspace/metaspaceArena.hpp" 46 #include "memory/metaspace/metaspaceCommon.hpp" 47 #include "memory/metaspace/metaspaceEnums.hpp" 48 #include "memory/metaspace/metaspaceStatistics.hpp" 49 #include "memory/metaspace/metaspace_test.hpp" 50 #include "memory/metaspace/virtualSpaceList.hpp" 51 #include "memory/metaspace/settings.hpp" 52 #include "runtime/mutexLocker.hpp" 53 #include "runtime/os.hpp" 54 55 #include "utilities/align.hpp" 56 #include "utilities/debug.hpp" 57 #include "utilities/globalDefinitions.hpp" 58 59 #include "unittest.hpp" 60 61 62 #include <stdio.h> 63 64 65 ////////////////////////////////////////////////////////// 66 // handy aliases 67 68 using metaspace::BinListImpl; 69 using metaspace::BlockTree; 70 using metaspace::ArenaGrowthPolicy; 71 using metaspace::ChunkHeaderPool; 72 using metaspace::ChunkManager; 73 using metaspace::CommitLimiter; 74 using metaspace::CommitMask; 75 using metaspace::SizeCounter; 76 using metaspace::SizeAtomicCounter; 77 using metaspace::IntCounter; 78 using metaspace::FreeBlocks; 79 using metaspace::FreeChunkList; 80 using metaspace::FreeChunkListVector; 81 using metaspace::MemRangeCounter; 82 using metaspace::Metachunk; 83 using metaspace::MetachunkList; 84 using metaspace::Settings; 85 using metaspace::arena_stats_t; 86 using metaspace::in_use_chunk_stats_t; 87 using metaspace::cm_stats_t; 88 using metaspace::SizeCounter; 89 using metaspace::MetaspaceArena; 90 using metaspace::VirtualSpaceList; 91 using metaspace::VirtualSpaceNode; 92 93 using metaspace::chunklevel_t; 94 using namespace metaspace::chunklevel; 95 96 97 ///////////////////////////////////////////////////////////////////// 98 // A little mockup to mimick and test the CommitMask in various tests 99 100 class TestMap { 101 const size_t _len; 102 char* _arr; 103 public: 104 TestMap(size_t len) : _len(len), _arr(NULL) { 105 _arr = NEW_C_HEAP_ARRAY(char, len, mtInternal); 106 memset(_arr, 0, _len); 107 } 108 ~TestMap() { FREE_C_HEAP_ARRAY(char, _arr); } 109 110 int get_num_set(size_t from, size_t to) const { 111 int result = 0; 112 for(size_t i = from; i < to; i ++) { 113 if (_arr[i] > 0) { 114 result ++; 115 } 116 } 117 return result; 118 } 119 120 size_t get_num_set() const { return get_num_set(0, _len); } 121 122 void set_range(size_t from, size_t to) { 123 memset(_arr + from, 1, to - from); 124 } 125 126 void clear_range(size_t from, size_t to) { 127 memset(_arr + from, 0, to - from); 128 } 129 130 bool at(size_t pos) const { 131 return _arr[pos] == 1; 132 } 133 134 }; 135 136 137 /////////////////////////////////////////////////////////// 138 // Helper class for generating random allocation sizes 139 class RandSizeGenerator { 140 const size_t _min; // [ 141 const size_t _max; // ) 142 const float _outlier_chance; // 0.0 -- 1.0 143 const size_t _outlier_min; // [ 144 const size_t _outlier_max; // ) 145 public: 146 RandSizeGenerator(size_t min, size_t max) 147 : _min(min), _max(max), _outlier_chance(0.0), _outlier_min(min), _outlier_max(max) 148 {} 149 150 RandSizeGenerator(size_t min, size_t max, float outlier_chance, size_t outlier_min, size_t outlier_max) 151 : _min(min), _max(max), _outlier_chance(outlier_chance), _outlier_min(outlier_min), _outlier_max(outlier_max) 152 {} 153 154 size_t min() const { return _min; } 155 size_t max() const { return _max; } 156 157 size_t get() const { 158 size_t l1 = _min; 159 size_t l2 = _max; 160 int r = os::random() % 1000; 161 if ((float)r < _outlier_chance * 1000.0) { 162 l1 = _outlier_min; 163 l2 = _outlier_max; 164 } 165 const size_t d = l2 - l1; 166 return l1 + (os::random() % d); 167 } 168 169 }; // end RandSizeGenerator 170 171 size_t get_random_size(size_t min, size_t max); 172 173 /////////////////////////////////////////////////////////// 174 // Function to test-access a memory range 175 176 void zap_range(MetaWord* p, size_t word_size); 177 178 // "fill_range_with_pattern" fills a range of heap words with pointers to itself. 179 // 180 // The idea is to fill a memory range with a pattern which is both marked clearly to the caller 181 // and cannot be moved without becoming invalid. 182 // 183 // The filled range can be checked with check_range_for_pattern. One also can only check 184 // a sub range of the original range. 185 void fill_range_with_pattern(MetaWord* p, uintx pattern, size_t word_size); 186 void check_range_for_pattern(const MetaWord* p, uintx pattern, size_t word_size); 187 188 // Writes a uniqe pattern to p 189 void mark_address(MetaWord* p, uintx pattern); 190 // checks pattern at address 191 void check_marked_address(const MetaWord* p, uintx pattern); 192 193 // Similar to fill_range_with_pattern, but only marks start and end. This is optimized for cases 194 // where fill_range_with_pattern just is too slow. 195 // Use check_marked_range to check the range. In contrast to check_range_for_pattern, only the original 196 // range can be checked. 197 void mark_range(MetaWord* p, uintx pattern, size_t word_size); 198 void check_marked_range(const MetaWord* p, uintx pattern, size_t word_size); 199 200 void mark_range(MetaWord* p, size_t word_size); 201 void check_marked_range(const MetaWord* p, size_t word_size); 202 203 ////////////////////////////////////////////////////////// 204 // Some helpers to avoid typing out those annoying casts for NULL 205 206 #define ASSERT_NOT_NULL(ptr) ASSERT_NE((void*)NULL, (void*)ptr) 207 #define ASSERT_NULL(ptr) ASSERT_EQ((void*)NULL, (void*)ptr) 208 #define EXPECT_NOT_NULL(ptr) EXPECT_NE((void*)NULL, (void*)ptr) 209 #define EXPECT_NULL(ptr) EXPECT_EQ((void*)NULL, (void*)ptr) 210 211 #define ASSERT_0(v) ASSERT_EQ((intptr_t)0, (intptr_t)v) 212 #define ASSERT_NOT_0(v) ASSERT_NE((intptr_t)0, (intptr_t)v) 213 #define EXPECT_0(v) EXPECT_EQ((intptr_t)0, (intptr_t)v) 214 #define EXPECT_NOT_0(v) EXPECT_NE((intptr_t)0, (intptr_t)v) 215 216 ////////////////////////////////////////////////////////// 217 // logging 218 219 // Define "LOG_PLEASE" to switch on logging for a particular test before inclusion of this header. 220 #ifdef LOG_PLEASE 221 #define LOG(...) { printf(__VA_ARGS__); printf("\n"); fflush(stdout); } 222 #else 223 #define LOG(...) 224 #endif 225 226 ////////////////////////////////////////////////////////// 227 // Helper 228 229 size_t get_workingset_size(); 230 231 // A simple preallocated buffer used to "feed" someone. 232 // Mimicks chunk retirement leftover blocks. 233 class FeederBuffer { 234 235 MetaWord* _buf; 236 237 // Buffer capacity in size of words. 238 const size_t _cap; 239 240 // Used words. 241 size_t _used; 242 243 public: 244 245 FeederBuffer(size_t size) : _buf(NULL), _cap(size), _used(0) { 246 _buf = NEW_C_HEAP_ARRAY(MetaWord, _cap, mtInternal); 247 } 248 249 ~FeederBuffer() { 250 FREE_C_HEAP_ARRAY(MetaWord, _buf); 251 } 252 253 MetaWord* get(size_t word_size) { 254 if (_used + word_size > _cap) { 255 return NULL; 256 } 257 MetaWord* p = _buf + _used; 258 _used += word_size; 259 return p; 260 } 261 262 bool is_valid_pointer(MetaWord* p) const { 263 return p >= _buf && p < _buf + _used; 264 } 265 266 bool is_valid_range(MetaWord* p, size_t word_size) const { 267 return is_valid_pointer(p) && 268 word_size > 0 ? is_valid_pointer(p + word_size - 1) : true; 269 } 270 271 }; 272 273 #endif // GTEST_METASPACE_METASPACETESTCOMMON_HPP