1 /* 2 * Copyright (c) 2012, 2018, 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 #ifndef SHARE_VM_MEMORY_METACHUNK_HPP 25 #define SHARE_VM_MEMORY_METACHUNK_HPP 26 27 #include "memory/metaspace/metabase.hpp" 28 #include "memory/metaspace/metaspaceCommon.hpp" 29 #include "utilities/debug.hpp" 30 #include "utilities/globalDefinitions.hpp" 31 32 class MetachunkTest; 33 34 namespace metaspace { 35 namespace internals { 36 37 class VirtualSpaceNode; 38 39 // Metachunk - Quantum of allocation from a Virtualspace 40 // Metachunks are reused (when freed are put on a global freelist) and 41 // have no permanent association to a SpaceManager. 42 43 // +--------------+ <- end --+ --+ 44 // | | | | 45 // | | | free | 46 // | | | | 47 // | | | | size | capacity 48 // | | | | 49 // | | <- top -- + | 50 // | | | | 51 // | | | used | 52 // | | | | 53 // | | | | 54 // +--------------+ <- bottom --+ --+ 55 56 enum ChunkOrigin { 57 // Chunk normally born (via take_from_committed) 58 origin_normal = 1, 59 // Chunk was born as padding chunk 60 origin_pad = 2, 61 // Chunk was born as leftover chunk in VirtualSpaceNode::retire 62 origin_leftover = 3, 63 // Chunk was born as result of a merge of smaller chunks 64 origin_merge = 4, 65 // Chunk was born as result of a split of a larger chunk 66 origin_split = 5, 67 68 origin_minimum = origin_normal, 69 origin_maximum = origin_split, 70 origins_count = origin_maximum + 1 71 }; 72 73 inline bool is_valid_chunkorigin(ChunkOrigin origin) { 74 return origin == origin_normal || 75 origin == origin_pad || 76 origin == origin_leftover || 77 origin == origin_merge || 78 origin == origin_split; 79 } 80 81 class Metachunk : public Metabase<Metachunk> { 82 83 friend class ::MetachunkTest; 84 85 // The VirtualSpaceNode containing this chunk. 86 VirtualSpaceNode* const _container; 87 88 // Current allocation top. 89 MetaWord* _top; 90 91 // A 32bit sentinel for debugging purposes. 92 enum { CHUNK_SENTINEL = 0x4d4554EF, // "MET" 93 CHUNK_SENTINEL_INVALID = 0xFEEEEEEF 94 }; 95 96 uint32_t _sentinel; 97 98 const ChunkIndex _chunk_type; 99 const bool _is_class; 100 // Whether the chunk is free (in freelist) or in use by some class loader. 101 bool _is_tagged_free; 102 103 ChunkOrigin _origin; 104 int _use_count; 105 106 MetaWord* initial_top() const { return (MetaWord*)this + overhead(); } 107 MetaWord* top() const { return _top; } 108 109 public: 110 // Metachunks are allocated out of a MetadataVirtualSpace and 111 // and use some of its space to describe itself (plus alignment 112 // considerations). Metadata is allocated in the rest of the chunk. 113 // This size is the overhead of maintaining the Metachunk within 114 // the space. 115 116 // Alignment of each allocation in the chunks. 117 static size_t object_alignment(); 118 119 // Size of the Metachunk header, in words, including alignment. 120 static size_t overhead(); 121 122 Metachunk(ChunkIndex chunktype, bool is_class, size_t word_size, VirtualSpaceNode* container); 123 124 MetaWord* allocate(size_t word_size); 125 126 VirtualSpaceNode* container() const { return _container; } 127 128 MetaWord* bottom() const { return (MetaWord*) this; } 129 130 // Reset top to bottom so chunk can be reused. 131 void reset_empty() { _top = initial_top(); clear_next(); clear_prev(); } 132 bool is_empty() { return _top == initial_top(); } 133 134 // used (has been allocated) 135 // free (available for future allocations) 136 size_t word_size() const { return size(); } 137 size_t used_word_size() const; 138 size_t free_word_size() const; 139 140 bool is_tagged_free() { return _is_tagged_free; } 141 void set_is_tagged_free(bool v) { _is_tagged_free = v; } 142 143 bool contains(const void* ptr) { return bottom() <= ptr && ptr < _top; } 144 145 void print_on(outputStream* st) const; 146 147 bool is_valid_sentinel() const { return _sentinel == CHUNK_SENTINEL; } 148 void remove_sentinel() { _sentinel = CHUNK_SENTINEL_INVALID; } 149 150 int get_use_count() const { return _use_count; } 151 void inc_use_count() { _use_count ++; } 152 153 ChunkOrigin get_origin() const { return _origin; } 154 void set_origin(ChunkOrigin orig) { _origin = orig; } 155 156 ChunkIndex get_chunk_type() const { return _chunk_type; } 157 bool is_class() const { return _is_class; } 158 159 DEBUG_ONLY(void mangle(juint word_value);) 160 DEBUG_ONLY(void verify() const;) 161 162 }; 163 164 165 // Helper function that does a bunch of checks for a chunk. 166 DEBUG_ONLY(void do_verify_chunk(Metachunk* chunk);) 167 168 // Given a Metachunk, update its in-use information (both in the 169 // chunk and the occupancy map). 170 void do_update_in_use_info_for_chunk(Metachunk* chunk, bool inuse); 171 172 } // namespace metaspace 173 } // namespace internals 174 175 #endif // SHARE_VM_MEMORY_METACHUNK_HPP