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