Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/hotspot/gtest/runtime/test_virtualMemoryTracker.cpp
41145 views
1
/*
2
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*/
23
24
#include "precompiled.hpp"
25
26
// Included early because the NMT flags don't include it.
27
#include "utilities/macros.hpp"
28
29
#if INCLUDE_NMT
30
31
#include "services/memTracker.hpp"
32
#include "services/virtualMemoryTracker.hpp"
33
#include "utilities/globalDefinitions.hpp"
34
#include "unittest.hpp"
35
36
namespace {
37
struct R {
38
address _addr;
39
size_t _size;
40
};
41
}
42
43
#define check(rmr, regions) check_inner((rmr), (regions), ARRAY_SIZE(regions), __FILE__, __LINE__)
44
45
#define check_empty(rmr) \
46
do { \
47
check_inner((rmr), NULL, 0, __FILE__, __LINE__); \
48
} while (false)
49
50
static void check_inner(ReservedMemoryRegion* rmr, R* regions, size_t regions_size, const char* file, int line) {
51
CommittedRegionIterator iter = rmr->iterate_committed_regions();
52
size_t i = 0;
53
size_t size = 0;
54
55
#define WHERE " from " << file << ":" << line
56
57
for (const CommittedMemoryRegion* region = iter.next(); region != NULL; region = iter.next()) {
58
EXPECT_LT(i, regions_size) << WHERE;
59
EXPECT_EQ(region->base(), regions[i]._addr) << WHERE;
60
EXPECT_EQ(region->size(), regions[i]._size) << WHERE;
61
size += region->size();
62
i++;
63
}
64
65
EXPECT_EQ(i, regions_size) << WHERE;
66
EXPECT_EQ(size, rmr->committed_size()) << WHERE;
67
}
68
69
class VirtualMemoryTrackerTest {
70
public:
71
static void test_add_committed_region_adjacent() {
72
VirtualMemoryTracker::initialize(NMT_detail);
73
VirtualMemoryTracker::late_initialize(NMT_detail);
74
75
address addr = (address)0x10000000;
76
size_t size = 0x01000000;
77
78
address frame1 = (address)0x1234;
79
address frame2 = (address)0x1235;
80
81
NativeCallStack stack(&frame1, 1);
82
NativeCallStack stack2(&frame2, 1);
83
84
// Add the reserved memory
85
VirtualMemoryTracker::add_reserved_region(addr, size, stack, mtTest);
86
87
// Fetch the added RMR added above
88
ReservedMemoryRegion* rmr = VirtualMemoryTracker::_reserved_regions->find(ReservedMemoryRegion(addr, size));
89
90
ASSERT_EQ(rmr->size(), size);
91
ASSERT_EQ(rmr->base(), addr);
92
93
// Commit Size Granularity
94
const size_t cs = 0x1000;
95
96
// Commit adjacent regions with same stack
97
98
{ // Commit one region
99
rmr->add_committed_region(addr + cs, cs, stack);
100
R r[] = { {addr + cs, cs} };
101
check(rmr, r);
102
}
103
104
{ // Commit adjacent - lower address
105
rmr->add_committed_region(addr, cs, stack);
106
R r[] = { {addr, 2 * cs} };
107
check(rmr, r);
108
}
109
110
{ // Commit adjacent - higher address
111
rmr->add_committed_region(addr + 2 * cs, cs, stack);
112
R r[] = { {addr, 3 * cs} };
113
check(rmr, r);
114
}
115
116
// Cleanup
117
rmr->remove_uncommitted_region(addr, 3 * cs);
118
ASSERT_EQ(rmr->committed_size(), 0u);
119
120
121
// Commit adjacent regions with different stacks
122
123
{ // Commit one region
124
rmr->add_committed_region(addr + cs, cs, stack);
125
R r[] = { {addr + cs, cs} };
126
check(rmr, r);
127
}
128
129
{ // Commit adjacent - lower address
130
rmr->add_committed_region(addr, cs, stack2);
131
R r[] = { {addr, cs},
132
{addr + cs, cs} };
133
check(rmr, r);
134
}
135
136
{ // Commit adjacent - higher address
137
rmr->add_committed_region(addr + 2 * cs, cs, stack2);
138
R r[] = { {addr, cs},
139
{addr + cs, cs},
140
{addr + 2 * cs, cs} };
141
check(rmr, r);
142
}
143
144
// Cleanup
145
rmr->remove_uncommitted_region(addr, 3 * cs);
146
ASSERT_EQ(rmr->committed_size(), 0u);
147
}
148
149
static void test_add_committed_region_adjacent_overlapping() {
150
VirtualMemoryTracker::initialize(NMT_detail);
151
VirtualMemoryTracker::late_initialize(NMT_detail);
152
153
address addr = (address)0x10000000;
154
size_t size = 0x01000000;
155
156
address frame1 = (address)0x1234;
157
address frame2 = (address)0x1235;
158
159
NativeCallStack stack(&frame1, 1);
160
NativeCallStack stack2(&frame2, 1);
161
162
// Add the reserved memory
163
VirtualMemoryTracker::add_reserved_region(addr, size, stack, mtTest);
164
165
// Fetch the added RMR added above
166
ReservedMemoryRegion* rmr = VirtualMemoryTracker::_reserved_regions->find(ReservedMemoryRegion(addr, size));
167
168
ASSERT_EQ(rmr->size(), size);
169
ASSERT_EQ(rmr->base(), addr);
170
171
// Commit Size Granularity
172
const size_t cs = 0x1000;
173
174
// Commit adjacent and overlapping regions with same stack
175
176
{ // Commit two non-adjacent regions
177
rmr->add_committed_region(addr, 2 * cs, stack);
178
rmr->add_committed_region(addr + 3 * cs, 2 * cs, stack);
179
R r[] = { {addr, 2 * cs},
180
{addr + 3 * cs, 2 * cs} };
181
check(rmr, r);
182
}
183
184
{ // Commit adjacent and overlapping
185
rmr->add_committed_region(addr + 2 * cs, 2 * cs, stack);
186
R r[] = { {addr, 5 * cs} };
187
check(rmr, r);
188
}
189
190
// revert to two non-adjacent regions
191
rmr->remove_uncommitted_region(addr + 2 * cs, cs);
192
ASSERT_EQ(rmr->committed_size(), 4 * cs);
193
194
{ // Commit overlapping and adjacent
195
rmr->add_committed_region(addr + cs, 2 * cs, stack);
196
R r[] = { {addr, 5 * cs} };
197
check(rmr, r);
198
}
199
200
// Cleanup
201
rmr->remove_uncommitted_region(addr, 5 * cs);
202
ASSERT_EQ(rmr->committed_size(), 0u);
203
204
205
// Commit adjacent and overlapping regions with different stacks
206
207
{ // Commit two non-adjacent regions
208
rmr->add_committed_region(addr, 2 * cs, stack);
209
rmr->add_committed_region(addr + 3 * cs, 2 * cs, stack);
210
R r[] = { {addr, 2 * cs},
211
{addr + 3 * cs, 2 * cs} };
212
check(rmr, r);
213
}
214
215
{ // Commit adjacent and overlapping
216
rmr->add_committed_region(addr + 2 * cs, 2 * cs, stack2);
217
R r[] = { {addr, 2 * cs},
218
{addr + 2 * cs, 2 * cs},
219
{addr + 4 * cs, cs} };
220
check(rmr, r);
221
}
222
223
// revert to two non-adjacent regions
224
rmr->add_committed_region(addr, 5 * cs, stack);
225
rmr->remove_uncommitted_region(addr + 2 * cs, cs);
226
ASSERT_EQ(rmr->committed_size(), 4 * cs);
227
228
{ // Commit overlapping and adjacent
229
rmr->add_committed_region(addr + cs, 2 * cs, stack2);
230
R r[] = { {addr, cs},
231
{addr + cs, 2 * cs},
232
{addr + 3 * cs, 2 * cs} };
233
check(rmr, r);
234
}
235
}
236
237
static void test_add_committed_region_overlapping() {
238
VirtualMemoryTracker::initialize(NMT_detail);
239
VirtualMemoryTracker::late_initialize(NMT_detail);
240
241
address addr = (address)0x10000000;
242
size_t size = 0x01000000;
243
244
address frame1 = (address)0x1234;
245
address frame2 = (address)0x1235;
246
247
NativeCallStack stack(&frame1, 1);
248
NativeCallStack stack2(&frame2, 1);
249
250
// Add the reserved memory
251
VirtualMemoryTracker::add_reserved_region(addr, size, stack, mtTest);
252
253
// Fetch the added RMR added above
254
ReservedMemoryRegion* rmr = VirtualMemoryTracker::_reserved_regions->find(ReservedMemoryRegion(addr, size));
255
256
ASSERT_EQ(rmr->size(), size);
257
ASSERT_EQ(rmr->base(), addr);
258
259
// Commit Size Granularity
260
const size_t cs = 0x1000;
261
262
// With same stack
263
264
{ // Commit one region
265
rmr->add_committed_region(addr, cs, stack);
266
R r[] = { {addr, cs} };
267
check(rmr, r);
268
}
269
270
{ // Commit the same region
271
rmr->add_committed_region(addr, cs, stack);
272
R r[] = { {addr, cs} };
273
check(rmr, r);
274
}
275
276
{ // Commit a succeeding region
277
rmr->add_committed_region(addr + cs, cs, stack);
278
R r[] = { {addr, 2 * cs} };
279
check(rmr, r);
280
}
281
282
{ // Commit over two regions
283
rmr->add_committed_region(addr, 2 * cs, stack);
284
R r[] = { {addr, 2 * cs} };
285
check(rmr, r);
286
}
287
288
{// Commit first part of a region
289
rmr->add_committed_region(addr, cs, stack);
290
R r[] = { {addr, 2 * cs} };
291
check(rmr, r);
292
}
293
294
{ // Commit second part of a region
295
rmr->add_committed_region(addr + cs, cs, stack);
296
R r[] = { {addr, 2 * cs} };
297
check(rmr, r);
298
}
299
300
{ // Commit a third part
301
rmr->add_committed_region(addr + 2 * cs, cs, stack);
302
R r[] = { {addr, 3 * cs} };
303
check(rmr, r);
304
}
305
306
{ // Commit in the middle of a region
307
rmr->add_committed_region(addr + 1 * cs, cs, stack);
308
R r[] = { {addr, 3 * cs} };
309
check(rmr, r);
310
}
311
312
// Cleanup
313
rmr->remove_uncommitted_region(addr, 3 * cs);
314
ASSERT_EQ(rmr->committed_size(), 0u);
315
316
// With preceding region
317
318
rmr->add_committed_region(addr, cs, stack);
319
rmr->add_committed_region(addr + 2 * cs, 3 * cs, stack);
320
321
rmr->add_committed_region(addr + 2 * cs, cs, stack);
322
{
323
R r[] = { {addr, cs},
324
{addr + 2 * cs, 3 * cs} };
325
check(rmr, r);
326
}
327
328
rmr->add_committed_region(addr + 3 * cs, cs, stack);
329
{
330
R r[] = { {addr, cs},
331
{addr + 2 * cs, 3 * cs} };
332
check(rmr, r);
333
}
334
335
rmr->add_committed_region(addr + 4 * cs, cs, stack);
336
{
337
R r[] = { {addr, cs},
338
{addr + 2 * cs, 3 * cs} };
339
check(rmr, r);
340
}
341
342
// Cleanup
343
rmr->remove_uncommitted_region(addr, 5 * cs);
344
ASSERT_EQ(rmr->committed_size(), 0u);
345
346
// With different stacks
347
348
{ // Commit one region
349
rmr->add_committed_region(addr, cs, stack);
350
R r[] = { {addr, cs} };
351
check(rmr, r);
352
}
353
354
{ // Commit the same region
355
rmr->add_committed_region(addr, cs, stack2);
356
R r[] = { {addr, cs} };
357
check(rmr, r);
358
}
359
360
{ // Commit a succeeding region
361
rmr->add_committed_region(addr + cs, cs, stack);
362
R r[] = { {addr, cs},
363
{addr + cs, cs} };
364
check(rmr, r);
365
}
366
367
{ // Commit over two regions
368
rmr->add_committed_region(addr, 2 * cs, stack);
369
R r[] = { {addr, 2 * cs} };
370
check(rmr, r);
371
}
372
373
{// Commit first part of a region
374
rmr->add_committed_region(addr, cs, stack2);
375
R r[] = { {addr, cs},
376
{addr + cs, cs} };
377
check(rmr, r);
378
}
379
380
{ // Commit second part of a region
381
rmr->add_committed_region(addr + cs, cs, stack2);
382
R r[] = { {addr, 2 * cs} };
383
check(rmr, r);
384
}
385
386
{ // Commit a third part
387
rmr->add_committed_region(addr + 2 * cs, cs, stack2);
388
R r[] = { {addr, 3 * cs} };
389
check(rmr, r);
390
}
391
392
{ // Commit in the middle of a region
393
rmr->add_committed_region(addr + 1 * cs, cs, stack);
394
R r[] = { {addr, cs},
395
{addr + cs, cs},
396
{addr + 2 * cs, cs} };
397
check(rmr, r);
398
}
399
}
400
401
static void test_add_committed_region() {
402
test_add_committed_region_adjacent();
403
test_add_committed_region_adjacent_overlapping();
404
test_add_committed_region_overlapping();
405
}
406
407
template <size_t S>
408
static void fix(R r[S]) {
409
410
}
411
412
static void test_remove_uncommitted_region() {
413
VirtualMemoryTracker::initialize(NMT_detail);
414
VirtualMemoryTracker::late_initialize(NMT_detail);
415
416
address addr = (address)0x10000000;
417
size_t size = 0x01000000;
418
419
address frame1 = (address)0x1234;
420
address frame2 = (address)0x1235;
421
422
NativeCallStack stack(&frame1, 1);
423
NativeCallStack stack2(&frame2, 1);
424
425
// Add the reserved memory
426
VirtualMemoryTracker::add_reserved_region(addr, size, stack, mtTest);
427
428
// Fetch the added RMR added above
429
ReservedMemoryRegion* rmr = VirtualMemoryTracker::_reserved_regions->find(ReservedMemoryRegion(addr, size));
430
431
ASSERT_EQ(rmr->size(), size);
432
ASSERT_EQ(rmr->base(), addr);
433
434
// Commit Size Granularity
435
const size_t cs = 0x1000;
436
437
{ // Commit regions
438
rmr->add_committed_region(addr, 3 * cs, stack);
439
R r[] = { {addr, 3 * cs} };
440
check(rmr, r);
441
442
// Remove only existing
443
rmr->remove_uncommitted_region(addr, 3 * cs);
444
check_empty(rmr);
445
}
446
447
{
448
rmr->add_committed_region(addr + 0 * cs, cs, stack);
449
rmr->add_committed_region(addr + 2 * cs, cs, stack);
450
rmr->add_committed_region(addr + 4 * cs, cs, stack);
451
452
{ // Remove first
453
rmr->remove_uncommitted_region(addr, cs);
454
R r[] = { {addr + 2 * cs, cs},
455
{addr + 4 * cs, cs} };
456
check(rmr, r);
457
}
458
459
// add back
460
rmr->add_committed_region(addr, cs, stack);
461
462
{ // Remove middle
463
rmr->remove_uncommitted_region(addr + 2 * cs, cs);
464
R r[] = { {addr + 0 * cs, cs},
465
{addr + 4 * cs, cs} };
466
check(rmr, r);
467
}
468
469
// add back
470
rmr->add_committed_region(addr + 2 * cs, cs, stack);
471
472
{ // Remove end
473
rmr->remove_uncommitted_region(addr + 4 * cs, cs);
474
R r[] = { {addr + 0 * cs, cs},
475
{addr + 2 * cs, cs} };
476
check(rmr, r);
477
}
478
479
rmr->remove_uncommitted_region(addr, 5 * cs);
480
check_empty(rmr);
481
}
482
483
{ // Remove larger region
484
rmr->add_committed_region(addr + 1 * cs, cs, stack);
485
rmr->remove_uncommitted_region(addr, 3 * cs);
486
check_empty(rmr);
487
}
488
489
{ // Remove smaller region - in the middle
490
rmr->add_committed_region(addr, 3 * cs, stack);
491
rmr->remove_uncommitted_region(addr + 1 * cs, cs);
492
R r[] = { { addr + 0 * cs, cs},
493
{ addr + 2 * cs, cs} };
494
check(rmr, r);
495
496
rmr->remove_uncommitted_region(addr, 3 * cs);
497
check_empty(rmr);
498
}
499
500
{ // Remove smaller region - at the beginning
501
rmr->add_committed_region(addr, 3 * cs, stack);
502
rmr->remove_uncommitted_region(addr + 0 * cs, cs);
503
R r[] = { { addr + 1 * cs, 2 * cs} };
504
check(rmr, r);
505
506
rmr->remove_uncommitted_region(addr, 3 * cs);
507
check_empty(rmr);
508
}
509
510
{ // Remove smaller region - at the end
511
rmr->add_committed_region(addr, 3 * cs, stack);
512
rmr->remove_uncommitted_region(addr + 2 * cs, cs);
513
R r[] = { { addr, 2 * cs} };
514
check(rmr, r);
515
516
rmr->remove_uncommitted_region(addr, 3 * cs);
517
check_empty(rmr);
518
}
519
520
{ // Remove smaller, overlapping region - at the beginning
521
rmr->add_committed_region(addr + 1 * cs, 4 * cs, stack);
522
rmr->remove_uncommitted_region(addr, 2 * cs);
523
R r[] = { { addr + 2 * cs, 3 * cs} };
524
check(rmr, r);
525
526
rmr->remove_uncommitted_region(addr + 1 * cs, 4 * cs);
527
check_empty(rmr);
528
}
529
530
{ // Remove smaller, overlapping region - at the end
531
rmr->add_committed_region(addr, 3 * cs, stack);
532
rmr->remove_uncommitted_region(addr + 2 * cs, 2 * cs);
533
R r[] = { { addr, 2 * cs} };
534
check(rmr, r);
535
536
rmr->remove_uncommitted_region(addr, 3 * cs);
537
check_empty(rmr);
538
}
539
}
540
};
541
542
TEST_VM(VirtualMemoryTracker, add_committed_region) {
543
VirtualMemoryTrackerTest::test_add_committed_region();
544
}
545
546
TEST_VM(VirtualMemoryTracker, remove_uncommitted_region) {
547
VirtualMemoryTrackerTest::test_remove_uncommitted_region();
548
}
549
550
#endif // INCLUDE_NMT
551
552