1 /* 2 * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. 3 * Copyright (c) 2018, 2020 SAP SE. All rights reserved. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 * 24 */ 25 26 #include "precompiled.hpp" 27 28 #include "metaspace/metaspace_testhelper.hpp" 29 30 using namespace metaspace::chunklevel; 31 32 // No reserve limit, and a commit limit. 33 MetaspaceTestHelper::MetaspaceTestHelper(size_t commit_limit, size_t reserve_limit) 34 : metaspace::MetaspaceTestContext("metaspace-gtest-context", commit_limit, reserve_limit), 35 _num_chunks_allocated(0) 36 { 37 } 38 39 void MetaspaceTestHelper::checked_alloc_chunk_0(Metachunk** p_return_value, chunklevel_t preferred_level, chunklevel_t max_level, 40 size_t min_committed_size) { 41 42 *p_return_value = NULL; 43 44 Metachunk* c = cm().get_chunk(preferred_level, max_level, min_committed_size); 45 46 if (c != NULL) { 47 48 ASSERT_LE(c->level(), max_level); 49 ASSERT_GE(c->level(), preferred_level); 50 ASSERT_GE(c->committed_words(), min_committed_size); 51 ASSERT_EQ(c->committed_words(), c->free_below_committed_words()); 52 ASSERT_EQ(c->used_words(), (size_t)0); 53 ASSERT_TRUE(c->is_in_use()); 54 ASSERT_FALSE(c->is_free()); 55 ASSERT_FALSE(c->is_dead()); 56 ASSERT_NULL(c->next()); 57 ASSERT_NULL(c->prev()); 58 if (c->level() == HIGHEST_CHUNK_LEVEL) { 59 ASSERT_TRUE(c->is_leaf_chunk()); 60 } else { 61 ASSERT_FALSE(c->is_leaf_chunk()); 62 } 63 if (c->level() == LOWEST_CHUNK_LEVEL) { 64 ASSERT_TRUE(c->is_root_chunk()); 65 } else { 66 ASSERT_FALSE(c->is_root_chunk()); 67 } 68 if (_num_chunks_allocated == 0) { // First chunk? We can make more assumptions 69 ASSERT_EQ(c->level(), preferred_level); 70 // Needs lock EXPECT_NULL(c->next_in_vs()); 71 // Needs lock EXPECT_NULL(c->prev_in_vs()); 72 ASSERT_TRUE(c->is_root_chunk() || c->is_leader()); 73 } 74 _num_chunks_allocated ++; 75 76 } 77 78 *p_return_value = c; 79 80 } 81 82 // Test pattern established when allocating from the chunk with allocate_from_chunk_with_tests(). 83 void MetaspaceTestHelper::test_pattern(Metachunk* c, size_t word_size) { 84 check_range_for_pattern(c->base(), word_size, (uintx)c); 85 } 86 87 void MetaspaceTestHelper::return_chunk(Metachunk* c) { 88 test_pattern(c); 89 c->set_in_use(); // Forestall assert in cm 90 cm().return_chunk(c); 91 } 92 93 void MetaspaceTestHelper::allocate_from_chunk(MetaWord** p_return_value, Metachunk* c, size_t word_size) { 94 95 size_t used_before = c->used_words(); 96 size_t free_before = c->free_words(); 97 size_t free_below_committed_before = c->free_below_committed_words(); 98 const MetaWord* top_before = c->top(); 99 100 MetaWord* p = c->allocate(word_size); 101 EXPECT_NOT_NULL(p); 102 EXPECT_EQ(c->used_words(), used_before + word_size); 103 EXPECT_EQ(c->free_words(), free_before - word_size); 104 EXPECT_EQ(c->free_below_committed_words(), free_below_committed_before - word_size); 105 EXPECT_EQ(c->top(), top_before + word_size); 106 107 // Old content should be preserved 108 test_pattern(c, used_before); 109 110 // Fill newly allocated range too 111 fill_range_with_pattern(p, word_size, (uintx)c); 112 113 *p_return_value = p; 114 } 115 116 void MetaspaceTestHelper::commit_chunk_with_test(Metachunk* c, size_t additional_size) { 117 118 size_t used_before = c->used_words(); 119 size_t free_before = c->free_words(); 120 const MetaWord* top_before = c->top(); 121 122 c->set_in_use(); 123 bool b = c->ensure_committed_additional(additional_size); 124 EXPECT_TRUE(b); 125 126 // We should have enough committed size now 127 EXPECT_GE(c->free_below_committed_words(), additional_size); 128 129 // used, free, top should be unchanged. 130 EXPECT_EQ(c->used_words(), used_before); 131 EXPECT_EQ(c->free_words(), free_before); 132 EXPECT_EQ(c->top(), top_before); 133 134 test_pattern(c, used_before); 135 136 } 137 138 void MetaspaceTestHelper::commit_chunk_expect_failure(Metachunk* c, size_t additional_size) { 139 140 size_t used_before = c->used_words(); 141 size_t free_before = c->free_words(); 142 size_t free_below_committed_before = c->free_below_committed_words(); 143 const MetaWord* top_before = c->top(); 144 145 c->set_in_use(); 146 bool b = c->ensure_committed_additional(additional_size); 147 EXPECT_FALSE(b); 148 149 // Nothing should have changed 150 EXPECT_EQ(c->used_words(), used_before); 151 EXPECT_EQ(c->free_words(), free_before); 152 EXPECT_EQ(c->free_below_committed_words(), free_below_committed_before); 153 EXPECT_EQ(c->top(), top_before); 154 155 test_pattern(c, used_before); 156 157 } 158 159 void MetaspaceTestHelper::uncommit_chunk_with_test(Metachunk* c) { 160 if (c->word_size() >= Settings::commit_granule_words()) { 161 c->set_free(); // Forestall assert in uncommit 162 c->reset_used_words(); 163 c->uncommit(); 164 165 EXPECT_EQ(c->free_below_committed_words(), (size_t)0); 166 EXPECT_EQ(c->used_words(), (size_t)0); 167 EXPECT_EQ(c->free_words(), c->word_size()); 168 EXPECT_EQ(c->top(), c->base()); 169 EXPECT_TRUE(c->is_fully_uncommitted()); 170 } 171 } 172 173 174 175 /////// SparseArray<T> //////////////// 176 177 178