Path: blob/master/test/hotspot/gtest/metaspace/test_metaspacearena.cpp
41144 views
/*1* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.2* Copyright (c) 2020 SAP SE. 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 it6* under the terms of the GNU General Public License version 2 only, as7* published by the Free Software Foundation.8*9* This code is distributed in the hope that it will be useful, but WITHOUT10* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or11* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License12* version 2 for more details (a copy is included in the LICENSE file that13* accompanied this code).14*15* You should have received a copy of the GNU General Public License version16* 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 USA20* or visit www.oracle.com if you need additional information or have any21* questions.22*23*/2425#include "precompiled.hpp"26#include "memory/metaspace/commitLimiter.hpp"27#include "memory/metaspace/counters.hpp"28#include "memory/metaspace/internalStats.hpp"29#include "memory/metaspace/metaspaceArena.hpp"30#include "memory/metaspace/metaspaceArenaGrowthPolicy.hpp"31#include "memory/metaspace/metaspaceSettings.hpp"32#include "memory/metaspace/metaspaceStatistics.hpp"33#include "runtime/mutex.hpp"34#include "runtime/mutexLocker.hpp"35#include "utilities/debug.hpp"36#include "utilities/globalDefinitions.hpp"3738//#define LOG_PLEASE39#include "metaspaceGtestCommon.hpp"40#include "metaspaceGtestContexts.hpp"41#include "metaspaceGtestRangeHelpers.hpp"4243using metaspace::ArenaGrowthPolicy;44using metaspace::CommitLimiter;45using metaspace::InternalStats;46using metaspace::MemRangeCounter;47using metaspace::MetaspaceArena;48using metaspace::SizeAtomicCounter;49using metaspace::Settings;50using metaspace::ArenaStats;5152// See metaspaceArena.cpp : needed for predicting commit sizes.53namespace metaspace {54extern size_t get_raw_word_size_for_requested_word_size(size_t net_word_size);55}5657class MetaspaceArenaTestHelper {5859MetaspaceGtestContext& _context;6061Mutex* _lock;62const ArenaGrowthPolicy* _growth_policy;63SizeAtomicCounter _used_words_counter;64MetaspaceArena* _arena;6566void initialize(const ArenaGrowthPolicy* growth_policy, const char* name = "gtest-MetaspaceArena") {67_growth_policy = growth_policy;68_lock = new Mutex(Monitor::native, "gtest-MetaspaceArenaTest-lock", false, Monitor::_safepoint_check_never);69// Lock during space creation, since this is what happens in the VM too70// (see ClassLoaderData::metaspace_non_null(), which we mimick here).71{72MutexLocker ml(_lock, Mutex::_no_safepoint_check_flag);73_arena = new MetaspaceArena(&_context.cm(), _growth_policy, _lock, &_used_words_counter, name);74}75DEBUG_ONLY(_arena->verify());7677}7879public:8081// Create a helper; growth policy for arena is determined by the given spacetype|class tupel82MetaspaceArenaTestHelper(MetaspaceGtestContext& helper,83Metaspace::MetaspaceType space_type, bool is_class,84const char* name = "gtest-MetaspaceArena") :85_context(helper)86{87initialize(ArenaGrowthPolicy::policy_for_space_type(space_type, is_class), name);88}8990// Create a helper; growth policy is directly specified91MetaspaceArenaTestHelper(MetaspaceGtestContext& helper, const ArenaGrowthPolicy* growth_policy,92const char* name = "gtest-MetaspaceArena") :93_context(helper)94{95initialize(growth_policy, name);96}9798~MetaspaceArenaTestHelper() {99delete_arena_with_tests();100delete _lock;101}102103const CommitLimiter& limiter() const { return _context.commit_limiter(); }104MetaspaceArena* arena() const { return _arena; }105SizeAtomicCounter& used_words_counter() { return _used_words_counter; }106107// Note: all test functions return void due to gtests limitation that we cannot use ASSERT108// in non-void returning tests.109110void delete_arena_with_tests() {111if (_arena != NULL) {112size_t used_words_before = _used_words_counter.get();113size_t committed_words_before = limiter().committed_words();114DEBUG_ONLY(_arena->verify());115delete _arena;116_arena = NULL;117size_t used_words_after = _used_words_counter.get();118size_t committed_words_after = limiter().committed_words();119ASSERT_0(used_words_after);120if (Settings::uncommit_free_chunks()) {121ASSERT_LE(committed_words_after, committed_words_before);122} else {123ASSERT_EQ(committed_words_after, committed_words_before);124}125}126}127128void usage_numbers_with_test(size_t* p_used, size_t* p_committed, size_t* p_capacity) const {129_arena->usage_numbers(p_used, p_committed, p_capacity);130if (p_used != NULL) {131if (p_committed != NULL) {132ASSERT_GE(*p_committed, *p_used);133}134// Since we own the used words counter, it should reflect our usage number 1:1135ASSERT_EQ(_used_words_counter.get(), *p_used);136}137if (p_committed != NULL && p_capacity != NULL) {138ASSERT_GE(*p_capacity, *p_committed);139}140}141142// Allocate; caller expects success; return pointer in *p_return_value143void allocate_from_arena_with_tests_expect_success(MetaWord** p_return_value, size_t word_size) {144allocate_from_arena_with_tests(p_return_value, word_size);145ASSERT_NOT_NULL(*p_return_value);146}147148// Allocate; caller expects success but is not interested in return value149void allocate_from_arena_with_tests_expect_success(size_t word_size) {150MetaWord* dummy = NULL;151allocate_from_arena_with_tests_expect_success(&dummy, word_size);152}153154// Allocate; caller expects failure155void allocate_from_arena_with_tests_expect_failure(size_t word_size) {156MetaWord* dummy = NULL;157allocate_from_arena_with_tests(&dummy, word_size);158ASSERT_NULL(dummy);159}160161// Allocate; it may or may not work; return value in *p_return_value162void allocate_from_arena_with_tests(MetaWord** p_return_value, size_t word_size) {163164// Note: usage_numbers walks all chunks in use and counts.165size_t used = 0, committed = 0, capacity = 0;166usage_numbers_with_test(&used, &committed, &capacity);167168size_t possible_expansion = limiter().possible_expansion_words();169170MetaWord* p = _arena->allocate(word_size);171172SOMETIMES(DEBUG_ONLY(_arena->verify();))173174size_t used2 = 0, committed2 = 0, capacity2 = 0;175usage_numbers_with_test(&used2, &committed2, &capacity2);176177if (p == NULL) {178// Allocation failed.179if (Settings::new_chunks_are_fully_committed()) {180ASSERT_LT(possible_expansion, MAX_CHUNK_WORD_SIZE);181} else {182ASSERT_LT(possible_expansion, word_size);183}184185ASSERT_EQ(used, used2);186ASSERT_EQ(committed, committed2);187ASSERT_EQ(capacity, capacity2);188} else {189// Allocation succeeded. Should be correctly aligned.190ASSERT_TRUE(is_aligned(p, sizeof(MetaWord)));191// used: may go up or may not (since our request may have been satisfied from the freeblocklist192// whose content already counts as used).193// committed: may go up, may not194// capacity: ditto195ASSERT_GE(used2, used);196ASSERT_GE(committed2, committed);197ASSERT_GE(capacity2, capacity);198}199200*p_return_value = p;201}202203// Allocate; it may or may not work; but caller does not care for the result value204void allocate_from_arena_with_tests(size_t word_size) {205MetaWord* dummy = NULL;206allocate_from_arena_with_tests(&dummy, word_size);207}208209void deallocate_with_tests(MetaWord* p, size_t word_size) {210size_t used = 0, committed = 0, capacity = 0;211usage_numbers_with_test(&used, &committed, &capacity);212213_arena->deallocate(p, word_size);214215SOMETIMES(DEBUG_ONLY(_arena->verify();))216217size_t used2 = 0, committed2 = 0, capacity2 = 0;218usage_numbers_with_test(&used2, &committed2, &capacity2);219220// Nothing should have changed. Deallocated blocks are added to the free block list221// which still counts as used.222ASSERT_EQ(used2, used);223ASSERT_EQ(committed2, committed);224ASSERT_EQ(capacity2, capacity);225}226227ArenaStats get_arena_statistics() const {228ArenaStats stats;229_arena->add_to_statistics(&stats);230return stats;231}232233// Convenience method to return number of chunks in arena (including current chunk)234int get_number_of_chunks() const {235return get_arena_statistics().totals()._num;236}237238};239240static void test_basics(size_t commit_limit, bool is_micro) {241MetaspaceGtestContext context(commit_limit);242MetaspaceArenaTestHelper helper(context, is_micro ? Metaspace::ReflectionMetaspaceType : Metaspace::StandardMetaspaceType, false);243244helper.allocate_from_arena_with_tests(1);245helper.allocate_from_arena_with_tests(128);246helper.allocate_from_arena_with_tests(128 * K);247helper.allocate_from_arena_with_tests(1);248helper.allocate_from_arena_with_tests(128);249helper.allocate_from_arena_with_tests(128 * K);250}251252TEST_VM(metaspace, MetaspaceArena_basics_micro_nolimit) {253test_basics(max_uintx, true);254}255256TEST_VM(metaspace, MetaspaceArena_basics_micro_limit) {257test_basics(256 * K, true);258}259260TEST_VM(metaspace, MetaspaceArena_basics_standard_nolimit) {261test_basics(max_uintx, false);262}263264TEST_VM(metaspace, MetaspaceArena_basics_standard_limit) {265test_basics(256 * K, false);266}267268// Test chunk enlargement:269// A single MetaspaceArena, left undisturbed with place to grow. Slowly fill arena up.270// We should see at least some occurrences of chunk-in-place enlargement.271static void test_chunk_enlargment_simple(Metaspace::MetaspaceType spacetype, bool is_class) {272273MetaspaceGtestContext context;274MetaspaceArenaTestHelper helper(context, (Metaspace::MetaspaceType)spacetype, is_class);275276uint64_t n1 = metaspace::InternalStats::num_chunks_enlarged();277278size_t allocated = 0;279while (allocated <= MAX_CHUNK_WORD_SIZE &&280metaspace::InternalStats::num_chunks_enlarged() == n1) {281size_t s = IntRange(32, 128).random_value();282helper.allocate_from_arena_with_tests_expect_success(s);283allocated += metaspace::get_raw_word_size_for_requested_word_size(s);284}285286EXPECT_GT(metaspace::InternalStats::num_chunks_enlarged(), n1);287288}289290// Do this test for some of the standard types; don't do it for the boot loader type291// since that one starts out with max chunk size so we would not see any enlargement.292293TEST_VM(metaspace, MetaspaceArena_test_enlarge_in_place_standard_c) {294test_chunk_enlargment_simple(Metaspace::StandardMetaspaceType, true);295}296297TEST_VM(metaspace, MetaspaceArena_test_enlarge_in_place_standard_nc) {298test_chunk_enlargment_simple(Metaspace::StandardMetaspaceType, false);299}300301TEST_VM(metaspace, MetaspaceArena_test_enlarge_in_place_micro_c) {302test_chunk_enlargment_simple(Metaspace::ReflectionMetaspaceType, true);303}304305TEST_VM(metaspace, MetaspaceArena_test_enlarge_in_place_micro_nc) {306test_chunk_enlargment_simple(Metaspace::ReflectionMetaspaceType, false);307}308309// Test chunk enlargement:310// A single MetaspaceArena, left undisturbed with place to grow. Slowly fill arena up.311// We should see occurrences of chunk-in-place enlargement.312// Here, we give it an ideal policy which should enable the initial chunk to grow unmolested313// until finish.314TEST_VM(metaspace, MetaspaceArena_test_enlarge_in_place_2) {315316if (Settings::use_allocation_guard()) {317return;318}319320// Note: internally, chunk in-place enlargement is disallowed if growing the chunk321// would cause the arena to claim more memory than its growth policy allows. This322// is done to prevent the arena to grow too fast.323//324// In order to test in-place growth here without that restriction I give it an325// artificial growth policy which starts out with a tiny chunk size, then balloons326// right up to max chunk size. This will cause the initial chunk to be tiny, and327// then the arena is able to grow it without violating growth policy.328chunklevel_t growth[] = { HIGHEST_CHUNK_LEVEL, ROOT_CHUNK_LEVEL };329ArenaGrowthPolicy growth_policy(growth, 2);330331MetaspaceGtestContext context;332MetaspaceArenaTestHelper helper(context, &growth_policy);333334uint64_t n1 = metaspace::InternalStats::num_chunks_enlarged();335336size_t allocated = 0;337while (allocated <= MAX_CHUNK_WORD_SIZE) {338size_t s = IntRange(32, 128).random_value();339helper.allocate_from_arena_with_tests_expect_success(s);340allocated += metaspace::get_raw_word_size_for_requested_word_size(s);341if (allocated <= MAX_CHUNK_WORD_SIZE) {342// Chunk should have been enlarged in place343ASSERT_EQ(1, helper.get_number_of_chunks());344} else {345// Next chunk should have started346ASSERT_EQ(2, helper.get_number_of_chunks());347}348}349350int times_chunk_were_enlarged = metaspace::InternalStats::num_chunks_enlarged() - n1;351LOG("chunk was enlarged %d times.", times_chunk_were_enlarged);352353ASSERT_GT0(times_chunk_were_enlarged);354355}356357// Regression test: Given a single MetaspaceArena, left undisturbed with place to grow,358// test that in place enlargement correctly fails if growing the chunk would bring us359// beyond the max. size of a chunk.360TEST_VM(metaspace, MetaspaceArena_test_failing_to_enlarge_in_place_max_chunk_size) {361362if (Settings::use_allocation_guard()) {363return;364}365366MetaspaceGtestContext context;367368for (size_t first_allocation_size = 1; first_allocation_size <= MAX_CHUNK_WORD_SIZE / 2; first_allocation_size *= 2) {369370MetaspaceArenaTestHelper helper(context, Metaspace::StandardMetaspaceType, false);371372// we allocate first a small amount, then the full amount possible.373// The sum of first and second allocation should bring us above root chunk size.374// This should work, we should not see any problems, but no chunk enlargement should375// happen.376int n1 = metaspace::InternalStats::num_chunks_enlarged();377378helper.allocate_from_arena_with_tests_expect_success(first_allocation_size);379EXPECT_EQ(helper.get_number_of_chunks(), 1);380381helper.allocate_from_arena_with_tests_expect_success(MAX_CHUNK_WORD_SIZE - first_allocation_size + 1);382EXPECT_EQ(helper.get_number_of_chunks(), 2);383384int times_chunk_were_enlarged = metaspace::InternalStats::num_chunks_enlarged() - n1;385LOG("chunk was enlarged %d times.", times_chunk_were_enlarged);386387EXPECT_0(times_chunk_were_enlarged);388389}390}391392// Regression test: Given a single MetaspaceArena, left undisturbed with place to grow,393// test that in place enlargement correctly fails if growing the chunk would cause more394// than doubling its size395TEST_VM(metaspace, MetaspaceArena_test_failing_to_enlarge_in_place_doubling_chunk_size) {396397if (Settings::use_allocation_guard()) {398return;399}400401MetaspaceGtestContext context;402MetaspaceArenaTestHelper helper(context, Metaspace::StandardMetaspaceType, false);403404int n1 = metaspace::InternalStats::num_chunks_enlarged();405406helper.allocate_from_arena_with_tests_expect_success(1000);407EXPECT_EQ(helper.get_number_of_chunks(), 1);408409helper.allocate_from_arena_with_tests_expect_success(4000);410EXPECT_EQ(helper.get_number_of_chunks(), 2);411412int times_chunk_were_enlarged = metaspace::InternalStats::num_chunks_enlarged() - n1;413LOG("chunk was enlarged %d times.", times_chunk_were_enlarged);414415EXPECT_0(times_chunk_were_enlarged);416417}418419// Test the MetaspaceArenas' free block list:420// Allocate, deallocate, then allocate the same block again. The second allocate should421// reuse the deallocated block.422TEST_VM(metaspace, MetaspaceArena_deallocate) {423if (Settings::use_allocation_guard()) {424return;425}426for (size_t s = 2; s <= MAX_CHUNK_WORD_SIZE; s *= 2) {427MetaspaceGtestContext context;428MetaspaceArenaTestHelper helper(context, Metaspace::StandardMetaspaceType, false);429430MetaWord* p1 = NULL;431helper.allocate_from_arena_with_tests_expect_success(&p1, s);432433size_t used1 = 0, capacity1 = 0;434helper.usage_numbers_with_test(&used1, NULL, &capacity1);435ASSERT_EQ(used1, s);436437helper.deallocate_with_tests(p1, s);438439size_t used2 = 0, capacity2 = 0;440helper.usage_numbers_with_test(&used2, NULL, &capacity2);441ASSERT_EQ(used1, used2);442ASSERT_EQ(capacity2, capacity2);443444MetaWord* p2 = NULL;445helper.allocate_from_arena_with_tests_expect_success(&p2, s);446447size_t used3 = 0, capacity3 = 0;448helper.usage_numbers_with_test(&used3, NULL, &capacity3);449ASSERT_EQ(used3, used2);450ASSERT_EQ(capacity3, capacity2);451452// Actually, we should get the very same allocation back453ASSERT_EQ(p1, p2);454}455}456457static void test_recover_from_commit_limit_hit() {458459if (Settings::new_chunks_are_fully_committed()) {460return; // This would throw off the commit counting in this test.461}462463// Test:464// - Multiple MetaspaceArena allocate (operating under the same commit limiter).465// - One, while attempting to commit parts of its current chunk on demand,466// triggers the limit and cannot commit its chunk further.467// - We release the other MetaspaceArena - its content is put back to the468// freelists.469// - We re-attempt allocation from the first manager. It should now succeed.470//471// This means if the first MetaspaceArena may have to let go of its current chunk and472// retire it and take a fresh chunk from the freelist.473474const size_t commit_limit = Settings::commit_granule_words() * 10;475MetaspaceGtestContext context(commit_limit);476477// The first MetaspaceArena mimicks a micro loader. This will fill the free478// chunk list with very small chunks. We allocate from them in an interleaved479// way to cause fragmentation.480MetaspaceArenaTestHelper helper1(context, Metaspace::ReflectionMetaspaceType, false);481MetaspaceArenaTestHelper helper2(context, Metaspace::ReflectionMetaspaceType, false);482483// This MetaspaceArena should hit the limit. We use BootMetaspaceType here since484// it gets a large initial chunk which is committed485// on demand and we are likely to hit a commit limit while trying to expand it.486MetaspaceArenaTestHelper helper3(context, Metaspace::BootMetaspaceType, false);487488// Allocate space until we have below two but above one granule left489size_t allocated_from_1_and_2 = 0;490while (context.commit_limiter().possible_expansion_words() >= Settings::commit_granule_words() * 2 &&491allocated_from_1_and_2 < commit_limit) {492helper1.allocate_from_arena_with_tests_expect_success(1);493helper2.allocate_from_arena_with_tests_expect_success(1);494allocated_from_1_and_2 += 2;495}496497// Now, allocating from helper3, creep up on the limit498size_t allocated_from_3 = 0;499MetaWord* p = NULL;500while ( (helper3.allocate_from_arena_with_tests(&p, 1), p != NULL) &&501++allocated_from_3 < Settings::commit_granule_words() * 2);502503EXPECT_LE(allocated_from_3, Settings::commit_granule_words() * 2);504505// We expect the freelist to be empty of committed space...506EXPECT_0(context.cm().calc_committed_word_size());507508//msthelper.cm().print_on(tty);509510// Release the first MetaspaceArena.511helper1.delete_arena_with_tests();512513//msthelper.cm().print_on(tty);514515// Should have populated the freelist with committed space516// We expect the freelist to be empty of committed space...517EXPECT_GT(context.cm().calc_committed_word_size(), (size_t)0);518519// Repeat allocation from helper3, should now work.520helper3.allocate_from_arena_with_tests_expect_success(1);521522}523524TEST_VM(metaspace, MetaspaceArena_recover_from_limit_hit) {525test_recover_from_commit_limit_hit();526}527528static void test_controlled_growth(Metaspace::MetaspaceType type, bool is_class,529size_t expected_starting_capacity,530bool test_in_place_enlargement)531{532533if (Settings::use_allocation_guard()) {534return;535}536537// From a MetaspaceArena in a clean room allocate tiny amounts;538// watch it grow. Used/committed/capacity should not grow in539// large jumps. Also, different types of MetaspaceArena should540// have different initial capacities.541542MetaspaceGtestContext context;543MetaspaceArenaTestHelper smhelper(context, type, is_class, "Grower");544545MetaspaceArenaTestHelper smhelper_harrasser(context, Metaspace::ReflectionMetaspaceType, true, "Harasser");546547size_t used = 0, committed = 0, capacity = 0;548const size_t alloc_words = 16;549550smhelper.arena()->usage_numbers(&used, &committed, &capacity);551ASSERT_0(used);552ASSERT_0(committed);553ASSERT_0(capacity);554555///// First allocation //556557smhelper.allocate_from_arena_with_tests_expect_success(alloc_words);558559smhelper.arena()->usage_numbers(&used, &committed, &capacity);560561ASSERT_EQ(used, alloc_words);562ASSERT_GE(committed, used);563ASSERT_GE(capacity, committed);564565ASSERT_EQ(capacity, expected_starting_capacity);566567if (!(Settings::new_chunks_are_fully_committed() && type == Metaspace::BootMetaspaceType)) {568// Initial commit charge for the whole context should be one granule569ASSERT_EQ(context.committed_words(), Settings::commit_granule_words());570// Initial commit number for the arena should be less since - apart from boot loader - no571// space type has large initial chunks.572ASSERT_LE(committed, Settings::commit_granule_words());573}574575///// subsequent allocations //576577DEBUG_ONLY(const uintx num_chunk_enlarged = metaspace::InternalStats::num_chunks_enlarged();)578579size_t words_allocated = 0;580int num_allocated = 0;581const size_t safety = MAX_CHUNK_WORD_SIZE * 1.2;582size_t highest_capacity_jump = capacity;583int num_capacity_jumps = 0;584585while (words_allocated < safety && num_capacity_jumps < 15) {586587// if we want to test growth with in-place chunk enlargement, leave MetaspaceArena588// undisturbed; it will have all the place to grow. Otherwise allocate from a little589// side arena to increase fragmentation.590// (Note that this does not completely prevent in-place chunk enlargement but makes it591// rather improbable)592if (!test_in_place_enlargement) {593smhelper_harrasser.allocate_from_arena_with_tests_expect_success(alloc_words * 2);594}595596smhelper.allocate_from_arena_with_tests_expect_success(alloc_words);597words_allocated += metaspace::get_raw_word_size_for_requested_word_size(alloc_words);598num_allocated++;599600size_t used2 = 0, committed2 = 0, capacity2 = 0;601602smhelper.arena()->usage_numbers(&used2, &committed2, &capacity2);603604// used should not grow larger than what we allocated, plus possible overhead.605ASSERT_GE(used2, used);606ASSERT_LE(used2, used + alloc_words * 2);607ASSERT_LE(used2, words_allocated + 100);608used = used2;609610// A jump in committed words should not be larger than commit granule size.611// It can be smaller, since the current chunk of the MetaspaceArena may be612// smaller than a commit granule.613// (Note: unless root chunks are born fully committed)614ASSERT_GE(committed2, used2);615ASSERT_GE(committed2, committed);616const size_t committed_jump = committed2 - committed;617if (committed_jump > 0 && !Settings::new_chunks_are_fully_committed()) {618ASSERT_LE(committed_jump, Settings::commit_granule_words());619}620committed = committed2;621622// Capacity jumps: Test that arenas capacity does not grow too fast.623ASSERT_GE(capacity2, committed2);624ASSERT_GE(capacity2, capacity);625const size_t capacity_jump = capacity2 - capacity;626if (capacity_jump > 0) {627LOG(">" SIZE_FORMAT "->" SIZE_FORMAT "(+" SIZE_FORMAT ")", capacity, capacity2, capacity_jump)628if (capacity_jump > highest_capacity_jump) {629/* Disabled for now since this is rather shaky. The way it is tested makes it too dependent630* on allocation history. Need to rethink this.631ASSERT_LE(capacity_jump, highest_capacity_jump * 2);632ASSERT_GE(capacity_jump, MIN_CHUNK_WORD_SIZE);633ASSERT_LE(capacity_jump, MAX_CHUNK_WORD_SIZE);634*/635highest_capacity_jump = capacity_jump;636}637num_capacity_jumps++;638}639640capacity = capacity2;641642}643644// After all this work, we should see an increase in number of chunk-in-place-enlargements645// (this especially is vulnerable to regression: the decisions of when to do in-place-enlargements are somewhat646// complicated, see MetaspaceArena::attempt_enlarge_current_chunk())647#ifdef ASSERT648if (test_in_place_enlargement) {649const uintx num_chunk_enlarged_2 = metaspace::InternalStats::num_chunks_enlarged();650ASSERT_GT(num_chunk_enlarged_2, num_chunk_enlarged);651}652#endif653}654655// these numbers have to be in sync with arena policy numbers (see memory/metaspace/arenaGrowthPolicy.cpp)656TEST_VM(metaspace, MetaspaceArena_growth_refl_c_inplace) {657test_controlled_growth(Metaspace::ReflectionMetaspaceType, true,658word_size_for_level(CHUNK_LEVEL_1K), true);659}660661TEST_VM(metaspace, MetaspaceArena_growth_refl_c_not_inplace) {662test_controlled_growth(Metaspace::ReflectionMetaspaceType, true,663word_size_for_level(CHUNK_LEVEL_1K), false);664}665666TEST_VM(metaspace, MetaspaceArena_growth_anon_c_inplace) {667test_controlled_growth(Metaspace::ClassMirrorHolderMetaspaceType, true,668word_size_for_level(CHUNK_LEVEL_1K), true);669}670671TEST_VM(metaspace, MetaspaceArena_growth_anon_c_not_inplace) {672test_controlled_growth(Metaspace::ClassMirrorHolderMetaspaceType, true,673word_size_for_level(CHUNK_LEVEL_1K), false);674}675676TEST_VM(metaspace, MetaspaceArena_growth_standard_c_inplace) {677test_controlled_growth(Metaspace::StandardMetaspaceType, true,678word_size_for_level(CHUNK_LEVEL_2K), true);679}680681TEST_VM(metaspace, MetaspaceArena_growth_standard_c_not_inplace) {682test_controlled_growth(Metaspace::StandardMetaspaceType, true,683word_size_for_level(CHUNK_LEVEL_2K), false);684}685686/* Disabled growth tests for BootMetaspaceType: there, the growth steps are too rare,687* and too large, to make any reliable guess as toward chunks get enlarged in place.688TEST_VM(metaspace, MetaspaceArena_growth_boot_c_inplace) {689test_controlled_growth(Metaspace::BootMetaspaceType, true,690word_size_for_level(CHUNK_LEVEL_1M), true);691}692693TEST_VM(metaspace, MetaspaceArena_growth_boot_c_not_inplace) {694test_controlled_growth(Metaspace::BootMetaspaceType, true,695word_size_for_level(CHUNK_LEVEL_1M), false);696}697*/698699TEST_VM(metaspace, MetaspaceArena_growth_refl_nc_inplace) {700test_controlled_growth(Metaspace::ReflectionMetaspaceType, false,701word_size_for_level(CHUNK_LEVEL_2K), true);702}703704TEST_VM(metaspace, MetaspaceArena_growth_refl_nc_not_inplace) {705test_controlled_growth(Metaspace::ReflectionMetaspaceType, false,706word_size_for_level(CHUNK_LEVEL_2K), false);707}708709TEST_VM(metaspace, MetaspaceArena_growth_anon_nc_inplace) {710test_controlled_growth(Metaspace::ClassMirrorHolderMetaspaceType, false,711word_size_for_level(CHUNK_LEVEL_1K), true);712}713714TEST_VM(metaspace, MetaspaceArena_growth_anon_nc_not_inplace) {715test_controlled_growth(Metaspace::ClassMirrorHolderMetaspaceType, false,716word_size_for_level(CHUNK_LEVEL_1K), false);717}718719TEST_VM(metaspace, MetaspaceArena_growth_standard_nc_inplace) {720test_controlled_growth(Metaspace::StandardMetaspaceType, false,721word_size_for_level(CHUNK_LEVEL_4K), true);722}723724TEST_VM(metaspace, MetaspaceArena_growth_standard_nc_not_inplace) {725test_controlled_growth(Metaspace::StandardMetaspaceType, false,726word_size_for_level(CHUNK_LEVEL_4K), false);727}728729/* Disabled growth tests for BootMetaspaceType: there, the growth steps are too rare,730* and too large, to make any reliable guess as toward chunks get enlarged in place.731TEST_VM(metaspace, MetaspaceArena_growth_boot_nc_inplace) {732test_controlled_growth(Metaspace::BootMetaspaceType, false,733word_size_for_level(CHUNK_LEVEL_4M), true);734}735736TEST_VM(metaspace, MetaspaceArena_growth_boot_nc_not_inplace) {737test_controlled_growth(Metaspace::BootMetaspaceType, false,738word_size_for_level(CHUNK_LEVEL_4M), false);739}740*/741742743