Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/hotspot/gtest/metaspace/test_freeblocks.cpp
41144 views
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
#include "precompiled.hpp"
27
#include "memory/metaspace/counters.hpp"
28
#include "memory/metaspace/freeBlocks.hpp"
29
//#define LOG_PLEASE
30
#include "metaspaceGtestCommon.hpp"
31
32
using metaspace::FreeBlocks;
33
using metaspace::SizeCounter;
34
35
#define CHECK_CONTENT(fb, num_blocks_expected, word_size_expected) \
36
{ \
37
if (word_size_expected > 0) { \
38
EXPECT_FALSE(fb.is_empty()); \
39
} else { \
40
EXPECT_TRUE(fb.is_empty()); \
41
} \
42
EXPECT_EQ(fb.total_size(), (size_t)word_size_expected); \
43
EXPECT_EQ(fb.count(), (int)num_blocks_expected); \
44
}
45
46
class FreeBlocksTest {
47
48
FeederBuffer _fb;
49
FreeBlocks _freeblocks;
50
51
// random generator for block feeding
52
RandSizeGenerator _rgen_feeding;
53
54
// random generator for allocations (and, hence, deallocations)
55
RandSizeGenerator _rgen_allocations;
56
57
SizeCounter _allocated_words;
58
59
struct allocation_t {
60
allocation_t* next;
61
size_t word_size;
62
MetaWord* p;
63
};
64
65
// Array of the same size as the pool max capacity; holds the allocated elements.
66
allocation_t* _allocations;
67
68
int _num_allocs;
69
int _num_deallocs;
70
int _num_feeds;
71
72
bool feed_some() {
73
size_t word_size = _rgen_feeding.get();
74
MetaWord* p = _fb.get(word_size);
75
if (p != NULL) {
76
_freeblocks.add_block(p, word_size);
77
return true;
78
}
79
return false;
80
}
81
82
void deallocate_top() {
83
84
allocation_t* a = _allocations;
85
if (a != NULL) {
86
_allocations = a->next;
87
check_marked_range(a->p, a->word_size);
88
_freeblocks.add_block(a->p, a->word_size);
89
delete a;
90
DEBUG_ONLY(_freeblocks.verify();)
91
}
92
}
93
94
bool allocate() {
95
96
size_t word_size = MAX2(_rgen_allocations.get(), _freeblocks.MinWordSize);
97
MetaWord* p = _freeblocks.remove_block(word_size);
98
if (p != NULL) {
99
_allocated_words.increment_by(word_size);
100
allocation_t* a = new allocation_t;
101
a->p = p; a->word_size = word_size;
102
a->next = _allocations;
103
_allocations = a;
104
DEBUG_ONLY(_freeblocks.verify();)
105
mark_range(p, word_size);
106
return true;
107
}
108
return false;
109
}
110
111
void test_all_marked_ranges() {
112
for (allocation_t* a = _allocations; a != NULL; a = a->next) {
113
check_marked_range(a->p, a->word_size);
114
}
115
}
116
117
void test_loop() {
118
// We loop and in each iteration execute one of three operations:
119
// - allocation from fbl
120
// - deallocation to fbl of a previously allocated block
121
// - feeding a new larger block into the fbl (mimicks chunk retiring)
122
// When we have fed all large blocks into the fbl (feedbuffer empty), we
123
// switch to draining the fbl completely (only allocs)
124
bool forcefeed = false;
125
bool draining = false;
126
bool stop = false;
127
int iter = 100000; // safety stop
128
while (!stop && iter > 0) {
129
iter --;
130
int surprise = (int)os::random() % 10;
131
if (!draining && (surprise >= 7 || forcefeed)) {
132
forcefeed = false;
133
if (feed_some()) {
134
_num_feeds++;
135
} else {
136
// We fed all input memory into the fbl. Now lets proceed until the fbl is drained.
137
draining = true;
138
}
139
} else if (!draining && surprise < 1) {
140
deallocate_top();
141
_num_deallocs++;
142
} else {
143
if (allocate()) {
144
_num_allocs++;
145
} else {
146
if (draining) {
147
stop = _freeblocks.total_size() < 512;
148
} else {
149
forcefeed = true;
150
}
151
}
152
}
153
if ((iter % 1000) == 0) {
154
DEBUG_ONLY(_freeblocks.verify();)
155
test_all_marked_ranges();
156
LOG("a %d (" SIZE_FORMAT "), d %d, f %d", _num_allocs, _allocated_words.get(), _num_deallocs, _num_feeds);
157
#ifdef LOG_PLEASE
158
_freeblocks.print(tty, true);
159
tty->cr();
160
#endif
161
}
162
}
163
164
// Drain
165
166
}
167
168
public:
169
170
FreeBlocksTest(size_t avg_alloc_size) :
171
_fb(512 * K), _freeblocks(),
172
_rgen_feeding(128, 4096),
173
_rgen_allocations(avg_alloc_size / 4, avg_alloc_size * 2, 0.01f, avg_alloc_size / 3, avg_alloc_size * 30),
174
_allocations(NULL),
175
_num_allocs(0),
176
_num_deallocs(0),
177
_num_feeds(0)
178
{
179
CHECK_CONTENT(_freeblocks, 0, 0);
180
// some initial feeding
181
_freeblocks.add_block(_fb.get(1024), 1024);
182
CHECK_CONTENT(_freeblocks, 1, 1024);
183
}
184
185
static void test_small_allocations() {
186
FreeBlocksTest test(10);
187
test.test_loop();
188
}
189
190
static void test_medium_allocations() {
191
FreeBlocksTest test(30);
192
test.test_loop();
193
}
194
195
static void test_large_allocations() {
196
FreeBlocksTest test(150);
197
test.test_loop();
198
}
199
200
};
201
202
TEST_VM(metaspace, freeblocks_basics) {
203
204
FreeBlocks fbl;
205
MetaWord tmp[1024];
206
CHECK_CONTENT(fbl, 0, 0);
207
208
fbl.add_block(tmp, 1024);
209
DEBUG_ONLY(fbl.verify();)
210
ASSERT_FALSE(fbl.is_empty());
211
CHECK_CONTENT(fbl, 1, 1024);
212
213
MetaWord* p = fbl.remove_block(1024);
214
EXPECT_EQ(p, tmp);
215
DEBUG_ONLY(fbl.verify();)
216
CHECK_CONTENT(fbl, 0, 0);
217
218
}
219
220
TEST_VM(metaspace, freeblocks_small) {
221
FreeBlocksTest::test_small_allocations();
222
}
223
224
TEST_VM(metaspace, freeblocks_medium) {
225
FreeBlocksTest::test_medium_allocations();
226
}
227
228
TEST_VM(metaspace, freeblocks_large) {
229
FreeBlocksTest::test_large_allocations();
230
}
231
232
233