Path: blob/master/test/hotspot/gtest/memory/test_virtualspace.cpp
41144 views
/*1* Copyright (c) 2018, 2021, 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"24#include "memory/virtualspace.hpp"25#include "runtime/os.hpp"26#include "oops/oop.hpp"27#include "utilities/align.hpp"28#include "concurrentTestRunner.inline.hpp"29#include "unittest.hpp"3031namespace {32class MemoryReleaser {33ReservedSpace* const _rs;34public:35MemoryReleaser(ReservedSpace* rs) : _rs(rs) { }36~MemoryReleaser() {37if (_rs->special()) {38EXPECT_TRUE(os::release_memory_special(_rs->base(), _rs->size()));39} else {40EXPECT_TRUE(os::release_memory(_rs->base(), _rs->size()));41}42}43};4445static void small_page_write(void* addr, size_t size) {46size_t page_size = os::vm_page_size();4748char* end = (char*) addr + size;49for (char* p = (char*) addr; p < end; p += page_size) {50*p = 1;51}52}5354// have to use these functions, as gtest's _PRED macros don't like is_aligned55// nor (is_aligned<size_t, size_t>)56static bool is_size_aligned(size_t size, size_t alignment) {57return is_aligned(size, alignment);58}59static bool is_ptr_aligned(void* ptr, size_t alignment) {60return is_aligned(ptr, alignment);61}6263static void test_reserved_size(size_t size) {64ASSERT_PRED2(is_size_aligned, size, os::vm_allocation_granularity());6566ReservedSpace rs(size);67MemoryReleaser releaser(&rs);6869EXPECT_TRUE(rs.base() != NULL) << "rs.special: " << rs.special();70EXPECT_EQ(size, rs.size()) << "rs.special: " << rs.special();7172if (rs.special()) {73small_page_write(rs.base(), size);74}75}7677static void test_reserved_size_alignment(size_t size, size_t alignment) {78ASSERT_PRED2(is_size_aligned, size, alignment) << "Incorrect input parameters";79size_t page_size = UseLargePages ? os::large_page_size() : os::vm_page_size();80ReservedSpace rs(size, alignment, page_size, (char *) NULL);8182ASSERT_TRUE(rs.base() != NULL) << "rs.special = " << rs.special();83ASSERT_EQ(size, rs.size()) << "rs.special = " << rs.special();8485EXPECT_PRED2(is_ptr_aligned, rs.base(), alignment)86<< "aligned sizes should always give aligned addresses";87EXPECT_PRED2(is_ptr_aligned, (void*) rs.size(), alignment)88<< "aligned sizes should always give aligned addresses";8990if (rs.special()) {91small_page_write(rs.base(), size);92}93}9495static void test_reserved_size_alignment_page_type(size_t size, size_t alignment, bool maybe_large) {96if (size < alignment) {97// Tests might set -XX:LargePageSizeInBytes=<small pages> and cause unexpected input arguments for this test.98ASSERT_EQ((size_t) os::vm_page_size(), os::large_page_size()) << "Test needs further refinement";99return;100}101102ASSERT_PRED2(is_size_aligned, size, os::vm_allocation_granularity()) << "Must be at least AG aligned";103ASSERT_PRED2(is_size_aligned, size, alignment) << "Must be at least AG aligned";104105bool large = maybe_large && UseLargePages && size >= os::large_page_size();106size_t page_size = large ? os::large_page_size() : os::vm_page_size();107108ReservedSpace rs(size, alignment, page_size);109MemoryReleaser releaser(&rs);110111EXPECT_TRUE(rs.base() != NULL) << "rs.special: " << rs.special();112EXPECT_EQ(size, rs.size()) << "rs.special: " << rs.special();113114if (rs.special()) {115small_page_write(rs.base(), size);116}117}118}119120TEST_VM(ReservedSpace, size_alignment) {121size_t size = 2 * 1024 * 1024;122size_t ag = os::vm_allocation_granularity();123124EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment(size, ag));125EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment(size * 2, ag));126EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment(size * 10, ag));127}128129TEST_VM(ReservedSpace, size) {130size_t size = 2 * 1024 * 1024;131size_t ag = os::vm_allocation_granularity();132133EXPECT_NO_FATAL_FAILURE(test_reserved_size(size * 1));134EXPECT_NO_FATAL_FAILURE(test_reserved_size(size * 2));135EXPECT_NO_FATAL_FAILURE(test_reserved_size(size * 10));136EXPECT_NO_FATAL_FAILURE(test_reserved_size(ag));137EXPECT_NO_FATAL_FAILURE(test_reserved_size(size - ag));138EXPECT_NO_FATAL_FAILURE(test_reserved_size(size));139EXPECT_NO_FATAL_FAILURE(test_reserved_size(size + ag));140EXPECT_NO_FATAL_FAILURE(test_reserved_size(size * 2));141EXPECT_NO_FATAL_FAILURE(test_reserved_size(size * 2 - ag));142EXPECT_NO_FATAL_FAILURE(test_reserved_size(size * 2 + ag));143EXPECT_NO_FATAL_FAILURE(test_reserved_size(size * 3));144EXPECT_NO_FATAL_FAILURE(test_reserved_size(size * 3 - ag));145EXPECT_NO_FATAL_FAILURE(test_reserved_size(size * 3 + ag));146EXPECT_NO_FATAL_FAILURE(test_reserved_size(size * 10));147EXPECT_NO_FATAL_FAILURE(test_reserved_size(size * 10 + size / 2));148}149150TEST_VM(ReservedSpace, size_alignment_page_type) {151size_t ag = os::vm_allocation_granularity();152153EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(ag, ag , false));154EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(ag * 2, ag , false));155EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(ag * 3, ag , false));156EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(ag * 2, ag * 2, false));157EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(ag * 4, ag * 2, false));158EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(ag * 8, ag * 2, false));159EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(ag * 4, ag * 4, false));160EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(ag * 8, ag * 4, false));161EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(ag * 16, ag * 4, false));162}163164TEST_VM(ReservedSpace, size_alignment_page_type_large_page) {165if (!UseLargePages) {166return;167}168169size_t ag = os::vm_allocation_granularity();170size_t lp = os::large_page_size();171172// Without large pages173EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(lp, ag * 4, false));174EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(lp * 2, ag * 4, false));175EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(lp * 4, ag * 4, false));176EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(lp, lp , false));177EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(lp * 2, lp , false));178EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(lp * 3, lp , false));179EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(lp * 2, lp * 2, false));180EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(lp * 4, lp * 2, false));181EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(lp * 8, lp * 2, false));182183// With large pages184EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(lp, ag * 4 , true));185EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(lp * 2, ag * 4, true));186EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(lp * 4, ag * 4, true));187EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(lp, lp , true));188EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(lp * 2, lp , true));189EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(lp * 3, lp , true));190EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(lp * 2, lp * 2, true));191EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(lp * 4, lp * 2, true));192EXPECT_NO_FATAL_FAILURE(test_reserved_size_alignment_page_type(lp * 8, lp * 2, true));193}194195namespace {196enum TestLargePages {197Default,198Disable,199Reserve,200Commit201};202203class ReservedSpaceReleaser {204ReservedSpace* const _rs;205public:206ReservedSpaceReleaser(ReservedSpace* rs) : _rs(rs) { }207~ReservedSpaceReleaser() {208_rs->release();209}210};211212ReservedSpace reserve_memory(size_t reserve_size_aligned, TestLargePages mode) {213switch(mode) {214default:215case Default:216case Reserve:217return ReservedSpace(reserve_size_aligned);218case Disable:219case Commit:220return ReservedSpace(reserve_size_aligned,221os::vm_allocation_granularity(),222os::vm_page_size());223}224}225226bool initialize_virtual_space(VirtualSpace& vs, ReservedSpace rs, TestLargePages mode) {227switch(mode) {228default:229case Default:230case Reserve:231return vs.initialize(rs, 0);232case Disable:233return vs.initialize_with_granularity(rs, 0, os::vm_page_size());234case Commit:235return vs.initialize_with_granularity(rs, 0, os::page_size_for_region_unaligned(rs.size(), 1));236}237}238239void test_virtual_space_actual_committed_space(size_t reserve_size, size_t commit_size,240TestLargePages mode = Default) {241size_t granularity = os::vm_allocation_granularity();242size_t reserve_size_aligned = align_up(reserve_size, granularity);243244ReservedSpace reserved = reserve_memory(reserve_size_aligned, mode);245ReservedSpaceReleaser releaser(&reserved);246247ASSERT_TRUE(reserved.is_reserved());248249VirtualSpace vs;250ASSERT_TRUE(initialize_virtual_space(vs, reserved, mode)) << "Failed to initialize VirtualSpace";251vs.expand_by(commit_size, false);252253if (vs.special()) {254EXPECT_EQ(reserve_size_aligned, vs.actual_committed_size());255} else {256EXPECT_GE(vs.actual_committed_size(), commit_size);257// Approximate the commit granularity.258// Make sure that we don't commit using large pages259// if large pages has been disabled for this VirtualSpace.260size_t commit_granularity = (mode == Disable || !UseLargePages) ?261os::vm_page_size() : os::large_page_size();262EXPECT_LT(vs.actual_committed_size(), commit_size + commit_granularity);263}264}265}266267TEST_VM(VirtualSpace, actual_committed_space) {268EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(4 * K, 0));269EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(4 * K, 4 * K));270EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(8 * K, 0));271EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(8 * K, 4 * K));272EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(8 * K, 8 * K));273EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(12 * K, 0));274EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(12 * K, 4 * K));275EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(12 * K, 8 * K));276EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(12 * K, 12 * K));277EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(64 * K, 0));278EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(64 * K, 32 * K));279EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(64 * K, 64 * K));280EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(2 * M, 0));281EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(2 * M, 4 * K));282EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(2 * M, 64 * K));283EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(2 * M, 1 * M));284EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(2 * M, 2 * M));285EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 0));286EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 4 * K));287EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 8 * K));288EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 1 * M));289EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 2 * M));290EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 5 * M));291EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 10 * M));292}293294TEST_VM(VirtualSpace, actual_committed_space_one_large_page) {295if (!UseLargePages) {296return;297}298299size_t large_page_size = os::large_page_size();300301ReservedSpace reserved(large_page_size, large_page_size, large_page_size);302ReservedSpaceReleaser releaser(&reserved);303ASSERT_TRUE(reserved.is_reserved());304305VirtualSpace vs;306ASSERT_TRUE(vs.initialize(reserved, 0)) << "Failed to initialize VirtualSpace";307vs.expand_by(large_page_size, false);308309EXPECT_EQ(large_page_size, vs.actual_committed_size());310}311312TEST_VM(VirtualSpace, disable_large_pages) {313if (!UseLargePages) {314return;315}316// These test cases verify that if we force VirtualSpace to disable large pages317EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 0, Disable));318EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 4 * K, Disable));319EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 8 * K, Disable));320EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 1 * M, Disable));321EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 2 * M, Disable));322EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 5 * M, Disable));323EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 10 * M, Disable));324325EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 0, Reserve));326EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 4 * K, Reserve));327EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 8 * K, Reserve));328EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 1 * M, Reserve));329EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 2 * M, Reserve));330EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 5 * M, Reserve));331EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 10 * M, Reserve));332333EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 0, Commit));334EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 4 * K, Commit));335EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 8 * K, Commit));336EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 1 * M, Commit));337EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 2 * M, Commit));338EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 5 * M, Commit));339EXPECT_NO_FATAL_FAILURE(test_virtual_space_actual_committed_space(10 * M, 10 * M, Commit));340}341342343// ========================= concurrent virtual space memory tests344// This class have been imported from the original "internal VM test" with minor modification,345// specifically using GTest asserts instead of native HotSpot asserts.346class TestReservedSpace : AllStatic {347public:348static void small_page_write(void* addr, size_t size) {349size_t page_size = os::vm_page_size();350351char* end = (char*)addr + size;352for (char* p = (char*)addr; p < end; p += page_size) {353*p = 1;354}355}356357static void release_memory_for_test(ReservedSpace rs) {358if (rs.special()) {359EXPECT_TRUE(os::release_memory_special(rs.base(), rs.size()));360} else {361EXPECT_TRUE(os::release_memory(rs.base(), rs.size()));362}363}364365static void test_reserved_space1(size_t size, size_t alignment) {366ASSERT_TRUE(is_aligned(size, alignment)) << "Incorrect input parameters";367size_t page_size = UseLargePages ? os::large_page_size() : os::vm_page_size();368ReservedSpace rs(size, // size369alignment, // alignment370page_size, // page size371(char *)NULL); // requested_address372373EXPECT_TRUE(rs.base() != NULL);374EXPECT_EQ(rs.size(), size) << "rs.size: " << rs.size();375376EXPECT_TRUE(is_aligned(rs.base(), alignment)) << "aligned sizes should always give aligned addresses";377EXPECT_TRUE(is_aligned(rs.size(), alignment)) << "aligned sizes should always give aligned addresses";378379if (rs.special()) {380small_page_write(rs.base(), size);381}382383release_memory_for_test(rs);384}385386static void test_reserved_space2(size_t size) {387ASSERT_TRUE(is_aligned(size, os::vm_allocation_granularity())) << "Must be at least AG aligned";388389ReservedSpace rs(size);390391EXPECT_TRUE(rs.base() != NULL);392EXPECT_EQ(rs.size(), size) << "rs.size: " << rs.size();393394if (rs.special()) {395small_page_write(rs.base(), size);396}397398release_memory_for_test(rs);399}400401static void test_reserved_space3(size_t size, size_t alignment, bool maybe_large) {402if (size < alignment) {403// Tests might set -XX:LargePageSizeInBytes=<small pages> and cause unexpected input arguments for this test.404ASSERT_EQ((size_t)os::vm_page_size(), os::large_page_size()) << "Test needs further refinement";405return;406}407408EXPECT_TRUE(is_aligned(size, os::vm_allocation_granularity())) << "Must be at least AG aligned";409EXPECT_TRUE(is_aligned(size, alignment)) << "Must be at least aligned against alignment";410411bool large = maybe_large && UseLargePages && size >= os::large_page_size();412size_t page_size = large ? os::large_page_size() : os::vm_page_size();413414ReservedSpace rs(size, alignment, page_size);415416EXPECT_TRUE(rs.base() != NULL);417EXPECT_EQ(rs.size(), size) << "rs.size: " << rs.size();418419if (rs.special()) {420small_page_write(rs.base(), size);421}422423release_memory_for_test(rs);424}425426427static void test_reserved_space1() {428size_t size = 2 * 1024 * 1024;429size_t ag = os::vm_allocation_granularity();430431test_reserved_space1(size, ag);432test_reserved_space1(size * 2, ag);433test_reserved_space1(size * 10, ag);434}435436static void test_reserved_space2() {437size_t size = 2 * 1024 * 1024;438size_t ag = os::vm_allocation_granularity();439440test_reserved_space2(size * 1);441test_reserved_space2(size * 2);442test_reserved_space2(size * 10);443test_reserved_space2(ag);444test_reserved_space2(size - ag);445test_reserved_space2(size);446test_reserved_space2(size + ag);447test_reserved_space2(size * 2);448test_reserved_space2(size * 2 - ag);449test_reserved_space2(size * 2 + ag);450test_reserved_space2(size * 3);451test_reserved_space2(size * 3 - ag);452test_reserved_space2(size * 3 + ag);453test_reserved_space2(size * 10);454test_reserved_space2(size * 10 + size / 2);455}456457static void test_reserved_space3() {458size_t ag = os::vm_allocation_granularity();459460test_reserved_space3(ag, ag , false);461test_reserved_space3(ag * 2, ag , false);462test_reserved_space3(ag * 3, ag , false);463test_reserved_space3(ag * 2, ag * 2, false);464test_reserved_space3(ag * 4, ag * 2, false);465test_reserved_space3(ag * 8, ag * 2, false);466test_reserved_space3(ag * 4, ag * 4, false);467test_reserved_space3(ag * 8, ag * 4, false);468test_reserved_space3(ag * 16, ag * 4, false);469470if (UseLargePages) {471size_t lp = os::large_page_size();472473// Without large pages474test_reserved_space3(lp, ag * 4, false);475test_reserved_space3(lp * 2, ag * 4, false);476test_reserved_space3(lp * 4, ag * 4, false);477test_reserved_space3(lp, lp , false);478test_reserved_space3(lp * 2, lp , false);479test_reserved_space3(lp * 3, lp , false);480test_reserved_space3(lp * 2, lp * 2, false);481test_reserved_space3(lp * 4, lp * 2, false);482test_reserved_space3(lp * 8, lp * 2, false);483484// With large pages485test_reserved_space3(lp, ag * 4 , true);486test_reserved_space3(lp * 2, ag * 4, true);487test_reserved_space3(lp * 4, ag * 4, true);488test_reserved_space3(lp, lp , true);489test_reserved_space3(lp * 2, lp , true);490test_reserved_space3(lp * 3, lp , true);491test_reserved_space3(lp * 2, lp * 2, true);492test_reserved_space3(lp * 4, lp * 2, true);493test_reserved_space3(lp * 8, lp * 2, true);494}495}496497static void test_reserved_space() {498test_reserved_space1();499test_reserved_space2();500test_reserved_space3();501}502};503504505class TestVirtualSpace : AllStatic {506enum TestLargePages {507Default,508Disable,509Reserve,510Commit511};512513static ReservedSpace reserve_memory(size_t reserve_size_aligned, TestLargePages mode) {514switch(mode) {515default:516case Default:517case Reserve:518return ReservedSpace(reserve_size_aligned);519case Disable:520case Commit:521return ReservedSpace(reserve_size_aligned,522os::vm_allocation_granularity(),523os::vm_page_size());524}525}526527static bool initialize_virtual_space(VirtualSpace& vs, ReservedSpace rs, TestLargePages mode) {528switch(mode) {529default:530case Default:531case Reserve:532return vs.initialize(rs, 0);533case Disable:534return vs.initialize_with_granularity(rs, 0, os::vm_page_size());535case Commit:536return vs.initialize_with_granularity(rs, 0, os::page_size_for_region_unaligned(rs.size(), 1));537}538}539540public:541static void test_virtual_space_actual_committed_space(size_t reserve_size, size_t commit_size,542TestLargePages mode = Default) {543size_t granularity = os::vm_allocation_granularity();544size_t reserve_size_aligned = align_up(reserve_size, granularity);545546ReservedSpace reserved = reserve_memory(reserve_size_aligned, mode);547548EXPECT_TRUE(reserved.is_reserved());549550VirtualSpace vs;551bool initialized = initialize_virtual_space(vs, reserved, mode);552EXPECT_TRUE(initialized) << "Failed to initialize VirtualSpace";553554vs.expand_by(commit_size, false);555556if (vs.special()) {557EXPECT_EQ(vs.actual_committed_size(), reserve_size_aligned);558} else {559EXPECT_GE(vs.actual_committed_size(), commit_size);560// Approximate the commit granularity.561// Make sure that we don't commit using large pages562// if large pages has been disabled for this VirtualSpace.563size_t commit_granularity = (mode == Disable || !UseLargePages) ?564os::vm_page_size() : os::large_page_size();565EXPECT_LT(vs.actual_committed_size(), commit_size + commit_granularity);566}567568reserved.release();569}570571static void test_virtual_space_actual_committed_space_one_large_page() {572if (!UseLargePages) {573return;574}575576size_t large_page_size = os::large_page_size();577578ReservedSpace reserved(large_page_size, large_page_size, large_page_size);579580EXPECT_TRUE(reserved.is_reserved());581582VirtualSpace vs;583bool initialized = vs.initialize(reserved, 0);584EXPECT_TRUE(initialized) << "Failed to initialize VirtualSpace";585586vs.expand_by(large_page_size, false);587588EXPECT_EQ(vs.actual_committed_size(), large_page_size);589590reserved.release();591}592593static void test_virtual_space_actual_committed_space() {594test_virtual_space_actual_committed_space(4 * K, 0);595test_virtual_space_actual_committed_space(4 * K, 4 * K);596test_virtual_space_actual_committed_space(8 * K, 0);597test_virtual_space_actual_committed_space(8 * K, 4 * K);598test_virtual_space_actual_committed_space(8 * K, 8 * K);599test_virtual_space_actual_committed_space(12 * K, 0);600test_virtual_space_actual_committed_space(12 * K, 4 * K);601test_virtual_space_actual_committed_space(12 * K, 8 * K);602test_virtual_space_actual_committed_space(12 * K, 12 * K);603test_virtual_space_actual_committed_space(64 * K, 0);604test_virtual_space_actual_committed_space(64 * K, 32 * K);605test_virtual_space_actual_committed_space(64 * K, 64 * K);606test_virtual_space_actual_committed_space(2 * M, 0);607test_virtual_space_actual_committed_space(2 * M, 4 * K);608test_virtual_space_actual_committed_space(2 * M, 64 * K);609test_virtual_space_actual_committed_space(2 * M, 1 * M);610test_virtual_space_actual_committed_space(2 * M, 2 * M);611test_virtual_space_actual_committed_space(10 * M, 0);612test_virtual_space_actual_committed_space(10 * M, 4 * K);613test_virtual_space_actual_committed_space(10 * M, 8 * K);614test_virtual_space_actual_committed_space(10 * M, 1 * M);615test_virtual_space_actual_committed_space(10 * M, 2 * M);616test_virtual_space_actual_committed_space(10 * M, 5 * M);617test_virtual_space_actual_committed_space(10 * M, 10 * M);618}619620static void test_virtual_space_disable_large_pages() {621if (!UseLargePages) {622return;623}624// These test cases verify that if we force VirtualSpace to disable large pages625test_virtual_space_actual_committed_space(10 * M, 0, Disable);626test_virtual_space_actual_committed_space(10 * M, 4 * K, Disable);627test_virtual_space_actual_committed_space(10 * M, 8 * K, Disable);628test_virtual_space_actual_committed_space(10 * M, 1 * M, Disable);629test_virtual_space_actual_committed_space(10 * M, 2 * M, Disable);630test_virtual_space_actual_committed_space(10 * M, 5 * M, Disable);631test_virtual_space_actual_committed_space(10 * M, 10 * M, Disable);632633test_virtual_space_actual_committed_space(10 * M, 0, Reserve);634test_virtual_space_actual_committed_space(10 * M, 4 * K, Reserve);635test_virtual_space_actual_committed_space(10 * M, 8 * K, Reserve);636test_virtual_space_actual_committed_space(10 * M, 1 * M, Reserve);637test_virtual_space_actual_committed_space(10 * M, 2 * M, Reserve);638test_virtual_space_actual_committed_space(10 * M, 5 * M, Reserve);639test_virtual_space_actual_committed_space(10 * M, 10 * M, Reserve);640641test_virtual_space_actual_committed_space(10 * M, 0, Commit);642test_virtual_space_actual_committed_space(10 * M, 4 * K, Commit);643test_virtual_space_actual_committed_space(10 * M, 8 * K, Commit);644test_virtual_space_actual_committed_space(10 * M, 1 * M, Commit);645test_virtual_space_actual_committed_space(10 * M, 2 * M, Commit);646test_virtual_space_actual_committed_space(10 * M, 5 * M, Commit);647test_virtual_space_actual_committed_space(10 * M, 10 * M, Commit);648}649650static void test_virtual_space() {651test_virtual_space_actual_committed_space();652test_virtual_space_actual_committed_space_one_large_page();653test_virtual_space_disable_large_pages();654}655};656657class ReservedSpaceRunnable : public TestRunnable {658public:659void runUnitTest() const {660TestReservedSpace::test_reserved_space();661}662};663664TEST_VM(VirtualSpace, os_reserve_space_concurrent) {665ReservedSpaceRunnable runnable;666ConcurrentTestRunner testRunner(&runnable, 5, 3000);667testRunner.run();668}669670class VirtualSpaceRunnable : public TestRunnable {671public:672void runUnitTest() const {673TestVirtualSpace::test_virtual_space();674}675};676677TEST_VM(VirtualSpace, os_virtual_space_concurrent) {678VirtualSpaceRunnable runnable;679ConcurrentTestRunner testRunner(&runnable, 5, 3000);680testRunner.run();681}682683684