1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219
|
/*
* Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef GTEST_METASPACE_METASPACEGTESTCOMMON_HPP
#define GTEST_METASPACE_METASPACEGTESTCOMMON_HPP
#include "memory/allocation.hpp"
#include "runtime/os.hpp"
#include "utilities/globalDefinitions.hpp"
#include "unittest.hpp"
/////////////////////////////////////////////////////////////////////
// A little mockup to mimick and test the CommitMask in various tests
class TestMap {
const size_t _len;
char* _arr;
public:
TestMap(size_t len) : _len(len), _arr(nullptr) {
_arr = NEW_C_HEAP_ARRAY(char, len, mtInternal);
memset(_arr, 0, _len);
}
~TestMap() { FREE_C_HEAP_ARRAY(char, _arr); }
int get_num_set(size_t from, size_t to) const {
int result = 0;
for(size_t i = from; i < to; i++) {
if (_arr[i] > 0) {
result++;
}
}
return result;
}
size_t get_num_set() const { return get_num_set(0, _len); }
void set_range(size_t from, size_t to) {
memset(_arr + from, 1, to - from);
}
void clear_range(size_t from, size_t to) {
memset(_arr + from, 0, to - from);
}
bool at(size_t pos) const {
return _arr[pos] == 1;
}
};
///////////////////////////////////////////////////////////
// Helper class for generating random allocation sizes
class RandSizeGenerator {
const size_t _min; // [
const size_t _max; // )
const float _outlier_chance; // 0.0 -- 1.0
const size_t _outlier_min; // [
const size_t _outlier_max; // )
public:
RandSizeGenerator(size_t min, size_t max) :
_min(min),
_max(max),
_outlier_chance(0.0),
_outlier_min(min),
_outlier_max(max)
{}
RandSizeGenerator(size_t min, size_t max, float outlier_chance, size_t outlier_min, size_t outlier_max) :
_min(min),
_max(max),
_outlier_chance(outlier_chance),
_outlier_min(outlier_min),
_outlier_max(outlier_max)
{}
size_t min() const { return _min; }
size_t max() const { return _max; }
size_t get() const {
size_t l1 = _min;
size_t l2 = _max;
int r = os::random() % 1000;
if ((float)r < _outlier_chance * 1000.0) {
l1 = _outlier_min;
l2 = _outlier_max;
}
const size_t d = l2 - l1;
return l1 + (os::random() % d);
}
}; // end RandSizeGenerator
size_t get_random_size(size_t min, size_t max);
///////////////////////////////////////////////////////////
// Function to test-access a memory range
void zap_range(MetaWord* p, size_t word_size);
// "fill_range_with_pattern" fills a range of heap words with pointers to itself.
//
// The idea is to fill a memory range with a pattern which is both marked clearly to the caller
// and cannot be moved without becoming invalid.
//
// The filled range can be checked with check_range_for_pattern. One also can only check
// a sub range of the original range.
void fill_range_with_pattern(MetaWord* p, uintx pattern, size_t word_size);
void check_range_for_pattern(const MetaWord* p, uintx pattern, size_t word_size);
// Writes a uniqe pattern to p
void mark_address(MetaWord* p, uintx pattern);
// checks pattern at address
void check_marked_address(const MetaWord* p, uintx pattern);
// Similar to fill_range_with_pattern, but only marks start and end. This is optimized for cases
// where fill_range_with_pattern just is too slow.
// Use check_marked_range to check the range. In contrast to check_range_for_pattern, only the original
// range can be checked.
void mark_range(MetaWord* p, uintx pattern, size_t word_size);
void check_marked_range(const MetaWord* p, uintx pattern, size_t word_size);
void mark_range(MetaWord* p, size_t word_size);
void check_marked_range(const MetaWord* p, size_t word_size);
//////////////////////////////////////////////////////////
// Some helpers to avoid typing out those annoying casts for nullptr
#define ASSERT_NOT_NULL(ptr) ASSERT_NE(nullptr, (void*)ptr)
#define ASSERT_NULL(ptr) ASSERT_EQ(nullptr, (void*)ptr)
#define EXPECT_NOT_NULL(ptr) EXPECT_NE(nullptr, (void*)ptr)
#define EXPECT_NULL(ptr) EXPECT_EQ(nullptr, (void*)ptr)
#define ASSERT_0(v) ASSERT_EQ((intptr_t)0, (intptr_t)v)
#define ASSERT_NOT_0(v) ASSERT_NE((intptr_t)0, (intptr_t)v)
#define EXPECT_0(v) EXPECT_EQ((intptr_t)0, (intptr_t)v)
#define EXPECT_NOT_0(v) EXPECT_NE((intptr_t)0, (intptr_t)v)
#define ASSERT_GT0(v) ASSERT_GT((intptr_t)v, (intptr_t)0)
#define EXPECT_GT0(v) EXPECT_GT((intptr_t)v, (intptr_t)0)
//////////////////////////////////////////////////////////
// logging
// Define "LOG_PLEASE" to switch on logging for a particular test before inclusion of this header.
#ifdef LOG_PLEASE
#define LOG(...) { printf(__VA_ARGS__); printf("\n"); fflush(stdout); }
#else
#define LOG(...)
#endif
//////////////////////////////////////////////////////////
// Helper
size_t get_workingset_size();
// A simple preallocated buffer used to "feed" someone.
// Mimicks chunk retirement leftover blocks.
class FeederBuffer {
MetaWord* _buf;
// Buffer capacity in size of words.
const size_t _cap;
// Used words.
size_t _used;
public:
FeederBuffer(size_t size) : _buf(nullptr), _cap(size), _used(0) {
_buf = NEW_C_HEAP_ARRAY(MetaWord, _cap, mtInternal);
}
~FeederBuffer() {
FREE_C_HEAP_ARRAY(MetaWord, _buf);
}
MetaWord* get(size_t word_size) {
if (_used + word_size > _cap) {
return nullptr;
}
MetaWord* p = _buf + _used;
_used += word_size;
return p;
}
bool is_valid_pointer(MetaWord* p) const {
return p >= _buf && p < _buf + _used;
}
bool is_valid_range(MetaWord* p, size_t word_size) const {
return is_valid_pointer(p) &&
word_size > 0 ? is_valid_pointer(p + word_size - 1) : true;
}
};
#endif // GTEST_METASPACE_METASPACEGTESTCOMMON_HPP
|