rev 57380 : [mq]: metaspace-improvement
1 /* 2 * Copyright (c) 2012, 2016, Oracle and/or its affiliates. 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 it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 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 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 26 #include "precompiled.hpp" 27 28 #include "memory/metaspace/chunkLevel.hpp" 29 #include "memory/metaspace/chunkTree.hpp" 30 #include "memory/metaspace/constants.hpp" 31 #include "memory/metaspace/metachunk.hpp" 32 #include "memory/metaspace/virtualSpaceNode.hpp" 33 34 #include "utilities/align.hpp" 35 #include "utilities/copy.hpp" 36 #include "utilities/debug.hpp" 37 38 namespace metaspace { 39 40 // Must align pointers and sizes to 8 so that 64 bit types get correctly aligned. 41 static const size_t allocation_alignment = 8; 42 43 // Make sure that the Klass alignment also agree. 44 STATIC_ASSERT(allocation_alignment == (size_t)KlassAlignmentInBytes); 45 46 void Metachunk::remove_from_list() { 47 if (_prev != NULL) { 48 _prev->set_next(_next); 49 } 50 if (_next != NULL) { 51 _next->set_prev(_prev); 52 } 53 _prev = _next = NULL; 54 } 55 56 // Allocate word_size words from this chunk. 57 // 58 // May cause memory to be committed. That may fail if we hit a commit limit. In that case, 59 // NULL is returned and p_did_hit_commit_limit will be set to true. 60 // If the remainder portion of the chunk was too small to hold the allocation, 61 // NULL is returned and p_did_hit_commit_limit will be set to false. 62 MetaWord* Metachunk::allocate(size_t word_size, bool* p_did_hit_commit_limit) { 63 64 size_t request_word_size = align_up(word_size, allocation_alignment); 65 66 // Space enough left? 67 if (free_words() < request_word_size) { 68 *p_did_hit_commit_limit = false; 69 return NULL; 70 } 71 72 // Will bring this allocation us over the border of the next commit granule? 73 MetaWord* const top = top(); 74 MetaWord* const next_top = top() + request_word_size; 75 76 MetaWord* const commit_granule_border = align_up(top, constants::commit_granule_words); 77 78 if (next_top > commit_granule_border) { 79 // We may need to commit. 80 81 // Calc the extend of the area we may need to commit. 82 MetaWord* const commit_granule_border_2 = align_up(next_top, constants::commit_granule_words); 83 84 // and attempt to commit. 85 const size_t word_size_to_commit = commit_granule_border_2 - commit_granule_border; 86 if (_vsnode->ensure_range_is_committed(commit_granule_border, word_size_to_commit) == false) { 87 // ... which failed because we hit a limit. 88 *p_did_hit_commit_limit = true; 89 return NULL; 90 } 91 92 } 93 94 // All is well. 95 _used_words += request_word_size; 96 97 return top; 98 99 } 100 101 #ifdef ASSERT 102 103 void Metachunk::verify(bool slow) const { 104 105 // Note: only call this on a life Metachunk. 106 107 chklvl::check_valid_level(level()); 108 109 // Test base pointer 110 assert(vsnode() != NULL, "No space"); 111 vsnode()->check_pointer(base()); 112 assert(base() != NULL, "Base pointer NULL"); 113 114 // Starting address shall be aligned to chunk size. 115 const size_t required_alignment = word_size() * sizeof(MetaWord); 116 assert(is_aligned(base(), required_alignment), 117 "Chunk " PTR_FORMAT ": (size " SIZE_FORMAT ") not aligned correctly to " SIZE_FORMAT ".", 118 p2i(this), word_size() * sizeof(MetaWord), required_alignment); 119 120 // Used words 121 assert(used_words() < word_size(), "oob"); 122 123 // We shall have a reference to a tree node and that node shall refer back to us 124 assert(tree_node() != NULL && 125 tree_node()->check_is_child(this), "Invalid tree node relationship"); 126 127 128 } 129 #endif // ASSERT 130 131 } // namespace metaspace 132 --- EOF ---