33
#include "precompiled.hpp"
35
#include "memory/virtualspace.hpp"
36
#include "nmt/memTracker.hpp"
37
#include "nmt/virtualMemoryTracker.hpp"
38
#include "utilities/globalDefinitions.hpp"
39
#include "utilities/macros.hpp"
40
#include "unittest.hpp"
54
#define check(rmr, regions) check_inner((rmr), (regions), ARRAY_SIZE(regions), __FILE__, __LINE__)
56
#define check_empty(rmr) \
58
check_inner((rmr), nullptr, 0, __FILE__, __LINE__); \
61
static void diagnostic_print(ReservedMemoryRegion* rmr) {
62
CommittedRegionIterator iter = rmr->iterate_committed_regions();
63
LOG("In reserved region " PTR_FORMAT ", size " SIZE_FORMAT_HEX ":", p2i(rmr->base()), rmr->size());
64
for (const CommittedMemoryRegion* region = iter.next(); region != nullptr; region = iter.next()) {
65
LOG(" committed region: " PTR_FORMAT ", size " SIZE_FORMAT_HEX, p2i(region->base()), region->size());
69
static void check_inner(ReservedMemoryRegion* rmr, R* regions, size_t regions_size, const char* file, int line) {
70
CommittedRegionIterator iter = rmr->iterate_committed_regions();
75
diagnostic_print(rmr);
77
#define WHERE " from " << file << ":" << line
79
for (const CommittedMemoryRegion* region = iter.next(); region != nullptr; region = iter.next()) {
80
EXPECT_LT(i, regions_size) << WHERE;
81
EXPECT_EQ(region->base(), regions[i]._addr) << WHERE;
82
EXPECT_EQ(region->size(), regions[i]._size) << WHERE;
83
size += region->size();
87
EXPECT_EQ(i, regions_size) << WHERE;
88
EXPECT_EQ(size, rmr->committed_size()) << WHERE;
91
class VirtualMemoryTrackerTest {
93
static void test_add_committed_region_adjacent() {
95
size_t size = 0x01000000;
96
ReservedSpace rs(size);
97
address addr = (address)rs.base();
99
address frame1 = (address)0x1234;
100
address frame2 = (address)0x1235;
102
NativeCallStack stack(&frame1, 1);
103
NativeCallStack stack2(&frame2, 1);
106
ReservedMemoryRegion* rmr = VirtualMemoryTracker::_reserved_regions->find(ReservedMemoryRegion(addr, size));
108
ASSERT_EQ(rmr->size(), size);
109
ASSERT_EQ(rmr->base(), addr);
112
const size_t cs = 0x1000;
117
rmr->add_committed_region(addr + cs, cs, stack);
118
R r[] = { {addr + cs, cs} };
123
rmr->add_committed_region(addr, cs, stack);
124
R r[] = { {addr, 2 * cs} };
129
rmr->add_committed_region(addr + 2 * cs, cs, stack);
130
R r[] = { {addr, 3 * cs} };
135
rmr->remove_uncommitted_region(addr, 3 * cs);
136
ASSERT_EQ(rmr->committed_size(), 0u);
142
rmr->add_committed_region(addr + cs, cs, stack);
143
R r[] = { {addr + cs, cs} };
148
rmr->add_committed_region(addr, cs, stack2);
149
R r[] = { {addr, cs},
155
rmr->add_committed_region(addr + 2 * cs, cs, stack2);
156
R r[] = { {addr, cs},
158
{addr + 2 * cs, cs} };
163
rmr->remove_uncommitted_region(addr, 3 * cs);
164
ASSERT_EQ(rmr->committed_size(), 0u);
167
static void test_add_committed_region_adjacent_overlapping() {
169
size_t size = 0x01000000;
170
ReservedSpace rs(size);
171
address addr = (address)rs.base();
173
address frame1 = (address)0x1234;
174
address frame2 = (address)0x1235;
176
NativeCallStack stack(&frame1, 1);
177
NativeCallStack stack2(&frame2, 1);
180
VirtualMemoryTracker::add_reserved_region(addr, size, stack, mtTest);
183
ReservedMemoryRegion* rmr = VirtualMemoryTracker::_reserved_regions->find(ReservedMemoryRegion(addr, size));
185
ASSERT_EQ(rmr->size(), size);
186
ASSERT_EQ(rmr->base(), addr);
189
const size_t cs = 0x1000;
194
rmr->add_committed_region(addr, 2 * cs, stack);
195
rmr->add_committed_region(addr + 3 * cs, 2 * cs, stack);
196
R r[] = { {addr, 2 * cs},
197
{addr + 3 * cs, 2 * cs} };
202
rmr->add_committed_region(addr + 2 * cs, 2 * cs, stack);
203
R r[] = { {addr, 5 * cs} };
208
rmr->remove_uncommitted_region(addr + 2 * cs, cs);
209
ASSERT_EQ(rmr->committed_size(), 4 * cs);
212
rmr->add_committed_region(addr + cs, 2 * cs, stack);
213
R r[] = { {addr, 5 * cs} };
218
rmr->remove_uncommitted_region(addr, 5 * cs);
219
ASSERT_EQ(rmr->committed_size(), 0u);
225
rmr->add_committed_region(addr, 2 * cs, stack);
226
rmr->add_committed_region(addr + 3 * cs, 2 * cs, stack);
227
R r[] = { {addr, 2 * cs},
228
{addr + 3 * cs, 2 * cs} };
233
rmr->add_committed_region(addr + 2 * cs, 2 * cs, stack2);
234
R r[] = { {addr, 2 * cs},
235
{addr + 2 * cs, 2 * cs},
236
{addr + 4 * cs, cs} };
241
rmr->add_committed_region(addr, 5 * cs, stack);
242
rmr->remove_uncommitted_region(addr + 2 * cs, cs);
243
ASSERT_EQ(rmr->committed_size(), 4 * cs);
246
rmr->add_committed_region(addr + cs, 2 * cs, stack2);
247
R r[] = { {addr, cs},
249
{addr + 3 * cs, 2 * cs} };
254
static void test_add_committed_region_overlapping() {
256
size_t size = 0x01000000;
257
ReservedSpace rs(size);
258
address addr = (address)rs.base();
260
address frame1 = (address)0x1234;
261
address frame2 = (address)0x1235;
263
NativeCallStack stack(&frame1, 1);
264
NativeCallStack stack2(&frame2, 1);
267
ReservedMemoryRegion* rmr = VirtualMemoryTracker::_reserved_regions->find(ReservedMemoryRegion(addr, size));
269
ASSERT_EQ(rmr->size(), size);
270
ASSERT_EQ(rmr->base(), addr);
273
const size_t cs = 0x1000;
278
rmr->add_committed_region(addr, cs, stack);
279
R r[] = { {addr, cs} };
284
rmr->add_committed_region(addr, cs, stack);
285
R r[] = { {addr, cs} };
290
rmr->add_committed_region(addr + cs, cs, stack);
291
R r[] = { {addr, 2 * cs} };
296
rmr->add_committed_region(addr, 2 * cs, stack);
297
R r[] = { {addr, 2 * cs} };
302
rmr->add_committed_region(addr, cs, stack);
303
R r[] = { {addr, 2 * cs} };
308
rmr->add_committed_region(addr + cs, cs, stack);
309
R r[] = { {addr, 2 * cs} };
314
rmr->add_committed_region(addr + 2 * cs, cs, stack);
315
R r[] = { {addr, 3 * cs} };
320
rmr->add_committed_region(addr + 1 * cs, cs, stack);
321
R r[] = { {addr, 3 * cs} };
326
rmr->remove_uncommitted_region(addr, 3 * cs);
327
ASSERT_EQ(rmr->committed_size(), 0u);
331
rmr->add_committed_region(addr, cs, stack);
332
rmr->add_committed_region(addr + 2 * cs, 3 * cs, stack);
334
rmr->add_committed_region(addr + 2 * cs, cs, stack);
336
R r[] = { {addr, cs},
337
{addr + 2 * cs, 3 * cs} };
341
rmr->add_committed_region(addr + 3 * cs, cs, stack);
343
R r[] = { {addr, cs},
344
{addr + 2 * cs, 3 * cs} };
348
rmr->add_committed_region(addr + 4 * cs, cs, stack);
350
R r[] = { {addr, cs},
351
{addr + 2 * cs, 3 * cs} };
356
rmr->remove_uncommitted_region(addr, 5 * cs);
357
ASSERT_EQ(rmr->committed_size(), 0u);
362
rmr->add_committed_region(addr, cs, stack);
363
R r[] = { {addr, cs} };
368
rmr->add_committed_region(addr, cs, stack2);
369
R r[] = { {addr, cs} };
374
rmr->add_committed_region(addr + cs, cs, stack);
375
R r[] = { {addr, cs},
381
rmr->add_committed_region(addr, 2 * cs, stack);
382
R r[] = { {addr, 2 * cs} };
387
rmr->add_committed_region(addr, cs, stack2);
388
R r[] = { {addr, cs},
394
rmr->add_committed_region(addr + cs, cs, stack2);
395
R r[] = { {addr, 2 * cs} };
400
rmr->add_committed_region(addr + 2 * cs, cs, stack2);
401
R r[] = { {addr, 3 * cs} };
406
rmr->add_committed_region(addr + 1 * cs, cs, stack);
407
R r[] = { {addr, cs},
409
{addr + 2 * cs, cs} };
414
static void test_add_committed_region() {
415
test_add_committed_region_adjacent();
416
test_add_committed_region_adjacent_overlapping();
417
test_add_committed_region_overlapping();
421
static void fix(R r[S]) {
425
static void test_remove_uncommitted_region() {
427
size_t size = 0x01000000;
428
ReservedSpace rs(size);
429
address addr = (address)rs.base();
431
address frame1 = (address)0x1234;
432
address frame2 = (address)0x1235;
434
NativeCallStack stack(&frame1, 1);
435
NativeCallStack stack2(&frame2, 1);
438
ReservedMemoryRegion* rmr = VirtualMemoryTracker::_reserved_regions->find(ReservedMemoryRegion(addr, size));
440
ASSERT_EQ(rmr->size(), size);
441
ASSERT_EQ(rmr->base(), addr);
444
const size_t cs = 0x1000;
447
rmr->add_committed_region(addr, 3 * cs, stack);
448
R r[] = { {addr, 3 * cs} };
452
rmr->remove_uncommitted_region(addr, 3 * cs);
457
rmr->add_committed_region(addr + 0 * cs, cs, stack);
458
rmr->add_committed_region(addr + 2 * cs, cs, stack);
459
rmr->add_committed_region(addr + 4 * cs, cs, stack);
462
rmr->remove_uncommitted_region(addr, cs);
463
R r[] = { {addr + 2 * cs, cs},
464
{addr + 4 * cs, cs} };
469
rmr->add_committed_region(addr, cs, stack);
472
rmr->remove_uncommitted_region(addr + 2 * cs, cs);
473
R r[] = { {addr + 0 * cs, cs},
474
{addr + 4 * cs, cs} };
479
rmr->add_committed_region(addr + 2 * cs, cs, stack);
482
rmr->remove_uncommitted_region(addr + 4 * cs, cs);
483
R r[] = { {addr + 0 * cs, cs},
484
{addr + 2 * cs, cs} };
488
rmr->remove_uncommitted_region(addr, 5 * cs);
493
rmr->add_committed_region(addr + 1 * cs, cs, stack);
494
rmr->remove_uncommitted_region(addr, 3 * cs);
499
rmr->add_committed_region(addr, 3 * cs, stack);
500
rmr->remove_uncommitted_region(addr + 1 * cs, cs);
501
R r[] = { { addr + 0 * cs, cs},
502
{ addr + 2 * cs, cs} };
505
rmr->remove_uncommitted_region(addr, 3 * cs);
510
rmr->add_committed_region(addr, 3 * cs, stack);
511
rmr->remove_uncommitted_region(addr + 0 * cs, cs);
512
R r[] = { { addr + 1 * cs, 2 * cs} };
515
rmr->remove_uncommitted_region(addr, 3 * cs);
520
rmr->add_committed_region(addr, 3 * cs, stack);
521
rmr->remove_uncommitted_region(addr + 2 * cs, cs);
522
R r[] = { { addr, 2 * cs} };
525
rmr->remove_uncommitted_region(addr, 3 * cs);
530
rmr->add_committed_region(addr + 1 * cs, 4 * cs, stack);
531
rmr->remove_uncommitted_region(addr, 2 * cs);
532
R r[] = { { addr + 2 * cs, 3 * cs} };
535
rmr->remove_uncommitted_region(addr + 1 * cs, 4 * cs);
540
rmr->add_committed_region(addr, 3 * cs, stack);
541
rmr->remove_uncommitted_region(addr + 2 * cs, 2 * cs);
542
R r[] = { { addr, 2 * cs} };
545
rmr->remove_uncommitted_region(addr, 3 * cs);
551
TEST_VM(NMT_VirtualMemoryTracker, add_committed_region) {
552
if (MemTracker::tracking_level() >= NMT_detail) {
553
VirtualMemoryTrackerTest::test_add_committed_region();
555
tty->print_cr("skipped.");
559
TEST_VM(NMT_VirtualMemoryTracker, remove_uncommitted_region) {
560
if (MemTracker::tracking_level() >= NMT_detail) {
561
VirtualMemoryTrackerTest::test_remove_uncommitted_region();
563
tty->print_cr("skipped.");