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/metachunkList.hpp"
33
34 class outputStream;
35 class Mutex;
36
37 namespace metaspace {
38
39 class ArenaGrowthPolicy;
40 class ChunkManager;
41 class Metachunk;
42 class FreeBlocks;
43
44 struct ArenaStats;
45
46 // The MetaspaceArena is a growable metaspace memory pool belonging to a CLD;
47 // internally it consists of a list of metaspace chunks, of which the head chunk
48 // is the current chunk from which we allocate via pointer bump.
49 //
50 // +---------------+
51 // | Arena |
52 // +---------------+
53 // |
54 // | _chunks commit top
55 // | v
56 // +----------+ +----------+ +----------+ +----------+
57 // | retired | ---> | retired | ---> | retired | ---> | current |
58 // | chunk | | chunk | | chunk | | chunk |
59 // +----------+ +----------+ +----------+ +----------+
60 // ^
61 // used top
62 //
63 // +------------+
64 // | FreeBlocks | --> O -> O -> O -> O
65 // +------------+
66 //
67 //
68
69 // When the current chunk is used up, MetaspaceArena requests a new chunk from
70 // the associated ChunkManager.
71 //
72 // MetaspaceArena also keeps a FreeBlocks structure to manage memory blocks which
73 // had been deallocated prematurely.
74 //
75
76 class MetaspaceArena : public CHeapObj<mtClass> {
77
78 // Please note that access to a metaspace arena may be shared
79 // between threads and needs to be synchronized in CLMS.
80
81 // Reference to the chunk manager to allocate chunks from.
82 ChunkManager* const _chunk_manager;
83
84 // Reference to the growth policy to use.
85 const ArenaGrowthPolicy* const _growth_policy;
86
87 // List of chunks. Head of the list is the current chunk.
88 MetachunkList _chunks;
89
90 // Structure to take care of leftover/deallocated space in used chunks.
91 // Owned by the Arena. Gets allocated on demand only.
92 FreeBlocks* _fbl;
93
94 Metachunk* current_chunk() { return _chunks.first(); }
95 const Metachunk* current_chunk() const { return _chunks.first(); }
96
97 // Reference to an outside counter to keep track of used space.
98 SizeAtomicCounter* const _total_used_words_counter;
99
100 // A name for purely debugging/logging purposes.
109 class Fence {
110 static const uintx EyeCatcher =
111 NOT_LP64(0x77698465) LP64_ONLY(0x7769846577698465ULL); // "META" resp "METAMETA"
112 // Two eyecatchers to easily spot a corrupted _next pointer
113 const uintx _eye1;
114 const Fence* const _next;
115 NOT_LP64(uintx _dummy;)
116 const uintx _eye2;
117 public:
118 Fence(const Fence* next) : _eye1(EyeCatcher), _next(next), _eye2(EyeCatcher) {}
119 const Fence* next() const { return _next; }
120 void verify() const;
121 };
122 const Fence* _first_fence;
123 #endif // ASSERT
124
125 ChunkManager* chunk_manager() const { return _chunk_manager; }
126
127 // free block list
128 FreeBlocks* fbl() const { return _fbl; }
129 void add_allocation_to_fbl(MetaWord* p, size_t word_size);
130
131 // Given a chunk, add its remaining free committed space to the free block list.
132 void salvage_chunk(Metachunk* c);
133
134 // Allocate a new chunk from the underlying chunk manager able to hold at least
135 // requested word size.
136 Metachunk* allocate_new_chunk(size_t requested_word_size);
137
138 // Returns the level of the next chunk to be added, acc to growth policy.
139 chunklevel_t next_chunk_level() const;
140
141 // Attempt to enlarge the current chunk to make it large enough to hold at least
142 // requested_word_size additional words.
143 //
144 // On success, true is returned, false otherwise.
145 bool attempt_enlarge_current_chunk(size_t requested_word_size);
146
147 // Returns true if the area indicated by pointer and size have actually been allocated
148 // from this arena.
149 DEBUG_ONLY(bool is_valid_area(MetaWord* p, size_t word_size) const;)
150
151 // Allocate from the arena proper, once dictionary allocations and fencing are sorted out.
152 MetaWord* allocate_inner(size_t word_size);
153
154 public:
155
156 MetaspaceArena(ChunkManager* chunk_manager, const ArenaGrowthPolicy* growth_policy,
157 SizeAtomicCounter* total_used_words_counter,
158 const char* name);
159
160 ~MetaspaceArena();
161
162 // Allocate memory from Metaspace.
163 // 1) Attempt to allocate from the dictionary of deallocated blocks.
164 // 2) Attempt to allocate from the current chunk.
165 // 3) Attempt to enlarge the current chunk in place if it is too small.
166 // 4) Attempt to get a new chunk and allocate from that chunk.
167 // At any point, if we hit a commit limit, we return null.
168 MetaWord* allocate(size_t word_size);
169
170 // Prematurely returns a metaspace allocation to the _block_freelists because it is not
171 // needed anymore.
172 void deallocate(MetaWord* p, size_t word_size);
173
174 // Update statistics. This walks all in-use chunks.
175 void add_to_statistics(ArenaStats* out) const;
176
177 // Convenience method to get the most important usage statistics.
178 // For deeper analysis use add_to_statistics().
179 void usage_numbers(size_t* p_used_words, size_t* p_committed_words, size_t* p_capacity_words) const;
180
181 DEBUG_ONLY(void verify() const;)
182 DEBUG_ONLY(void verify_allocation_guards() const;)
183
184 void print_on(outputStream* st) const;
185
186 };
187
188 } // namespace metaspace
189
190 #endif // SHARE_MEMORY_METASPACE_METASPACEARENA_HPP
191
|
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.
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
|