Path: blob/master/test/hotspot/gtest/runtime/test_virtualMemoryTracker.cpp
41145 views
/*1* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223#include "precompiled.hpp"2425// Included early because the NMT flags don't include it.26#include "utilities/macros.hpp"2728#if INCLUDE_NMT2930#include "services/memTracker.hpp"31#include "services/virtualMemoryTracker.hpp"32#include "utilities/globalDefinitions.hpp"33#include "unittest.hpp"3435namespace {36struct R {37address _addr;38size_t _size;39};40}4142#define check(rmr, regions) check_inner((rmr), (regions), ARRAY_SIZE(regions), __FILE__, __LINE__)4344#define check_empty(rmr) \45do { \46check_inner((rmr), NULL, 0, __FILE__, __LINE__); \47} while (false)4849static void check_inner(ReservedMemoryRegion* rmr, R* regions, size_t regions_size, const char* file, int line) {50CommittedRegionIterator iter = rmr->iterate_committed_regions();51size_t i = 0;52size_t size = 0;5354#define WHERE " from " << file << ":" << line5556for (const CommittedMemoryRegion* region = iter.next(); region != NULL; region = iter.next()) {57EXPECT_LT(i, regions_size) << WHERE;58EXPECT_EQ(region->base(), regions[i]._addr) << WHERE;59EXPECT_EQ(region->size(), regions[i]._size) << WHERE;60size += region->size();61i++;62}6364EXPECT_EQ(i, regions_size) << WHERE;65EXPECT_EQ(size, rmr->committed_size()) << WHERE;66}6768class VirtualMemoryTrackerTest {69public:70static void test_add_committed_region_adjacent() {71VirtualMemoryTracker::initialize(NMT_detail);72VirtualMemoryTracker::late_initialize(NMT_detail);7374address addr = (address)0x10000000;75size_t size = 0x01000000;7677address frame1 = (address)0x1234;78address frame2 = (address)0x1235;7980NativeCallStack stack(&frame1, 1);81NativeCallStack stack2(&frame2, 1);8283// Add the reserved memory84VirtualMemoryTracker::add_reserved_region(addr, size, stack, mtTest);8586// Fetch the added RMR added above87ReservedMemoryRegion* rmr = VirtualMemoryTracker::_reserved_regions->find(ReservedMemoryRegion(addr, size));8889ASSERT_EQ(rmr->size(), size);90ASSERT_EQ(rmr->base(), addr);9192// Commit Size Granularity93const size_t cs = 0x1000;9495// Commit adjacent regions with same stack9697{ // Commit one region98rmr->add_committed_region(addr + cs, cs, stack);99R r[] = { {addr + cs, cs} };100check(rmr, r);101}102103{ // Commit adjacent - lower address104rmr->add_committed_region(addr, cs, stack);105R r[] = { {addr, 2 * cs} };106check(rmr, r);107}108109{ // Commit adjacent - higher address110rmr->add_committed_region(addr + 2 * cs, cs, stack);111R r[] = { {addr, 3 * cs} };112check(rmr, r);113}114115// Cleanup116rmr->remove_uncommitted_region(addr, 3 * cs);117ASSERT_EQ(rmr->committed_size(), 0u);118119120// Commit adjacent regions with different stacks121122{ // Commit one region123rmr->add_committed_region(addr + cs, cs, stack);124R r[] = { {addr + cs, cs} };125check(rmr, r);126}127128{ // Commit adjacent - lower address129rmr->add_committed_region(addr, cs, stack2);130R r[] = { {addr, cs},131{addr + cs, cs} };132check(rmr, r);133}134135{ // Commit adjacent - higher address136rmr->add_committed_region(addr + 2 * cs, cs, stack2);137R r[] = { {addr, cs},138{addr + cs, cs},139{addr + 2 * cs, cs} };140check(rmr, r);141}142143// Cleanup144rmr->remove_uncommitted_region(addr, 3 * cs);145ASSERT_EQ(rmr->committed_size(), 0u);146}147148static void test_add_committed_region_adjacent_overlapping() {149VirtualMemoryTracker::initialize(NMT_detail);150VirtualMemoryTracker::late_initialize(NMT_detail);151152address addr = (address)0x10000000;153size_t size = 0x01000000;154155address frame1 = (address)0x1234;156address frame2 = (address)0x1235;157158NativeCallStack stack(&frame1, 1);159NativeCallStack stack2(&frame2, 1);160161// Add the reserved memory162VirtualMemoryTracker::add_reserved_region(addr, size, stack, mtTest);163164// Fetch the added RMR added above165ReservedMemoryRegion* rmr = VirtualMemoryTracker::_reserved_regions->find(ReservedMemoryRegion(addr, size));166167ASSERT_EQ(rmr->size(), size);168ASSERT_EQ(rmr->base(), addr);169170// Commit Size Granularity171const size_t cs = 0x1000;172173// Commit adjacent and overlapping regions with same stack174175{ // Commit two non-adjacent regions176rmr->add_committed_region(addr, 2 * cs, stack);177rmr->add_committed_region(addr + 3 * cs, 2 * cs, stack);178R r[] = { {addr, 2 * cs},179{addr + 3 * cs, 2 * cs} };180check(rmr, r);181}182183{ // Commit adjacent and overlapping184rmr->add_committed_region(addr + 2 * cs, 2 * cs, stack);185R r[] = { {addr, 5 * cs} };186check(rmr, r);187}188189// revert to two non-adjacent regions190rmr->remove_uncommitted_region(addr + 2 * cs, cs);191ASSERT_EQ(rmr->committed_size(), 4 * cs);192193{ // Commit overlapping and adjacent194rmr->add_committed_region(addr + cs, 2 * cs, stack);195R r[] = { {addr, 5 * cs} };196check(rmr, r);197}198199// Cleanup200rmr->remove_uncommitted_region(addr, 5 * cs);201ASSERT_EQ(rmr->committed_size(), 0u);202203204// Commit adjacent and overlapping regions with different stacks205206{ // Commit two non-adjacent regions207rmr->add_committed_region(addr, 2 * cs, stack);208rmr->add_committed_region(addr + 3 * cs, 2 * cs, stack);209R r[] = { {addr, 2 * cs},210{addr + 3 * cs, 2 * cs} };211check(rmr, r);212}213214{ // Commit adjacent and overlapping215rmr->add_committed_region(addr + 2 * cs, 2 * cs, stack2);216R r[] = { {addr, 2 * cs},217{addr + 2 * cs, 2 * cs},218{addr + 4 * cs, cs} };219check(rmr, r);220}221222// revert to two non-adjacent regions223rmr->add_committed_region(addr, 5 * cs, stack);224rmr->remove_uncommitted_region(addr + 2 * cs, cs);225ASSERT_EQ(rmr->committed_size(), 4 * cs);226227{ // Commit overlapping and adjacent228rmr->add_committed_region(addr + cs, 2 * cs, stack2);229R r[] = { {addr, cs},230{addr + cs, 2 * cs},231{addr + 3 * cs, 2 * cs} };232check(rmr, r);233}234}235236static void test_add_committed_region_overlapping() {237VirtualMemoryTracker::initialize(NMT_detail);238VirtualMemoryTracker::late_initialize(NMT_detail);239240address addr = (address)0x10000000;241size_t size = 0x01000000;242243address frame1 = (address)0x1234;244address frame2 = (address)0x1235;245246NativeCallStack stack(&frame1, 1);247NativeCallStack stack2(&frame2, 1);248249// Add the reserved memory250VirtualMemoryTracker::add_reserved_region(addr, size, stack, mtTest);251252// Fetch the added RMR added above253ReservedMemoryRegion* rmr = VirtualMemoryTracker::_reserved_regions->find(ReservedMemoryRegion(addr, size));254255ASSERT_EQ(rmr->size(), size);256ASSERT_EQ(rmr->base(), addr);257258// Commit Size Granularity259const size_t cs = 0x1000;260261// With same stack262263{ // Commit one region264rmr->add_committed_region(addr, cs, stack);265R r[] = { {addr, cs} };266check(rmr, r);267}268269{ // Commit the same region270rmr->add_committed_region(addr, cs, stack);271R r[] = { {addr, cs} };272check(rmr, r);273}274275{ // Commit a succeeding region276rmr->add_committed_region(addr + cs, cs, stack);277R r[] = { {addr, 2 * cs} };278check(rmr, r);279}280281{ // Commit over two regions282rmr->add_committed_region(addr, 2 * cs, stack);283R r[] = { {addr, 2 * cs} };284check(rmr, r);285}286287{// Commit first part of a region288rmr->add_committed_region(addr, cs, stack);289R r[] = { {addr, 2 * cs} };290check(rmr, r);291}292293{ // Commit second part of a region294rmr->add_committed_region(addr + cs, cs, stack);295R r[] = { {addr, 2 * cs} };296check(rmr, r);297}298299{ // Commit a third part300rmr->add_committed_region(addr + 2 * cs, cs, stack);301R r[] = { {addr, 3 * cs} };302check(rmr, r);303}304305{ // Commit in the middle of a region306rmr->add_committed_region(addr + 1 * cs, cs, stack);307R r[] = { {addr, 3 * cs} };308check(rmr, r);309}310311// Cleanup312rmr->remove_uncommitted_region(addr, 3 * cs);313ASSERT_EQ(rmr->committed_size(), 0u);314315// With preceding region316317rmr->add_committed_region(addr, cs, stack);318rmr->add_committed_region(addr + 2 * cs, 3 * cs, stack);319320rmr->add_committed_region(addr + 2 * cs, cs, stack);321{322R r[] = { {addr, cs},323{addr + 2 * cs, 3 * cs} };324check(rmr, r);325}326327rmr->add_committed_region(addr + 3 * cs, cs, stack);328{329R r[] = { {addr, cs},330{addr + 2 * cs, 3 * cs} };331check(rmr, r);332}333334rmr->add_committed_region(addr + 4 * cs, cs, stack);335{336R r[] = { {addr, cs},337{addr + 2 * cs, 3 * cs} };338check(rmr, r);339}340341// Cleanup342rmr->remove_uncommitted_region(addr, 5 * cs);343ASSERT_EQ(rmr->committed_size(), 0u);344345// With different stacks346347{ // Commit one region348rmr->add_committed_region(addr, cs, stack);349R r[] = { {addr, cs} };350check(rmr, r);351}352353{ // Commit the same region354rmr->add_committed_region(addr, cs, stack2);355R r[] = { {addr, cs} };356check(rmr, r);357}358359{ // Commit a succeeding region360rmr->add_committed_region(addr + cs, cs, stack);361R r[] = { {addr, cs},362{addr + cs, cs} };363check(rmr, r);364}365366{ // Commit over two regions367rmr->add_committed_region(addr, 2 * cs, stack);368R r[] = { {addr, 2 * cs} };369check(rmr, r);370}371372{// Commit first part of a region373rmr->add_committed_region(addr, cs, stack2);374R r[] = { {addr, cs},375{addr + cs, cs} };376check(rmr, r);377}378379{ // Commit second part of a region380rmr->add_committed_region(addr + cs, cs, stack2);381R r[] = { {addr, 2 * cs} };382check(rmr, r);383}384385{ // Commit a third part386rmr->add_committed_region(addr + 2 * cs, cs, stack2);387R r[] = { {addr, 3 * cs} };388check(rmr, r);389}390391{ // Commit in the middle of a region392rmr->add_committed_region(addr + 1 * cs, cs, stack);393R r[] = { {addr, cs},394{addr + cs, cs},395{addr + 2 * cs, cs} };396check(rmr, r);397}398}399400static void test_add_committed_region() {401test_add_committed_region_adjacent();402test_add_committed_region_adjacent_overlapping();403test_add_committed_region_overlapping();404}405406template <size_t S>407static void fix(R r[S]) {408409}410411static void test_remove_uncommitted_region() {412VirtualMemoryTracker::initialize(NMT_detail);413VirtualMemoryTracker::late_initialize(NMT_detail);414415address addr = (address)0x10000000;416size_t size = 0x01000000;417418address frame1 = (address)0x1234;419address frame2 = (address)0x1235;420421NativeCallStack stack(&frame1, 1);422NativeCallStack stack2(&frame2, 1);423424// Add the reserved memory425VirtualMemoryTracker::add_reserved_region(addr, size, stack, mtTest);426427// Fetch the added RMR added above428ReservedMemoryRegion* rmr = VirtualMemoryTracker::_reserved_regions->find(ReservedMemoryRegion(addr, size));429430ASSERT_EQ(rmr->size(), size);431ASSERT_EQ(rmr->base(), addr);432433// Commit Size Granularity434const size_t cs = 0x1000;435436{ // Commit regions437rmr->add_committed_region(addr, 3 * cs, stack);438R r[] = { {addr, 3 * cs} };439check(rmr, r);440441// Remove only existing442rmr->remove_uncommitted_region(addr, 3 * cs);443check_empty(rmr);444}445446{447rmr->add_committed_region(addr + 0 * cs, cs, stack);448rmr->add_committed_region(addr + 2 * cs, cs, stack);449rmr->add_committed_region(addr + 4 * cs, cs, stack);450451{ // Remove first452rmr->remove_uncommitted_region(addr, cs);453R r[] = { {addr + 2 * cs, cs},454{addr + 4 * cs, cs} };455check(rmr, r);456}457458// add back459rmr->add_committed_region(addr, cs, stack);460461{ // Remove middle462rmr->remove_uncommitted_region(addr + 2 * cs, cs);463R r[] = { {addr + 0 * cs, cs},464{addr + 4 * cs, cs} };465check(rmr, r);466}467468// add back469rmr->add_committed_region(addr + 2 * cs, cs, stack);470471{ // Remove end472rmr->remove_uncommitted_region(addr + 4 * cs, cs);473R r[] = { {addr + 0 * cs, cs},474{addr + 2 * cs, cs} };475check(rmr, r);476}477478rmr->remove_uncommitted_region(addr, 5 * cs);479check_empty(rmr);480}481482{ // Remove larger region483rmr->add_committed_region(addr + 1 * cs, cs, stack);484rmr->remove_uncommitted_region(addr, 3 * cs);485check_empty(rmr);486}487488{ // Remove smaller region - in the middle489rmr->add_committed_region(addr, 3 * cs, stack);490rmr->remove_uncommitted_region(addr + 1 * cs, cs);491R r[] = { { addr + 0 * cs, cs},492{ addr + 2 * cs, cs} };493check(rmr, r);494495rmr->remove_uncommitted_region(addr, 3 * cs);496check_empty(rmr);497}498499{ // Remove smaller region - at the beginning500rmr->add_committed_region(addr, 3 * cs, stack);501rmr->remove_uncommitted_region(addr + 0 * cs, cs);502R r[] = { { addr + 1 * cs, 2 * cs} };503check(rmr, r);504505rmr->remove_uncommitted_region(addr, 3 * cs);506check_empty(rmr);507}508509{ // Remove smaller region - at the end510rmr->add_committed_region(addr, 3 * cs, stack);511rmr->remove_uncommitted_region(addr + 2 * cs, cs);512R r[] = { { addr, 2 * cs} };513check(rmr, r);514515rmr->remove_uncommitted_region(addr, 3 * cs);516check_empty(rmr);517}518519{ // Remove smaller, overlapping region - at the beginning520rmr->add_committed_region(addr + 1 * cs, 4 * cs, stack);521rmr->remove_uncommitted_region(addr, 2 * cs);522R r[] = { { addr + 2 * cs, 3 * cs} };523check(rmr, r);524525rmr->remove_uncommitted_region(addr + 1 * cs, 4 * cs);526check_empty(rmr);527}528529{ // Remove smaller, overlapping region - at the end530rmr->add_committed_region(addr, 3 * cs, stack);531rmr->remove_uncommitted_region(addr + 2 * cs, 2 * cs);532R r[] = { { addr, 2 * cs} };533check(rmr, r);534535rmr->remove_uncommitted_region(addr, 3 * cs);536check_empty(rmr);537}538}539};540541TEST_VM(VirtualMemoryTracker, add_committed_region) {542VirtualMemoryTrackerTest::test_add_committed_region();543}544545TEST_VM(VirtualMemoryTracker, remove_uncommitted_region) {546VirtualMemoryTrackerTest::test_remove_uncommitted_region();547}548549#endif // INCLUDE_NMT550551552