Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/jdk17u
Path: blob/master/test/hotspot/gtest/runtime/test_virtualMemoryTracker.cpp
64438 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
// Tests here test the VM-global NMT facility.
25
// The tests must *not* modify global state! E.g. switch NMT on or off. Instead, they
26
// should work passively with whatever setting the gtestlauncher had been started with
27
// - if NMT is enabled, test NMT, otherwise do whatever minimal tests make sense if NMT
28
// is off.
29
//
30
// The gtestLauncher then are called with various levels of -XX:NativeMemoryTracking during
31
// jtreg-controlled gtests (see test/hotspot/jtreg/gtest/NMTGtests.java)
32
33
#include "precompiled.hpp"
34
35
// Included early because the NMT flags don't include it.
36
#include "utilities/macros.hpp"
37
38
#if INCLUDE_NMT
39
40
#include "memory/virtualspace.hpp"
41
#include "services/memTracker.hpp"
42
#include "services/virtualMemoryTracker.hpp"
43
#include "utilities/globalDefinitions.hpp"
44
#include "unittest.hpp"
45
#include <stdio.h>
46
47
// #define LOG(...) printf(__VA_ARGS__); printf("\n"); fflush(stdout);
48
#define LOG(...)
49
50
namespace {
51
struct R {
52
address _addr;
53
size_t _size;
54
};
55
}
56
57
#define check(rmr, regions) check_inner((rmr), (regions), ARRAY_SIZE(regions), __FILE__, __LINE__)
58
59
#define check_empty(rmr) \
60
do { \
61
check_inner((rmr), NULL, 0, __FILE__, __LINE__); \
62
} while (false)
63
64
static void diagnostic_print(ReservedMemoryRegion* rmr) {
65
CommittedRegionIterator iter = rmr->iterate_committed_regions();
66
LOG("In reserved region " PTR_FORMAT ", size " SIZE_FORMAT_HEX ":", p2i(rmr->base()), rmr->size());
67
for (const CommittedMemoryRegion* region = iter.next(); region != NULL; region = iter.next()) {
68
LOG(" committed region: " PTR_FORMAT ", size " SIZE_FORMAT_HEX, p2i(region->base()), region->size());
69
}
70
}
71
72
static void check_inner(ReservedMemoryRegion* rmr, R* regions, size_t regions_size, const char* file, int line) {
73
CommittedRegionIterator iter = rmr->iterate_committed_regions();
74
size_t i = 0;
75
size_t size = 0;
76
77
// Helpful log
78
diagnostic_print(rmr);
79
80
#define WHERE " from " << file << ":" << line
81
82
for (const CommittedMemoryRegion* region = iter.next(); region != NULL; region = iter.next()) {
83
EXPECT_LT(i, regions_size) << WHERE;
84
EXPECT_EQ(region->base(), regions[i]._addr) << WHERE;
85
EXPECT_EQ(region->size(), regions[i]._size) << WHERE;
86
size += region->size();
87
i++;
88
}
89
90
EXPECT_EQ(i, regions_size) << WHERE;
91
EXPECT_EQ(size, rmr->committed_size()) << WHERE;
92
}
93
94
class VirtualMemoryTrackerTest {
95
public:
96
static void test_add_committed_region_adjacent() {
97
98
size_t size = 0x01000000;
99
ReservedSpace rs(size);
100
address addr = (address)rs.base();
101
102
address frame1 = (address)0x1234;
103
address frame2 = (address)0x1235;
104
105
NativeCallStack stack(&frame1, 1);
106
NativeCallStack stack2(&frame2, 1);
107
108
// Fetch the added RMR for the space
109
ReservedMemoryRegion* rmr = VirtualMemoryTracker::_reserved_regions->find(ReservedMemoryRegion(addr, size));
110
111
ASSERT_EQ(rmr->size(), size);
112
ASSERT_EQ(rmr->base(), addr);
113
114
// Commit Size Granularity
115
const size_t cs = 0x1000;
116
117
// Commit adjacent regions with same stack
118
119
{ // Commit one region
120
rmr->add_committed_region(addr + cs, cs, stack);
121
R r[] = { {addr + cs, cs} };
122
check(rmr, r);
123
}
124
125
{ // Commit adjacent - lower address
126
rmr->add_committed_region(addr, cs, stack);
127
R r[] = { {addr, 2 * cs} };
128
check(rmr, r);
129
}
130
131
{ // Commit adjacent - higher address
132
rmr->add_committed_region(addr + 2 * cs, cs, stack);
133
R r[] = { {addr, 3 * cs} };
134
check(rmr, r);
135
}
136
137
// Cleanup
138
rmr->remove_uncommitted_region(addr, 3 * cs);
139
ASSERT_EQ(rmr->committed_size(), 0u);
140
141
142
// Commit adjacent regions with different stacks
143
144
{ // Commit one region
145
rmr->add_committed_region(addr + cs, cs, stack);
146
R r[] = { {addr + cs, cs} };
147
check(rmr, r);
148
}
149
150
{ // Commit adjacent - lower address
151
rmr->add_committed_region(addr, cs, stack2);
152
R r[] = { {addr, cs},
153
{addr + cs, cs} };
154
check(rmr, r);
155
}
156
157
{ // Commit adjacent - higher address
158
rmr->add_committed_region(addr + 2 * cs, cs, stack2);
159
R r[] = { {addr, cs},
160
{addr + cs, cs},
161
{addr + 2 * cs, cs} };
162
check(rmr, r);
163
}
164
165
// Cleanup
166
rmr->remove_uncommitted_region(addr, 3 * cs);
167
ASSERT_EQ(rmr->committed_size(), 0u);
168
}
169
170
static void test_add_committed_region_adjacent_overlapping() {
171
172
size_t size = 0x01000000;
173
ReservedSpace rs(size);
174
address addr = (address)rs.base();
175
176
address frame1 = (address)0x1234;
177
address frame2 = (address)0x1235;
178
179
NativeCallStack stack(&frame1, 1);
180
NativeCallStack stack2(&frame2, 1);
181
182
// Add the reserved memory
183
VirtualMemoryTracker::add_reserved_region(addr, size, stack, mtTest);
184
185
// Fetch the added RMR for the space
186
ReservedMemoryRegion* rmr = VirtualMemoryTracker::_reserved_regions->find(ReservedMemoryRegion(addr, size));
187
188
ASSERT_EQ(rmr->size(), size);
189
ASSERT_EQ(rmr->base(), addr);
190
191
// Commit Size Granularity
192
const size_t cs = 0x1000;
193
194
// Commit adjacent and overlapping regions with same stack
195
196
{ // Commit two non-adjacent regions
197
rmr->add_committed_region(addr, 2 * cs, stack);
198
rmr->add_committed_region(addr + 3 * cs, 2 * cs, stack);
199
R r[] = { {addr, 2 * cs},
200
{addr + 3 * cs, 2 * cs} };
201
check(rmr, r);
202
}
203
204
{ // Commit adjacent and overlapping
205
rmr->add_committed_region(addr + 2 * cs, 2 * cs, stack);
206
R r[] = { {addr, 5 * cs} };
207
check(rmr, r);
208
}
209
210
// revert to two non-adjacent regions
211
rmr->remove_uncommitted_region(addr + 2 * cs, cs);
212
ASSERT_EQ(rmr->committed_size(), 4 * cs);
213
214
{ // Commit overlapping and adjacent
215
rmr->add_committed_region(addr + cs, 2 * cs, stack);
216
R r[] = { {addr, 5 * cs} };
217
check(rmr, r);
218
}
219
220
// Cleanup
221
rmr->remove_uncommitted_region(addr, 5 * cs);
222
ASSERT_EQ(rmr->committed_size(), 0u);
223
224
225
// Commit adjacent and overlapping regions with different stacks
226
227
{ // Commit two non-adjacent regions
228
rmr->add_committed_region(addr, 2 * cs, stack);
229
rmr->add_committed_region(addr + 3 * cs, 2 * cs, stack);
230
R r[] = { {addr, 2 * cs},
231
{addr + 3 * cs, 2 * cs} };
232
check(rmr, r);
233
}
234
235
{ // Commit adjacent and overlapping
236
rmr->add_committed_region(addr + 2 * cs, 2 * cs, stack2);
237
R r[] = { {addr, 2 * cs},
238
{addr + 2 * cs, 2 * cs},
239
{addr + 4 * cs, cs} };
240
check(rmr, r);
241
}
242
243
// revert to two non-adjacent regions
244
rmr->add_committed_region(addr, 5 * cs, stack);
245
rmr->remove_uncommitted_region(addr + 2 * cs, cs);
246
ASSERT_EQ(rmr->committed_size(), 4 * cs);
247
248
{ // Commit overlapping and adjacent
249
rmr->add_committed_region(addr + cs, 2 * cs, stack2);
250
R r[] = { {addr, cs},
251
{addr + cs, 2 * cs},
252
{addr + 3 * cs, 2 * cs} };
253
check(rmr, r);
254
}
255
}
256
257
static void test_add_committed_region_overlapping() {
258
259
size_t size = 0x01000000;
260
ReservedSpace rs(size);
261
address addr = (address)rs.base();
262
263
address frame1 = (address)0x1234;
264
address frame2 = (address)0x1235;
265
266
NativeCallStack stack(&frame1, 1);
267
NativeCallStack stack2(&frame2, 1);
268
269
// Fetch the added RMR for the space
270
ReservedMemoryRegion* rmr = VirtualMemoryTracker::_reserved_regions->find(ReservedMemoryRegion(addr, size));
271
272
ASSERT_EQ(rmr->size(), size);
273
ASSERT_EQ(rmr->base(), addr);
274
275
// Commit Size Granularity
276
const size_t cs = 0x1000;
277
278
// With same stack
279
280
{ // Commit one region
281
rmr->add_committed_region(addr, cs, stack);
282
R r[] = { {addr, cs} };
283
check(rmr, r);
284
}
285
286
{ // Commit the same region
287
rmr->add_committed_region(addr, cs, stack);
288
R r[] = { {addr, cs} };
289
check(rmr, r);
290
}
291
292
{ // Commit a succeeding region
293
rmr->add_committed_region(addr + cs, cs, stack);
294
R r[] = { {addr, 2 * cs} };
295
check(rmr, r);
296
}
297
298
{ // Commit over two regions
299
rmr->add_committed_region(addr, 2 * cs, stack);
300
R r[] = { {addr, 2 * cs} };
301
check(rmr, r);
302
}
303
304
{// Commit first part of a region
305
rmr->add_committed_region(addr, cs, stack);
306
R r[] = { {addr, 2 * cs} };
307
check(rmr, r);
308
}
309
310
{ // Commit second part of a region
311
rmr->add_committed_region(addr + cs, cs, stack);
312
R r[] = { {addr, 2 * cs} };
313
check(rmr, r);
314
}
315
316
{ // Commit a third part
317
rmr->add_committed_region(addr + 2 * cs, cs, stack);
318
R r[] = { {addr, 3 * cs} };
319
check(rmr, r);
320
}
321
322
{ // Commit in the middle of a region
323
rmr->add_committed_region(addr + 1 * cs, cs, stack);
324
R r[] = { {addr, 3 * cs} };
325
check(rmr, r);
326
}
327
328
// Cleanup
329
rmr->remove_uncommitted_region(addr, 3 * cs);
330
ASSERT_EQ(rmr->committed_size(), 0u);
331
332
// With preceding region
333
334
rmr->add_committed_region(addr, cs, stack);
335
rmr->add_committed_region(addr + 2 * cs, 3 * cs, stack);
336
337
rmr->add_committed_region(addr + 2 * cs, cs, stack);
338
{
339
R r[] = { {addr, cs},
340
{addr + 2 * cs, 3 * cs} };
341
check(rmr, r);
342
}
343
344
rmr->add_committed_region(addr + 3 * cs, cs, stack);
345
{
346
R r[] = { {addr, cs},
347
{addr + 2 * cs, 3 * cs} };
348
check(rmr, r);
349
}
350
351
rmr->add_committed_region(addr + 4 * cs, cs, stack);
352
{
353
R r[] = { {addr, cs},
354
{addr + 2 * cs, 3 * cs} };
355
check(rmr, r);
356
}
357
358
// Cleanup
359
rmr->remove_uncommitted_region(addr, 5 * cs);
360
ASSERT_EQ(rmr->committed_size(), 0u);
361
362
// With different stacks
363
364
{ // Commit one region
365
rmr->add_committed_region(addr, cs, stack);
366
R r[] = { {addr, cs} };
367
check(rmr, r);
368
}
369
370
{ // Commit the same region
371
rmr->add_committed_region(addr, cs, stack2);
372
R r[] = { {addr, cs} };
373
check(rmr, r);
374
}
375
376
{ // Commit a succeeding region
377
rmr->add_committed_region(addr + cs, cs, stack);
378
R r[] = { {addr, cs},
379
{addr + cs, cs} };
380
check(rmr, r);
381
}
382
383
{ // Commit over two regions
384
rmr->add_committed_region(addr, 2 * cs, stack);
385
R r[] = { {addr, 2 * cs} };
386
check(rmr, r);
387
}
388
389
{// Commit first part of a region
390
rmr->add_committed_region(addr, cs, stack2);
391
R r[] = { {addr, cs},
392
{addr + cs, cs} };
393
check(rmr, r);
394
}
395
396
{ // Commit second part of a region
397
rmr->add_committed_region(addr + cs, cs, stack2);
398
R r[] = { {addr, 2 * cs} };
399
check(rmr, r);
400
}
401
402
{ // Commit a third part
403
rmr->add_committed_region(addr + 2 * cs, cs, stack2);
404
R r[] = { {addr, 3 * cs} };
405
check(rmr, r);
406
}
407
408
{ // Commit in the middle of a region
409
rmr->add_committed_region(addr + 1 * cs, cs, stack);
410
R r[] = { {addr, cs},
411
{addr + cs, cs},
412
{addr + 2 * cs, cs} };
413
check(rmr, r);
414
}
415
}
416
417
static void test_add_committed_region() {
418
test_add_committed_region_adjacent();
419
test_add_committed_region_adjacent_overlapping();
420
test_add_committed_region_overlapping();
421
}
422
423
template <size_t S>
424
static void fix(R r[S]) {
425
426
}
427
428
static void test_remove_uncommitted_region() {
429
430
size_t size = 0x01000000;
431
ReservedSpace rs(size);
432
address addr = (address)rs.base();
433
434
address frame1 = (address)0x1234;
435
address frame2 = (address)0x1235;
436
437
NativeCallStack stack(&frame1, 1);
438
NativeCallStack stack2(&frame2, 1);
439
440
// Fetch the added RMR for the space
441
ReservedMemoryRegion* rmr = VirtualMemoryTracker::_reserved_regions->find(ReservedMemoryRegion(addr, size));
442
443
ASSERT_EQ(rmr->size(), size);
444
ASSERT_EQ(rmr->base(), addr);
445
446
// Commit Size Granularity
447
const size_t cs = 0x1000;
448
449
{ // Commit regions
450
rmr->add_committed_region(addr, 3 * cs, stack);
451
R r[] = { {addr, 3 * cs} };
452
check(rmr, r);
453
454
// Remove only existing
455
rmr->remove_uncommitted_region(addr, 3 * cs);
456
check_empty(rmr);
457
}
458
459
{
460
rmr->add_committed_region(addr + 0 * cs, cs, stack);
461
rmr->add_committed_region(addr + 2 * cs, cs, stack);
462
rmr->add_committed_region(addr + 4 * cs, cs, stack);
463
464
{ // Remove first
465
rmr->remove_uncommitted_region(addr, cs);
466
R r[] = { {addr + 2 * cs, cs},
467
{addr + 4 * cs, cs} };
468
check(rmr, r);
469
}
470
471
// add back
472
rmr->add_committed_region(addr, cs, stack);
473
474
{ // Remove middle
475
rmr->remove_uncommitted_region(addr + 2 * cs, cs);
476
R r[] = { {addr + 0 * cs, cs},
477
{addr + 4 * cs, cs} };
478
check(rmr, r);
479
}
480
481
// add back
482
rmr->add_committed_region(addr + 2 * cs, cs, stack);
483
484
{ // Remove end
485
rmr->remove_uncommitted_region(addr + 4 * cs, cs);
486
R r[] = { {addr + 0 * cs, cs},
487
{addr + 2 * cs, cs} };
488
check(rmr, r);
489
}
490
491
rmr->remove_uncommitted_region(addr, 5 * cs);
492
check_empty(rmr);
493
}
494
495
{ // Remove larger region
496
rmr->add_committed_region(addr + 1 * cs, cs, stack);
497
rmr->remove_uncommitted_region(addr, 3 * cs);
498
check_empty(rmr);
499
}
500
501
{ // Remove smaller region - in the middle
502
rmr->add_committed_region(addr, 3 * cs, stack);
503
rmr->remove_uncommitted_region(addr + 1 * cs, cs);
504
R r[] = { { addr + 0 * cs, cs},
505
{ addr + 2 * cs, cs} };
506
check(rmr, r);
507
508
rmr->remove_uncommitted_region(addr, 3 * cs);
509
check_empty(rmr);
510
}
511
512
{ // Remove smaller region - at the beginning
513
rmr->add_committed_region(addr, 3 * cs, stack);
514
rmr->remove_uncommitted_region(addr + 0 * cs, cs);
515
R r[] = { { addr + 1 * cs, 2 * cs} };
516
check(rmr, r);
517
518
rmr->remove_uncommitted_region(addr, 3 * cs);
519
check_empty(rmr);
520
}
521
522
{ // Remove smaller region - at the end
523
rmr->add_committed_region(addr, 3 * cs, stack);
524
rmr->remove_uncommitted_region(addr + 2 * cs, cs);
525
R r[] = { { addr, 2 * cs} };
526
check(rmr, r);
527
528
rmr->remove_uncommitted_region(addr, 3 * cs);
529
check_empty(rmr);
530
}
531
532
{ // Remove smaller, overlapping region - at the beginning
533
rmr->add_committed_region(addr + 1 * cs, 4 * cs, stack);
534
rmr->remove_uncommitted_region(addr, 2 * cs);
535
R r[] = { { addr + 2 * cs, 3 * cs} };
536
check(rmr, r);
537
538
rmr->remove_uncommitted_region(addr + 1 * cs, 4 * cs);
539
check_empty(rmr);
540
}
541
542
{ // Remove smaller, overlapping region - at the end
543
rmr->add_committed_region(addr, 3 * cs, stack);
544
rmr->remove_uncommitted_region(addr + 2 * cs, 2 * cs);
545
R r[] = { { addr, 2 * cs} };
546
check(rmr, r);
547
548
rmr->remove_uncommitted_region(addr, 3 * cs);
549
check_empty(rmr);
550
}
551
}
552
};
553
554
TEST_VM(NMT_VirtualMemoryTracker, add_committed_region) {
555
if (MemTracker::tracking_level() >= NMT_detail) {
556
VirtualMemoryTrackerTest::test_add_committed_region();
557
} else {
558
tty->print_cr("skipped.");
559
}
560
}
561
562
TEST_VM(NMT_VirtualMemoryTracker, remove_uncommitted_region) {
563
if (MemTracker::tracking_level() >= NMT_detail) {
564
VirtualMemoryTrackerTest::test_remove_uncommitted_region();
565
} else {
566
tty->print_cr("skipped.");
567
}
568
}
569
570
#endif // INCLUDE_NMT
571
572