c1281e6b45
Reviewed-by: kbarrett, dholmes, jwaters
220 lines
6.7 KiB
C++
220 lines
6.7 KiB
C++
/*
|
|
* 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
|