Path: blob/master/test/hotspot/gtest/runtime/test_virtualMemoryTracker.cpp
64438 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// Tests here test the VM-global NMT facility.24// The tests must *not* modify global state! E.g. switch NMT on or off. Instead, they25// should work passively with whatever setting the gtestlauncher had been started with26// - if NMT is enabled, test NMT, otherwise do whatever minimal tests make sense if NMT27// is off.28//29// The gtestLauncher then are called with various levels of -XX:NativeMemoryTracking during30// jtreg-controlled gtests (see test/hotspot/jtreg/gtest/NMTGtests.java)3132#include "precompiled.hpp"3334// Included early because the NMT flags don't include it.35#include "utilities/macros.hpp"3637#if INCLUDE_NMT3839#include "memory/virtualspace.hpp"40#include "services/memTracker.hpp"41#include "services/virtualMemoryTracker.hpp"42#include "utilities/globalDefinitions.hpp"43#include "unittest.hpp"44#include <stdio.h>4546// #define LOG(...) printf(__VA_ARGS__); printf("\n"); fflush(stdout);47#define LOG(...)4849namespace {50struct R {51address _addr;52size_t _size;53};54}5556#define check(rmr, regions) check_inner((rmr), (regions), ARRAY_SIZE(regions), __FILE__, __LINE__)5758#define check_empty(rmr) \59do { \60check_inner((rmr), NULL, 0, __FILE__, __LINE__); \61} while (false)6263static void diagnostic_print(ReservedMemoryRegion* rmr) {64CommittedRegionIterator iter = rmr->iterate_committed_regions();65LOG("In reserved region " PTR_FORMAT ", size " SIZE_FORMAT_HEX ":", p2i(rmr->base()), rmr->size());66for (const CommittedMemoryRegion* region = iter.next(); region != NULL; region = iter.next()) {67LOG(" committed region: " PTR_FORMAT ", size " SIZE_FORMAT_HEX, p2i(region->base()), region->size());68}69}7071static void check_inner(ReservedMemoryRegion* rmr, R* regions, size_t regions_size, const char* file, int line) {72CommittedRegionIterator iter = rmr->iterate_committed_regions();73size_t i = 0;74size_t size = 0;7576// Helpful log77diagnostic_print(rmr);7879#define WHERE " from " << file << ":" << line8081for (const CommittedMemoryRegion* region = iter.next(); region != NULL; region = iter.next()) {82EXPECT_LT(i, regions_size) << WHERE;83EXPECT_EQ(region->base(), regions[i]._addr) << WHERE;84EXPECT_EQ(region->size(), regions[i]._size) << WHERE;85size += region->size();86i++;87}8889EXPECT_EQ(i, regions_size) << WHERE;90EXPECT_EQ(size, rmr->committed_size()) << WHERE;91}9293class VirtualMemoryTrackerTest {94public:95static void test_add_committed_region_adjacent() {9697size_t size = 0x01000000;98ReservedSpace rs(size);99address addr = (address)rs.base();100101address frame1 = (address)0x1234;102address frame2 = (address)0x1235;103104NativeCallStack stack(&frame1, 1);105NativeCallStack stack2(&frame2, 1);106107// Fetch the added RMR for the space108ReservedMemoryRegion* rmr = VirtualMemoryTracker::_reserved_regions->find(ReservedMemoryRegion(addr, size));109110ASSERT_EQ(rmr->size(), size);111ASSERT_EQ(rmr->base(), addr);112113// Commit Size Granularity114const size_t cs = 0x1000;115116// Commit adjacent regions with same stack117118{ // Commit one region119rmr->add_committed_region(addr + cs, cs, stack);120R r[] = { {addr + cs, cs} };121check(rmr, r);122}123124{ // Commit adjacent - lower address125rmr->add_committed_region(addr, cs, stack);126R r[] = { {addr, 2 * cs} };127check(rmr, r);128}129130{ // Commit adjacent - higher address131rmr->add_committed_region(addr + 2 * cs, cs, stack);132R r[] = { {addr, 3 * cs} };133check(rmr, r);134}135136// Cleanup137rmr->remove_uncommitted_region(addr, 3 * cs);138ASSERT_EQ(rmr->committed_size(), 0u);139140141// Commit adjacent regions with different stacks142143{ // Commit one region144rmr->add_committed_region(addr + cs, cs, stack);145R r[] = { {addr + cs, cs} };146check(rmr, r);147}148149{ // Commit adjacent - lower address150rmr->add_committed_region(addr, cs, stack2);151R r[] = { {addr, cs},152{addr + cs, cs} };153check(rmr, r);154}155156{ // Commit adjacent - higher address157rmr->add_committed_region(addr + 2 * cs, cs, stack2);158R r[] = { {addr, cs},159{addr + cs, cs},160{addr + 2 * cs, cs} };161check(rmr, r);162}163164// Cleanup165rmr->remove_uncommitted_region(addr, 3 * cs);166ASSERT_EQ(rmr->committed_size(), 0u);167}168169static void test_add_committed_region_adjacent_overlapping() {170171size_t size = 0x01000000;172ReservedSpace rs(size);173address addr = (address)rs.base();174175address frame1 = (address)0x1234;176address frame2 = (address)0x1235;177178NativeCallStack stack(&frame1, 1);179NativeCallStack stack2(&frame2, 1);180181// Add the reserved memory182VirtualMemoryTracker::add_reserved_region(addr, size, stack, mtTest);183184// Fetch the added RMR for the space185ReservedMemoryRegion* rmr = VirtualMemoryTracker::_reserved_regions->find(ReservedMemoryRegion(addr, size));186187ASSERT_EQ(rmr->size(), size);188ASSERT_EQ(rmr->base(), addr);189190// Commit Size Granularity191const size_t cs = 0x1000;192193// Commit adjacent and overlapping regions with same stack194195{ // Commit two non-adjacent regions196rmr->add_committed_region(addr, 2 * cs, stack);197rmr->add_committed_region(addr + 3 * cs, 2 * cs, stack);198R r[] = { {addr, 2 * cs},199{addr + 3 * cs, 2 * cs} };200check(rmr, r);201}202203{ // Commit adjacent and overlapping204rmr->add_committed_region(addr + 2 * cs, 2 * cs, stack);205R r[] = { {addr, 5 * cs} };206check(rmr, r);207}208209// revert to two non-adjacent regions210rmr->remove_uncommitted_region(addr + 2 * cs, cs);211ASSERT_EQ(rmr->committed_size(), 4 * cs);212213{ // Commit overlapping and adjacent214rmr->add_committed_region(addr + cs, 2 * cs, stack);215R r[] = { {addr, 5 * cs} };216check(rmr, r);217}218219// Cleanup220rmr->remove_uncommitted_region(addr, 5 * cs);221ASSERT_EQ(rmr->committed_size(), 0u);222223224// Commit adjacent and overlapping regions with different stacks225226{ // Commit two non-adjacent regions227rmr->add_committed_region(addr, 2 * cs, stack);228rmr->add_committed_region(addr + 3 * cs, 2 * cs, stack);229R r[] = { {addr, 2 * cs},230{addr + 3 * cs, 2 * cs} };231check(rmr, r);232}233234{ // Commit adjacent and overlapping235rmr->add_committed_region(addr + 2 * cs, 2 * cs, stack2);236R r[] = { {addr, 2 * cs},237{addr + 2 * cs, 2 * cs},238{addr + 4 * cs, cs} };239check(rmr, r);240}241242// revert to two non-adjacent regions243rmr->add_committed_region(addr, 5 * cs, stack);244rmr->remove_uncommitted_region(addr + 2 * cs, cs);245ASSERT_EQ(rmr->committed_size(), 4 * cs);246247{ // Commit overlapping and adjacent248rmr->add_committed_region(addr + cs, 2 * cs, stack2);249R r[] = { {addr, cs},250{addr + cs, 2 * cs},251{addr + 3 * cs, 2 * cs} };252check(rmr, r);253}254}255256static void test_add_committed_region_overlapping() {257258size_t size = 0x01000000;259ReservedSpace rs(size);260address addr = (address)rs.base();261262address frame1 = (address)0x1234;263address frame2 = (address)0x1235;264265NativeCallStack stack(&frame1, 1);266NativeCallStack stack2(&frame2, 1);267268// Fetch the added RMR for the space269ReservedMemoryRegion* rmr = VirtualMemoryTracker::_reserved_regions->find(ReservedMemoryRegion(addr, size));270271ASSERT_EQ(rmr->size(), size);272ASSERT_EQ(rmr->base(), addr);273274// Commit Size Granularity275const size_t cs = 0x1000;276277// With same stack278279{ // Commit one region280rmr->add_committed_region(addr, cs, stack);281R r[] = { {addr, cs} };282check(rmr, r);283}284285{ // Commit the same region286rmr->add_committed_region(addr, cs, stack);287R r[] = { {addr, cs} };288check(rmr, r);289}290291{ // Commit a succeeding region292rmr->add_committed_region(addr + cs, cs, stack);293R r[] = { {addr, 2 * cs} };294check(rmr, r);295}296297{ // Commit over two regions298rmr->add_committed_region(addr, 2 * cs, stack);299R r[] = { {addr, 2 * cs} };300check(rmr, r);301}302303{// Commit first part of a region304rmr->add_committed_region(addr, cs, stack);305R r[] = { {addr, 2 * cs} };306check(rmr, r);307}308309{ // Commit second part of a region310rmr->add_committed_region(addr + cs, cs, stack);311R r[] = { {addr, 2 * cs} };312check(rmr, r);313}314315{ // Commit a third part316rmr->add_committed_region(addr + 2 * cs, cs, stack);317R r[] = { {addr, 3 * cs} };318check(rmr, r);319}320321{ // Commit in the middle of a region322rmr->add_committed_region(addr + 1 * cs, cs, stack);323R r[] = { {addr, 3 * cs} };324check(rmr, r);325}326327// Cleanup328rmr->remove_uncommitted_region(addr, 3 * cs);329ASSERT_EQ(rmr->committed_size(), 0u);330331// With preceding region332333rmr->add_committed_region(addr, cs, stack);334rmr->add_committed_region(addr + 2 * cs, 3 * cs, stack);335336rmr->add_committed_region(addr + 2 * cs, cs, stack);337{338R r[] = { {addr, cs},339{addr + 2 * cs, 3 * cs} };340check(rmr, r);341}342343rmr->add_committed_region(addr + 3 * cs, cs, stack);344{345R r[] = { {addr, cs},346{addr + 2 * cs, 3 * cs} };347check(rmr, r);348}349350rmr->add_committed_region(addr + 4 * cs, cs, stack);351{352R r[] = { {addr, cs},353{addr + 2 * cs, 3 * cs} };354check(rmr, r);355}356357// Cleanup358rmr->remove_uncommitted_region(addr, 5 * cs);359ASSERT_EQ(rmr->committed_size(), 0u);360361// With different stacks362363{ // Commit one region364rmr->add_committed_region(addr, cs, stack);365R r[] = { {addr, cs} };366check(rmr, r);367}368369{ // Commit the same region370rmr->add_committed_region(addr, cs, stack2);371R r[] = { {addr, cs} };372check(rmr, r);373}374375{ // Commit a succeeding region376rmr->add_committed_region(addr + cs, cs, stack);377R r[] = { {addr, cs},378{addr + cs, cs} };379check(rmr, r);380}381382{ // Commit over two regions383rmr->add_committed_region(addr, 2 * cs, stack);384R r[] = { {addr, 2 * cs} };385check(rmr, r);386}387388{// Commit first part of a region389rmr->add_committed_region(addr, cs, stack2);390R r[] = { {addr, cs},391{addr + cs, cs} };392check(rmr, r);393}394395{ // Commit second part of a region396rmr->add_committed_region(addr + cs, cs, stack2);397R r[] = { {addr, 2 * cs} };398check(rmr, r);399}400401{ // Commit a third part402rmr->add_committed_region(addr + 2 * cs, cs, stack2);403R r[] = { {addr, 3 * cs} };404check(rmr, r);405}406407{ // Commit in the middle of a region408rmr->add_committed_region(addr + 1 * cs, cs, stack);409R r[] = { {addr, cs},410{addr + cs, cs},411{addr + 2 * cs, cs} };412check(rmr, r);413}414}415416static void test_add_committed_region() {417test_add_committed_region_adjacent();418test_add_committed_region_adjacent_overlapping();419test_add_committed_region_overlapping();420}421422template <size_t S>423static void fix(R r[S]) {424425}426427static void test_remove_uncommitted_region() {428429size_t size = 0x01000000;430ReservedSpace rs(size);431address addr = (address)rs.base();432433address frame1 = (address)0x1234;434address frame2 = (address)0x1235;435436NativeCallStack stack(&frame1, 1);437NativeCallStack stack2(&frame2, 1);438439// Fetch the added RMR for the space440ReservedMemoryRegion* rmr = VirtualMemoryTracker::_reserved_regions->find(ReservedMemoryRegion(addr, size));441442ASSERT_EQ(rmr->size(), size);443ASSERT_EQ(rmr->base(), addr);444445// Commit Size Granularity446const size_t cs = 0x1000;447448{ // Commit regions449rmr->add_committed_region(addr, 3 * cs, stack);450R r[] = { {addr, 3 * cs} };451check(rmr, r);452453// Remove only existing454rmr->remove_uncommitted_region(addr, 3 * cs);455check_empty(rmr);456}457458{459rmr->add_committed_region(addr + 0 * cs, cs, stack);460rmr->add_committed_region(addr + 2 * cs, cs, stack);461rmr->add_committed_region(addr + 4 * cs, cs, stack);462463{ // Remove first464rmr->remove_uncommitted_region(addr, cs);465R r[] = { {addr + 2 * cs, cs},466{addr + 4 * cs, cs} };467check(rmr, r);468}469470// add back471rmr->add_committed_region(addr, cs, stack);472473{ // Remove middle474rmr->remove_uncommitted_region(addr + 2 * cs, cs);475R r[] = { {addr + 0 * cs, cs},476{addr + 4 * cs, cs} };477check(rmr, r);478}479480// add back481rmr->add_committed_region(addr + 2 * cs, cs, stack);482483{ // Remove end484rmr->remove_uncommitted_region(addr + 4 * cs, cs);485R r[] = { {addr + 0 * cs, cs},486{addr + 2 * cs, cs} };487check(rmr, r);488}489490rmr->remove_uncommitted_region(addr, 5 * cs);491check_empty(rmr);492}493494{ // Remove larger region495rmr->add_committed_region(addr + 1 * cs, cs, stack);496rmr->remove_uncommitted_region(addr, 3 * cs);497check_empty(rmr);498}499500{ // Remove smaller region - in the middle501rmr->add_committed_region(addr, 3 * cs, stack);502rmr->remove_uncommitted_region(addr + 1 * cs, cs);503R r[] = { { addr + 0 * cs, cs},504{ addr + 2 * cs, cs} };505check(rmr, r);506507rmr->remove_uncommitted_region(addr, 3 * cs);508check_empty(rmr);509}510511{ // Remove smaller region - at the beginning512rmr->add_committed_region(addr, 3 * cs, stack);513rmr->remove_uncommitted_region(addr + 0 * cs, cs);514R r[] = { { addr + 1 * cs, 2 * cs} };515check(rmr, r);516517rmr->remove_uncommitted_region(addr, 3 * cs);518check_empty(rmr);519}520521{ // Remove smaller region - at the end522rmr->add_committed_region(addr, 3 * cs, stack);523rmr->remove_uncommitted_region(addr + 2 * cs, cs);524R r[] = { { addr, 2 * cs} };525check(rmr, r);526527rmr->remove_uncommitted_region(addr, 3 * cs);528check_empty(rmr);529}530531{ // Remove smaller, overlapping region - at the beginning532rmr->add_committed_region(addr + 1 * cs, 4 * cs, stack);533rmr->remove_uncommitted_region(addr, 2 * cs);534R r[] = { { addr + 2 * cs, 3 * cs} };535check(rmr, r);536537rmr->remove_uncommitted_region(addr + 1 * cs, 4 * cs);538check_empty(rmr);539}540541{ // Remove smaller, overlapping region - at the end542rmr->add_committed_region(addr, 3 * cs, stack);543rmr->remove_uncommitted_region(addr + 2 * cs, 2 * cs);544R r[] = { { addr, 2 * cs} };545check(rmr, r);546547rmr->remove_uncommitted_region(addr, 3 * cs);548check_empty(rmr);549}550}551};552553TEST_VM(NMT_VirtualMemoryTracker, add_committed_region) {554if (MemTracker::tracking_level() >= NMT_detail) {555VirtualMemoryTrackerTest::test_add_committed_region();556} else {557tty->print_cr("skipped.");558}559}560561TEST_VM(NMT_VirtualMemoryTracker, remove_uncommitted_region) {562if (MemTracker::tracking_level() >= NMT_detail) {563VirtualMemoryTrackerTest::test_remove_uncommitted_region();564} else {565tty->print_cr("skipped.");566}567}568569#endif // INCLUDE_NMT570571572