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 27 #include "precompiled.hpp" 28 #include "metaspace/metaspaceTestsCommon.hpp" 29 #include "metaspace/metaspaceTestContexts.hpp" 30 31 using namespace metaspace::chunklevel; 32 33 34 void ChunkTestsContext::checked_alloc_chunk_0(Metachunk** p_return_value, chunklevel_t preferred_level, chunklevel_t max_level, 35 size_t min_committed_size) { 36 37 *p_return_value = NULL; 38 39 Metachunk* c = cm().get_chunk(preferred_level, max_level, min_committed_size); 40 41 if (c != NULL) { 42 43 ASSERT_LE(c->level(), max_level); 44 ASSERT_GE(c->level(), preferred_level); 45 ASSERT_GE(c->committed_words(), min_committed_size); 46 ASSERT_EQ(c->committed_words(), c->free_below_committed_words()); 47 ASSERT_EQ(c->used_words(), (size_t)0); 48 ASSERT_TRUE(c->is_in_use()); 49 ASSERT_FALSE(c->is_free()); 50 ASSERT_FALSE(c->is_dead()); 51 ASSERT_NULL(c->next()); 52 ASSERT_NULL(c->prev()); 53 if (c->level() == HIGHEST_CHUNK_LEVEL) { 54 ASSERT_TRUE(c->is_leaf_chunk()); 55 } else { 56 ASSERT_FALSE(c->is_leaf_chunk()); 57 } 58 if (c->level() == LOWEST_CHUNK_LEVEL) { 59 ASSERT_TRUE(c->is_root_chunk()); 60 } else { 61 ASSERT_FALSE(c->is_root_chunk()); 62 } 63 if (_num_chunks_allocated == 0) { // First chunk? We can make more assumptions 64 ASSERT_EQ(c->level(), preferred_level); 65 // Needs lock EXPECT_NULL(c->next_in_vs()); 66 // Needs lock EXPECT_NULL(c->prev_in_vs()); 67 ASSERT_TRUE(c->is_root_chunk() || c->is_leader()); 68 } 69 _num_chunks_allocated ++; 70 71 } 72 73 *p_return_value = c; 74 75 } 76 77 // Test pattern established when allocating from the chunk with allocate_from_chunk_with_tests(). 78 void ChunkTestsContext::test_pattern(Metachunk* c, size_t word_size) { 79 check_range_for_pattern(c->base(), word_size, (uintx)c); 80 } 81 82 void ChunkTestsContext::return_chunk(Metachunk* c) { 83 test_pattern(c); 84 c->set_in_use(); // Forestall assert in cm 85 cm().return_chunk(c); 86 } 87 88 void ChunkTestsContext::allocate_from_chunk(MetaWord** p_return_value, Metachunk* c, size_t word_size) { 89 90 size_t used_before = c->used_words(); 91 size_t free_before = c->free_words(); 92 size_t free_below_committed_before = c->free_below_committed_words(); 93 const MetaWord* top_before = c->top(); 94 95 MetaWord* p = c->allocate(word_size); 96 EXPECT_NOT_NULL(p); 97 EXPECT_EQ(c->used_words(), used_before + word_size); 98 EXPECT_EQ(c->free_words(), free_before - word_size); 99 EXPECT_EQ(c->free_below_committed_words(), free_below_committed_before - word_size); 100 EXPECT_EQ(c->top(), top_before + word_size); 101 102 // Old content should be preserved 103 test_pattern(c, used_before); 104 105 // Fill newly allocated range too 106 fill_range_with_pattern(p, word_size, (uintx)c); 107 108 *p_return_value = p; 109 } 110 111 void ChunkTestsContext::commit_chunk_with_test(Metachunk* c, size_t additional_size) { 112 113 size_t used_before = c->used_words(); 114 size_t free_before = c->free_words(); 115 const MetaWord* top_before = c->top(); 116 117 c->set_in_use(); 118 bool b = c->ensure_committed_additional(additional_size); 119 EXPECT_TRUE(b); 120 121 // We should have enough committed size now 122 EXPECT_GE(c->free_below_committed_words(), additional_size); 123 124 // used, free, top should be unchanged. 125 EXPECT_EQ(c->used_words(), used_before); 126 EXPECT_EQ(c->free_words(), free_before); 127 EXPECT_EQ(c->top(), top_before); 128 129 test_pattern(c, used_before); 130 131 } 132 133 void ChunkTestsContext::commit_chunk_expect_failure(Metachunk* c, size_t additional_size) { 134 135 size_t used_before = c->used_words(); 136 size_t free_before = c->free_words(); 137 size_t free_below_committed_before = c->free_below_committed_words(); 138 const MetaWord* top_before = c->top(); 139 140 c->set_in_use(); 141 bool b = c->ensure_committed_additional(additional_size); 142 EXPECT_FALSE(b); 143 144 // Nothing should have changed 145 EXPECT_EQ(c->used_words(), used_before); 146 EXPECT_EQ(c->free_words(), free_before); 147 EXPECT_EQ(c->free_below_committed_words(), free_below_committed_before); 148 EXPECT_EQ(c->top(), top_before); 149 150 test_pattern(c, used_before); 151 152 } 153 154 void ChunkTestsContext::uncommit_chunk_with_test(Metachunk* c) { 155 if (c->word_size() >= Settings::commit_granule_words()) { 156 c->set_free(); // Forestall assert in uncommit 157 c->reset_used_words(); 158 c->uncommit(); 159 160 EXPECT_EQ(c->free_below_committed_words(), (size_t)0); 161 EXPECT_EQ(c->used_words(), (size_t)0); 162 EXPECT_EQ(c->free_words(), c->word_size()); 163 EXPECT_EQ(c->top(), c->base()); 164 EXPECT_TRUE(c->is_fully_uncommitted()); 165 } 166 } 167 168 169 170 /////// SparseArray<T> //////////////// 171 172 173