1 /* 2 * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. 3 * Copyright (c) 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 #ifndef SHARE_MEMORY_METASPACE_METASPACEARENA_HPP 27 #define SHARE_MEMORY_METASPACE_METASPACEARENA_HPP 28 29 #include "memory/allocation.hpp" 30 #include "memory/metaspace.hpp" 31 #include "memory/metaspace/counters.hpp" 32 #include "memory/metaspace/metablock.hpp" 33 #include "memory/metaspace/metachunkList.hpp" 34 35 class outputStream; 36 class Mutex; 37 38 namespace metaspace { 39 40 class ArenaGrowthPolicy; 41 struct ArenaStats; 42 class MetaspaceContext; 43 class ChunkManager; 44 class FreeBlocks; 45 class Metachunk; 46 47 48 // The MetaspaceArena is a growable metaspace memory pool belonging to a CLD; 49 // internally it consists of a list of metaspace chunks, of which the head chunk 50 // is the current chunk from which we allocate via pointer bump. 51 // 52 // +---------------+ 53 // | Arena | 54 // +---------------+ 55 // | 56 // | _chunks commit top 57 // | v 58 // +----------+ +----------+ +----------+ +----------+ 59 // | retired | ---> | retired | ---> | retired | ---> | current | 60 // | chunk | | chunk | | chunk | | chunk | 61 // +----------+ +----------+ +----------+ +----------+ 62 // ^ 63 // used top 64 // 65 // +------------+ 66 // | FreeBlocks | --> O -> O -> O -> O 67 // +------------+ 68 // 69 // 70 71 // When the current chunk is used up, MetaspaceArena requests a new chunk from 72 // the associated ChunkManager. 73 // 74 // MetaspaceArena also keeps a FreeBlocks structure to manage memory blocks which 75 // had been deallocated prematurely. 76 // 77 78 class MetaspaceArena : public CHeapObj<mtClass> { 79 friend class MetaspaceArenaTestFriend; 80 81 // Please note that access to a metaspace arena may be shared 82 // between threads and needs to be synchronized in CLMS. 83 84 const size_t _allocation_alignment_words; 85 86 // Reference to the chunk manager to allocate chunks from. 87 ChunkManager* const _chunk_manager; 88 89 // Reference to the growth policy to use. 90 const ArenaGrowthPolicy* const _growth_policy; 91 92 // List of chunks. Head of the list is the current chunk. 93 MetachunkList _chunks; 94 95 // Structure to take care of leftover/deallocated space in used chunks. 96 // Owned by the Arena. Gets allocated on demand only. 97 FreeBlocks* _fbl; 98 99 Metachunk* current_chunk() { return _chunks.first(); } 100 const Metachunk* current_chunk() const { return _chunks.first(); } 101 102 // Reference to an outside counter to keep track of used space. 103 SizeAtomicCounter* const _total_used_words_counter; 104 105 // A name for purely debugging/logging purposes. 106 const char* const _name; 107 108 #ifdef ASSERT 109 // Allocation guards: When active, arena allocations are interleaved with 110 // fence allocations. An overwritten fence indicates a buffer overrun in either 111 // the preceding or the following user block. All fences are linked together; 112 // validating the fences just means walking that linked list. 113 // Note that for the Arena, fence blocks are just another form of user blocks. 114 class Fence { 115 static const uintx EyeCatcher = 116 NOT_LP64(0x77698465) LP64_ONLY(0x7769846577698465ULL); // "META" resp "METAMETA" 117 // Two eyecatchers to easily spot a corrupted _next pointer 118 const uintx _eye1; 119 const Fence* const _next; 120 NOT_LP64(uintx _dummy;) 121 const uintx _eye2; 122 public: 123 Fence(const Fence* next) : _eye1(EyeCatcher), _next(next), _eye2(EyeCatcher) {} 124 const Fence* next() const { return _next; } 125 void verify() const; 126 }; 127 const Fence* _first_fence; 128 #endif // ASSERT 129 130 ChunkManager* chunk_manager() const { return _chunk_manager; } 131 132 // free block list 133 FreeBlocks* fbl() const { return _fbl; } 134 void add_allocation_to_fbl(MetaBlock bl); 135 136 // Given a chunk, return the committed remainder of this chunk. 137 MetaBlock salvage_chunk(Metachunk* c); 138 139 // Allocate a new chunk from the underlying chunk manager able to hold at least 140 // requested word size. 141 Metachunk* allocate_new_chunk(size_t requested_word_size); 142 143 // Returns the level of the next chunk to be added, acc to growth policy. 144 chunklevel_t next_chunk_level() const; 145 146 // Attempt to enlarge the current chunk to make it large enough to hold at least 147 // requested_word_size additional words. 148 // 149 // On success, true is returned, false otherwise. 150 bool attempt_enlarge_current_chunk(size_t requested_word_size); 151 152 // Allocate from the arena proper, once dictionary allocations and fencing are sorted out. 153 MetaBlock allocate_inner(size_t word_size, MetaBlock& wastage); 154 155 public: 156 157 MetaspaceArena(MetaspaceContext* context, 158 const ArenaGrowthPolicy* growth_policy, 159 size_t allocation_alignment_words, 160 const char* name); 161 162 ~MetaspaceArena(); 163 164 size_t allocation_alignment_words() const { return _allocation_alignment_words; } 165 size_t allocation_alignment_bytes() const { return allocation_alignment_words() * BytesPerWord; } 166 167 // Allocate memory from Metaspace. 168 // On success, returns non-empty block of the specified word size, and 169 // possibly a wastage block that is the result of alignment operations. 170 // On failure, returns an empty block. Failure may happen if we hit a 171 // commit limit. 172 MetaBlock allocate(size_t word_size, MetaBlock& wastage); 173 174 // Prematurely returns a metaspace allocation to the _block_freelists because it is not 175 // needed anymore. 176 void deallocate(MetaBlock bl); 177 178 // Update statistics. This walks all in-use chunks. 179 void add_to_statistics(ArenaStats* out) const; 180 181 // Convenience method to get the most important usage statistics. 182 // For deeper analysis use add_to_statistics(). 183 void usage_numbers(size_t* p_used_words, size_t* p_committed_words, size_t* p_capacity_words) const; 184 185 DEBUG_ONLY(void verify() const;) 186 DEBUG_ONLY(void verify_allocation_guards() const;) 187 188 void print_on(outputStream* st) const; 189 190 // Returns true if the given block is contained in this arena 191 DEBUG_ONLY(bool contains(MetaBlock bl) const;) 192 }; 193 194 } // namespace metaspace 195 196 #endif // SHARE_MEMORY_METASPACE_METASPACEARENA_HPP 197