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 #include "precompiled.hpp"
27 #include "logging/log.hpp"
28 #include "logging/logStream.hpp"
29 #include "memory/metaspace/chunkManager.hpp"
30 #include "memory/metaspace/counters.hpp"
31 #include "memory/metaspace/freeBlocks.hpp"
32 #include "memory/metaspace/internalStats.hpp"
33 #include "memory/metaspace/metachunk.hpp"
34 #include "memory/metaspace/metaspaceArena.hpp"
35 #include "memory/metaspace/metaspaceArenaGrowthPolicy.hpp"
36 #include "memory/metaspace/metaspaceCommon.hpp"
37 #include "memory/metaspace/metaspaceSettings.hpp"
38 #include "memory/metaspace/metaspaceStatistics.hpp"
39 #include "memory/metaspace/virtualSpaceList.hpp"
40 #include "runtime/atomic.hpp"
41 #include "runtime/init.hpp"
42 #include "runtime/mutexLocker.hpp"
43 #include "services/memoryService.hpp"
44 #include "utilities/align.hpp"
45 #include "utilities/debug.hpp"
46 #include "utilities/globalDefinitions.hpp"
47
48 namespace metaspace {
49
50 #define LOGFMT "Arena @" PTR_FORMAT " (%s)"
51 #define LOGFMT_ARGS p2i(this), this->_name
52
53 // Returns the level of the next chunk to be added, acc to growth policy.
90 const chunklevel_t max_level = chunklevel::level_fitting_word_size(requested_word_size);
91 const chunklevel_t preferred_level = MIN2(max_level, next_chunk_level());
92
93 Metachunk* c = _chunk_manager->get_chunk(preferred_level, max_level, requested_word_size);
94 if (c == NULL) {
95 return NULL;
96 }
97
98 assert(c->is_in_use(), "Wrong chunk state.");
99 assert(c->free_below_committed_words() >= requested_word_size, "Chunk not committed");
100 return c;
101 }
102
103 void MetaspaceArena::add_allocation_to_fbl(MetaWord* p, size_t word_size) {
104 if (_fbl == NULL) {
105 _fbl = new FreeBlocks(); // Create only on demand
106 }
107 _fbl->add_block(p, word_size);
108 }
109
110 MetaspaceArena::MetaspaceArena(ChunkManager* chunk_manager, const ArenaGrowthPolicy* growth_policy,
111 Mutex* lock, SizeAtomicCounter* total_used_words_counter,
112 const char* name) :
113 _lock(lock),
114 _chunk_manager(chunk_manager),
115 _growth_policy(growth_policy),
116 _chunks(),
117 _fbl(NULL),
118 _total_used_words_counter(total_used_words_counter),
119 _name(name)
120 #ifdef ASSERT
121 , _first_fence(NULL)
122 #endif
123 {
124 UL(debug, ": born.");
125
126 // Update statistics
127 InternalStats::inc_num_arena_births();
128 }
129
130 MetaspaceArena::~MetaspaceArena() {
131 #ifdef ASSERT
132 verify();
133 if (Settings::use_allocation_guard()) {
134 verify_allocation_guards();
135 }
136 #endif
137
138 MutexLocker fcl(lock(), Mutex::_no_safepoint_check_flag);
139 MemRangeCounter return_counter;
140
141 Metachunk* c = _chunks.first();
142 Metachunk* c2 = NULL;
207 if (next_chunk_level() > c->level()) {
208 return false;
209 }
210
211 bool success = _chunk_manager->attempt_enlarge_chunk(c);
212 assert(success == false || c->free_words() >= requested_word_size, "Sanity");
213 return success;
214 }
215
216 // Allocate memory from Metaspace.
217 // 1) Attempt to allocate from the free block list.
218 // 2) Attempt to allocate from the current chunk.
219 // 3) Attempt to enlarge the current chunk in place if it is too small.
220 // 4) Attempt to get a new chunk and allocate from that chunk.
221 // At any point, if we hit a commit limit, we return NULL.
222 MetaWord* MetaspaceArena::allocate(size_t requested_word_size) {
223 MutexLocker cl(lock(), Mutex::_no_safepoint_check_flag);
224 UL2(trace, "requested " SIZE_FORMAT " words.", requested_word_size);
225
226 MetaWord* p = NULL;
227 const size_t raw_word_size = get_raw_word_size_for_requested_word_size(requested_word_size);
228
229 // Before bothering the arena proper, attempt to re-use a block from the free blocks list
230 if (_fbl != NULL && !_fbl->is_empty()) {
231 p = _fbl->remove_block(raw_word_size);
232 if (p != NULL) {
233 DEBUG_ONLY(InternalStats::inc_num_allocs_from_deallocated_blocks();)
234 UL2(trace, "taken from fbl (now: %d, " SIZE_FORMAT ").",
235 _fbl->count(), _fbl->total_size());
236 // Note: free blocks in freeblock dictionary still count as "used" as far as statistics go;
237 // therefore we have no need to adjust any usage counters (see epilogue of allocate_inner())
238 // and can just return here.
239 return p;
240 }
241 }
242
243 // Primary allocation
244 p = allocate_inner(requested_word_size);
245
246 #ifdef ASSERT
247 // Fence allocation
251 if (guard != NULL) {
252 // Ignore allocation errors for the fence to keep coding simple. If this
253 // happens (e.g. because right at this time we hit the Metaspace GC threshold)
254 // we miss adding this one fence. Not a big deal. Note that his would
255 // be pretty rare. Chances are much higher the primary allocation above
256 // would have already failed).
257 Fence* f = new(guard) Fence(_first_fence);
258 _first_fence = f;
259 }
260 }
261 #endif // ASSERT
262
263 return p;
264 }
265
266 // Allocate from the arena proper, once dictionary allocations and fencing are sorted out.
267 MetaWord* MetaspaceArena::allocate_inner(size_t requested_word_size) {
268
269 assert_lock_strong(lock());
270
271 const size_t raw_word_size = get_raw_word_size_for_requested_word_size(requested_word_size);
272 MetaWord* p = NULL;
273 bool current_chunk_too_small = false;
274 bool commit_failure = false;
275
276 if (current_chunk() != NULL) {
277
278 // Attempt to satisfy the allocation from the current chunk.
279
280 // If the current chunk is too small to hold the requested size, attempt to enlarge it.
281 // If that fails, retire the chunk.
282 if (current_chunk()->free_words() < raw_word_size) {
283 if (!attempt_enlarge_current_chunk(raw_word_size)) {
284 current_chunk_too_small = true;
285 } else {
286 DEBUG_ONLY(InternalStats::inc_num_chunks_enlarged();)
287 UL(debug, "enlarged chunk.");
288 }
289 }
290
291 // Commit the chunk far enough to hold the requested word size. If that fails, we
351 UL2(trace, "after allocation: %u chunk(s), current:" METACHUNK_FULL_FORMAT,
352 _chunks.count(), METACHUNK_FULL_FORMAT_ARGS(current_chunk()));
353 UL2(trace, "returning " PTR_FORMAT ".", p2i(p));
354 }
355 return p;
356 }
357
358 // Prematurely returns a metaspace allocation to the _block_freelists
359 // because it is not needed anymore (requires CLD lock to be active).
360 void MetaspaceArena::deallocate_locked(MetaWord* p, size_t word_size) {
361 assert_lock_strong(lock());
362 // At this point a current chunk must exist since we only deallocate if we did allocate before.
363 assert(current_chunk() != NULL, "stray deallocation?");
364 assert(is_valid_area(p, word_size),
365 "Pointer range not part of this Arena and cannot be deallocated: (" PTR_FORMAT ".." PTR_FORMAT ").",
366 p2i(p), p2i(p + word_size));
367
368 UL2(trace, "deallocating " PTR_FORMAT ", word size: " SIZE_FORMAT ".",
369 p2i(p), word_size);
370
371 size_t raw_word_size = get_raw_word_size_for_requested_word_size(word_size);
372 add_allocation_to_fbl(p, raw_word_size);
373
374 DEBUG_ONLY(verify_locked();)
375 }
376
377 // Prematurely returns a metaspace allocation to the _block_freelists because it is not
378 // needed anymore.
379 void MetaspaceArena::deallocate(MetaWord* p, size_t word_size) {
380 MutexLocker cl(lock(), Mutex::_no_safepoint_check_flag);
381 deallocate_locked(p, word_size);
382 }
383
384 // Update statistics. This walks all in-use chunks.
385 void MetaspaceArena::add_to_statistics(ArenaStats* out) const {
386 MutexLocker cl(lock(), Mutex::_no_safepoint_check_flag);
387
388 for (const Metachunk* c = _chunks.first(); c != NULL; c = c->next()) {
389 InUseChunkStats& ucs = out->_stats[c->level()];
390 ucs._num++;
391 ucs._word_size += c->word_size();
465 assert(c->is_valid_committed_pointer(p) ==
466 c->is_valid_committed_pointer(p + word_size - 1), "range intersects");
467 found = c->is_valid_committed_pointer(p);
468 }
469 return found;
470 }
471
472 #endif // ASSERT
473
474 void MetaspaceArena::print_on(outputStream* st) const {
475 MutexLocker fcl(_lock, Mutex::_no_safepoint_check_flag);
476 print_on_locked(st);
477 }
478
479 void MetaspaceArena::print_on_locked(outputStream* st) const {
480 assert_lock_strong(_lock);
481 st->print_cr("sm %s: %d chunks, total word size: " SIZE_FORMAT ", committed word size: " SIZE_FORMAT, _name,
482 _chunks.count(), _chunks.calc_word_size(), _chunks.calc_committed_word_size());
483 _chunks.print_on(st);
484 st->cr();
485 st->print_cr("growth-policy " PTR_FORMAT ", lock " PTR_FORMAT ", cm " PTR_FORMAT ", fbl " PTR_FORMAT,
486 p2i(_growth_policy), p2i(_lock), p2i(_chunk_manager), p2i(_fbl));
487 }
488
489 } // namespace metaspace
490
|
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 #include "precompiled.hpp"
27 #include "logging/log.hpp"
28 #include "logging/logStream.hpp"
29 #include "memory/metaspace/chunkManager.hpp"
30 #include "memory/metaspace/counters.hpp"
31 #include "memory/metaspace/freeBlocks.hpp"
32 #include "memory/metaspace/internalStats.hpp"
33 #include "memory/metaspace/metachunk.hpp"
34 #include "memory/metaspace/metaspaceAlignment.hpp"
35 #include "memory/metaspace/metaspaceArena.hpp"
36 #include "memory/metaspace/metaspaceArenaGrowthPolicy.hpp"
37 #include "memory/metaspace/metaspaceCommon.hpp"
38 #include "memory/metaspace/metaspaceSettings.hpp"
39 #include "memory/metaspace/metaspaceStatistics.hpp"
40 #include "memory/metaspace/virtualSpaceList.hpp"
41 #include "runtime/atomic.hpp"
42 #include "runtime/init.hpp"
43 #include "runtime/mutexLocker.hpp"
44 #include "services/memoryService.hpp"
45 #include "utilities/align.hpp"
46 #include "utilities/debug.hpp"
47 #include "utilities/globalDefinitions.hpp"
48
49 namespace metaspace {
50
51 #define LOGFMT "Arena @" PTR_FORMAT " (%s)"
52 #define LOGFMT_ARGS p2i(this), this->_name
53
54 // Returns the level of the next chunk to be added, acc to growth policy.
91 const chunklevel_t max_level = chunklevel::level_fitting_word_size(requested_word_size);
92 const chunklevel_t preferred_level = MIN2(max_level, next_chunk_level());
93
94 Metachunk* c = _chunk_manager->get_chunk(preferred_level, max_level, requested_word_size);
95 if (c == NULL) {
96 return NULL;
97 }
98
99 assert(c->is_in_use(), "Wrong chunk state.");
100 assert(c->free_below_committed_words() >= requested_word_size, "Chunk not committed");
101 return c;
102 }
103
104 void MetaspaceArena::add_allocation_to_fbl(MetaWord* p, size_t word_size) {
105 if (_fbl == NULL) {
106 _fbl = new FreeBlocks(); // Create only on demand
107 }
108 _fbl->add_block(p, word_size);
109 }
110
111 MetaspaceArena::MetaspaceArena(ChunkManager* chunk_manager, const ArenaGrowthPolicy* growth_policy, int alignment_words,
112 Mutex* lock, SizeAtomicCounter* total_used_words_counter,
113 const char* name) :
114 _lock(lock),
115 _chunk_manager(chunk_manager),
116 _growth_policy(growth_policy),
117 _chunks(),
118 _alignment_words(alignment_words),
119 _fbl(NULL),
120 _total_used_words_counter(total_used_words_counter),
121 _name(name)
122 #ifdef ASSERT
123 , _first_fence(NULL)
124 #endif
125
126 {
127 UL(debug, ": born.");
128
129 // Update statistics
130 InternalStats::inc_num_arena_births();
131 }
132
133 MetaspaceArena::~MetaspaceArena() {
134 #ifdef ASSERT
135 verify();
136 if (Settings::use_allocation_guard()) {
137 verify_allocation_guards();
138 }
139 #endif
140
141 MutexLocker fcl(lock(), Mutex::_no_safepoint_check_flag);
142 MemRangeCounter return_counter;
143
144 Metachunk* c = _chunks.first();
145 Metachunk* c2 = NULL;
210 if (next_chunk_level() > c->level()) {
211 return false;
212 }
213
214 bool success = _chunk_manager->attempt_enlarge_chunk(c);
215 assert(success == false || c->free_words() >= requested_word_size, "Sanity");
216 return success;
217 }
218
219 // Allocate memory from Metaspace.
220 // 1) Attempt to allocate from the free block list.
221 // 2) Attempt to allocate from the current chunk.
222 // 3) Attempt to enlarge the current chunk in place if it is too small.
223 // 4) Attempt to get a new chunk and allocate from that chunk.
224 // At any point, if we hit a commit limit, we return NULL.
225 MetaWord* MetaspaceArena::allocate(size_t requested_word_size) {
226 MutexLocker cl(lock(), Mutex::_no_safepoint_check_flag);
227 UL2(trace, "requested " SIZE_FORMAT " words.", requested_word_size);
228
229 MetaWord* p = NULL;
230 const size_t raw_word_size = get_raw_word_size_for_requested_word_size(requested_word_size, _alignment_words);
231
232 // Before bothering the arena proper, attempt to re-use a block from the free blocks list
233 if (_fbl != NULL && !_fbl->is_empty()) {
234 p = _fbl->remove_block(raw_word_size);
235 if (p != NULL) {
236 DEBUG_ONLY(InternalStats::inc_num_allocs_from_deallocated_blocks();)
237 UL2(trace, "taken from fbl (now: %d, " SIZE_FORMAT ").",
238 _fbl->count(), _fbl->total_size());
239 // Note: free blocks in freeblock dictionary still count as "used" as far as statistics go;
240 // therefore we have no need to adjust any usage counters (see epilogue of allocate_inner())
241 // and can just return here.
242 return p;
243 }
244 }
245
246 // Primary allocation
247 p = allocate_inner(requested_word_size);
248
249 #ifdef ASSERT
250 // Fence allocation
254 if (guard != NULL) {
255 // Ignore allocation errors for the fence to keep coding simple. If this
256 // happens (e.g. because right at this time we hit the Metaspace GC threshold)
257 // we miss adding this one fence. Not a big deal. Note that his would
258 // be pretty rare. Chances are much higher the primary allocation above
259 // would have already failed).
260 Fence* f = new(guard) Fence(_first_fence);
261 _first_fence = f;
262 }
263 }
264 #endif // ASSERT
265
266 return p;
267 }
268
269 // Allocate from the arena proper, once dictionary allocations and fencing are sorted out.
270 MetaWord* MetaspaceArena::allocate_inner(size_t requested_word_size) {
271
272 assert_lock_strong(lock());
273
274 const size_t raw_word_size = get_raw_word_size_for_requested_word_size(requested_word_size, _alignment_words);
275 MetaWord* p = NULL;
276 bool current_chunk_too_small = false;
277 bool commit_failure = false;
278
279 if (current_chunk() != NULL) {
280
281 // Attempt to satisfy the allocation from the current chunk.
282
283 // If the current chunk is too small to hold the requested size, attempt to enlarge it.
284 // If that fails, retire the chunk.
285 if (current_chunk()->free_words() < raw_word_size) {
286 if (!attempt_enlarge_current_chunk(raw_word_size)) {
287 current_chunk_too_small = true;
288 } else {
289 DEBUG_ONLY(InternalStats::inc_num_chunks_enlarged();)
290 UL(debug, "enlarged chunk.");
291 }
292 }
293
294 // Commit the chunk far enough to hold the requested word size. If that fails, we
354 UL2(trace, "after allocation: %u chunk(s), current:" METACHUNK_FULL_FORMAT,
355 _chunks.count(), METACHUNK_FULL_FORMAT_ARGS(current_chunk()));
356 UL2(trace, "returning " PTR_FORMAT ".", p2i(p));
357 }
358 return p;
359 }
360
361 // Prematurely returns a metaspace allocation to the _block_freelists
362 // because it is not needed anymore (requires CLD lock to be active).
363 void MetaspaceArena::deallocate_locked(MetaWord* p, size_t word_size) {
364 assert_lock_strong(lock());
365 // At this point a current chunk must exist since we only deallocate if we did allocate before.
366 assert(current_chunk() != NULL, "stray deallocation?");
367 assert(is_valid_area(p, word_size),
368 "Pointer range not part of this Arena and cannot be deallocated: (" PTR_FORMAT ".." PTR_FORMAT ").",
369 p2i(p), p2i(p + word_size));
370
371 UL2(trace, "deallocating " PTR_FORMAT ", word size: " SIZE_FORMAT ".",
372 p2i(p), word_size);
373
374 size_t raw_word_size = get_raw_word_size_for_requested_word_size(word_size, _alignment_words);
375 add_allocation_to_fbl(p, raw_word_size);
376
377 DEBUG_ONLY(verify_locked();)
378 }
379
380 // Prematurely returns a metaspace allocation to the _block_freelists because it is not
381 // needed anymore.
382 void MetaspaceArena::deallocate(MetaWord* p, size_t word_size) {
383 MutexLocker cl(lock(), Mutex::_no_safepoint_check_flag);
384 deallocate_locked(p, word_size);
385 }
386
387 // Update statistics. This walks all in-use chunks.
388 void MetaspaceArena::add_to_statistics(ArenaStats* out) const {
389 MutexLocker cl(lock(), Mutex::_no_safepoint_check_flag);
390
391 for (const Metachunk* c = _chunks.first(); c != NULL; c = c->next()) {
392 InUseChunkStats& ucs = out->_stats[c->level()];
393 ucs._num++;
394 ucs._word_size += c->word_size();
468 assert(c->is_valid_committed_pointer(p) ==
469 c->is_valid_committed_pointer(p + word_size - 1), "range intersects");
470 found = c->is_valid_committed_pointer(p);
471 }
472 return found;
473 }
474
475 #endif // ASSERT
476
477 void MetaspaceArena::print_on(outputStream* st) const {
478 MutexLocker fcl(_lock, Mutex::_no_safepoint_check_flag);
479 print_on_locked(st);
480 }
481
482 void MetaspaceArena::print_on_locked(outputStream* st) const {
483 assert_lock_strong(_lock);
484 st->print_cr("sm %s: %d chunks, total word size: " SIZE_FORMAT ", committed word size: " SIZE_FORMAT, _name,
485 _chunks.count(), _chunks.calc_word_size(), _chunks.calc_committed_word_size());
486 _chunks.print_on(st);
487 st->cr();
488 st->print_cr("growth-policy " PTR_FORMAT ", alignment %d, lock " PTR_FORMAT ", cm " PTR_FORMAT ", fbl " PTR_FORMAT,
489 p2i(_growth_policy), _alignment_words * BytesPerWord, p2i(_lock), p2i(_chunk_manager), p2i(_fbl));
490 }
491
492 } // namespace metaspace
493
|