1 /*
   2  * Copyright (c) 2020, 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 #include "precompiled.hpp"
  27 
  28 #include "logging/log.hpp"
  29 #include "logging/logStream.hpp"
  30 #include "memory/metaspace/allocationGuard.hpp"
  31 #include "memory/metaspace/arenaGrowthPolicy.hpp"
  32 #include "memory/metaspace/freeBlocks.hpp"
  33 #include "memory/metaspace/chunkManager.hpp"
  34 #include "memory/metaspace/internStat.hpp"
  35 #include "memory/metaspace/metachunk.hpp"
  36 #include "memory/metaspace/metaspaceArena.hpp"
  37 #include "memory/metaspace/metaspaceCommon.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 "services/memoryService.hpp"
  43 #include "utilities/align.hpp"
  44 #include "utilities/debug.hpp"
  45 #include "utilities/globalDefinitions.hpp"
  46 
  47 namespace metaspace {
  48 
  49 #define LOGFMT         "Arena @" PTR_FORMAT " (%s)"
  50 #define LOGFMT_ARGS    p2i(this), this->_name
  51 
  52 // Given a net allocation word size, return the raw word size we actually allocate.
  53 // Note: externally visible for gtests.
  54 //static
  55 size_t get_raw_allocation_word_size(size_t net_word_size) {
  56 
  57   size_t byte_size = net_word_size * BytesPerWord;
  58 
  59   // Deallocated metablocks are kept in a binlist which limits their minimal
  60   //  size to at least the size of a binlist item (2 words).
  61   byte_size = MAX2(byte_size, FreeBlocks::minimal_word_size * BytesPerWord);
  62 
  63   // Metaspace allocations are aligned to word size.
  64   byte_size = align_up(byte_size, allocation_alignment_bytes);
  65 
  66   // If we guard allocations, we need additional space for a prefix.
  67 #ifdef ASSERT
  68   if (Settings::use_allocation_guard()) {
  69     byte_size += align_up(prefix_size(), allocation_alignment_bytes);
  70   }
  71 #endif
  72 
  73   size_t word_size = byte_size / BytesPerWord;
  74 
  75   assert(word_size * BytesPerWord == byte_size, "Sanity");
  76 
  77   return word_size;
  78 
  79 }
  80 
  81 // Returns the level of the next chunk to be added, acc to growth policy.
  82 chunklevel_t MetaspaceArena::next_chunk_level() const {
  83   const int growth_step = _chunks.count();
  84   return _growth_policy->get_level_at_step(growth_step);
  85 }
  86 
  87 // Given a chunk, add its remaining free committed space to the free block list.
  88 void MetaspaceArena::salvage_chunk(Metachunk* c) {
  89 
  90   if (Settings::handle_deallocations() == false) {
  91     return;
  92   }
  93 
  94   assert_lock_strong(lock());
  95 
  96   // If the chunk is completely empty, just return it to the chunk manager.
  97   if (c->used_words() == 0) {
  98     UL2(trace, "salvage: returning empty chunk " METACHUNK_FORMAT ".", METACHUNK_FORMAT_ARGS(c));
  99     _chunk_manager->return_chunk(c);
 100     return;
 101   }
 102 
 103   size_t remaining_words = c->free_below_committed_words();
 104 
 105   if (remaining_words > FreeBlocks::minimal_word_size) {
 106 
 107     UL2(trace, "salvaging chunk " METACHUNK_FULL_FORMAT ".", METACHUNK_FULL_FORMAT_ARGS(c));
 108 
 109     MetaWord* ptr = c->allocate(remaining_words);
 110     assert(ptr != NULL, "Should have worked");
 111     _total_used_words_counter->increment_by(remaining_words);
 112 
 113     add_allocation_to_fbl(ptr, remaining_words);
 114 
 115     // After this operation: the chunk should have no free committed space left.
 116     assert(c->free_below_committed_words() == 0,
 117            "Salvaging chunk failed (chunk " METACHUNK_FULL_FORMAT ").",
 118            METACHUNK_FULL_FORMAT_ARGS(c));
 119 
 120   }
 121 
 122 }
 123 
 124 // Allocate a new chunk from the underlying chunk manager able to hold at least
 125 // requested word size.
 126 Metachunk* MetaspaceArena::allocate_new_chunk(size_t requested_word_size) {
 127 
 128   assert_lock_strong(lock());
 129 
 130   // Should this ever happen, we need to increase the maximum possible chunk size.
 131   guarantee(requested_word_size <= chunklevel::MAX_CHUNK_WORD_SIZE,
 132             "Requested size too large (" SIZE_FORMAT ") - max allowed size per allocation is " SIZE_FORMAT ".",
 133             requested_word_size, chunklevel::MAX_CHUNK_WORD_SIZE);
 134 
 135   const int growth_step = _chunks.count();
 136   const chunklevel_t max_level = chunklevel::level_fitting_word_size(requested_word_size);
 137   const chunklevel_t preferred_level = MIN2(max_level, next_chunk_level());
 138 
 139   Metachunk* c = _chunk_manager->get_chunk(preferred_level, max_level, requested_word_size);
 140   if (c == NULL) {
 141     return NULL;
 142   }
 143 
 144   assert(c->is_in_use(), "Wrong chunk state.");
 145   assert(c->free_below_committed_words() >= requested_word_size, "Chunk not committed");
 146 
 147   return c;
 148 
 149 }
 150 
 151 void MetaspaceArena::add_allocation_to_fbl(MetaWord* p, size_t word_size) {
 152   assert(Settings::handle_deallocations(), "Sanity");
 153   if (_fbl == NULL) {
 154     _fbl = new FreeBlocks(); // Create only on demand
 155   }
 156   _fbl->add_block(p, word_size);
 157 }
 158 
 159 MetaspaceArena::MetaspaceArena(ChunkManager* chunk_manager,
 160              const ArenaGrowthPolicy* growth_policy,
 161              Mutex* lock,
 162              SizeAtomicCounter* total_used_words_counter,
 163              const char* name)
 164 : _lock(lock),
 165   _chunk_manager(chunk_manager),
 166   _growth_policy(growth_policy),
 167   _chunks(),
 168   _fbl(NULL),
 169   _total_used_words_counter(total_used_words_counter),
 170   _name(name)
 171 {
 172   UL(debug, ": born.");
 173 
 174   // Update statistics
 175   InternalStats::inc_num_arena_births();
 176 }
 177 
 178 MetaspaceArena::~MetaspaceArena() {
 179 
 180   DEBUG_ONLY(verify(true);)
 181 
 182   MutexLocker fcl(lock(), Mutex::_no_safepoint_check_flag);
 183 
 184   MemRangeCounter return_counter;
 185 
 186   Metachunk* c = _chunks.first();
 187   Metachunk* c2 = NULL;
 188 
 189   while(c) {
 190     c2 = c->next();
 191     return_counter.add(c->used_words());
 192     DEBUG_ONLY(c->set_prev(NULL);)
 193     DEBUG_ONLY(c->set_next(NULL);)
 194     UL2(debug, "return chunk: " METACHUNK_FORMAT ".", METACHUNK_FORMAT_ARGS(c));
 195     _chunk_manager->return_chunk(c);
 196     // c may be invalid after return_chunk(c) was called. Don't access anymore.
 197     c = c2;
 198   }
 199 
 200   UL2(info, "returned %d chunks, total capacity " SIZE_FORMAT " words.",
 201       return_counter.count(), return_counter.total_size());
 202 
 203   _total_used_words_counter->decrement_by(return_counter.total_size());
 204 
 205   DEBUG_ONLY(chunk_manager()->verify(true);)
 206 
 207   delete _fbl;
 208 
 209   UL(debug, ": dies.");
 210 
 211   // Update statistics
 212   InternalStats::inc_num_arena_deaths();
 213 
 214 }
 215 
 216 // Attempt to enlarge the current chunk to make it large enough to hold at least
 217 //  requested_word_size additional words.
 218 //
 219 // On success, true is returned, false otherwise.
 220 bool MetaspaceArena::attempt_enlarge_current_chunk(size_t requested_word_size) {
 221 
 222   assert_lock_strong(lock());
 223 
 224   Metachunk* c = current_chunk();
 225   assert(c->free_words() < requested_word_size, "Sanity");
 226 
 227   // Not if chunk enlargment is switched off...
 228   if (Settings::enlarge_chunks_in_place() == false) {
 229     return false;
 230   }
 231 
 232   // ... we also disallow it for very large chunks...
 233   if (c->word_size() > Settings::enlarge_chunks_in_place_max_word_size()) {
 234     return false;
 235   }
 236 
 237   // ... nor if we are already a root chunk ...
 238   if (c->is_root_chunk()) {
 239     return false;
 240   }
 241 
 242   // ... nor if the combined size of chunk content and new content would bring us above the size of a root chunk ...
 243   if ((c->used_words() + requested_word_size) > metaspace::chunklevel::MAX_CHUNK_WORD_SIZE) {
 244     return false;
 245   }
 246 
 247   const chunklevel_t new_level =
 248       chunklevel::level_fitting_word_size(c->used_words() + requested_word_size);
 249   assert(new_level < c->level(), "Sanity");
 250 
 251   // Atm we only enlarge by one level (so, doubling the chunk in size). So, if the requested enlargement
 252   // would require the chunk to more than double in size, we bail. But this covers about 99% of all cases,
 253   // so this is good enough.
 254   if (new_level < c->level() - 1) {
 255     return false;
 256   }
 257 
 258   // This only works if chunk is the leader of its buddy pair (and also if buddy
 259   // is free and unsplit, but that we cannot check outside of metaspace lock).
 260   if (!c->is_leader()) {
 261     return false;
 262   }
 263 
 264   // If the size added to the chunk would be larger than allowed for the next growth step
 265   // dont enlarge.
 266   if (next_chunk_level() > c->level()) {
 267     return false;
 268   }
 269 
 270   bool success = _chunk_manager->attempt_enlarge_chunk(c);
 271 
 272   assert(success == false || c->free_words() >= requested_word_size, "Sanity");
 273 
 274   return success;
 275 
 276 }
 277 
 278 // Allocate memory from Metaspace.
 279 // 1) Attempt to allocate from the free block list.
 280 // 2) Attempt to allocate from the current chunk.
 281 // 3) Attempt to enlarge the current chunk in place if it is too small.
 282 // 4) Attempt to get a new chunk and allocate from that chunk.
 283 // At any point, if we hit a commit limit, we return NULL.
 284 MetaWord* MetaspaceArena::allocate(size_t requested_word_size) {
 285 
 286   MutexLocker cl(lock(), Mutex::_no_safepoint_check_flag);
 287 
 288   UL2(trace, "requested " SIZE_FORMAT " words.", requested_word_size);
 289 
 290   MetaWord* p = NULL;
 291 
 292   const size_t raw_word_size = get_raw_word_size_for_requested_word_size(requested_word_size);
 293 
 294   // 1) Attempt to allocate from the free blocks list
 295   if (Settings::handle_deallocations() && _fbl != NULL && !_fbl->is_empty()) {
 296     p = _fbl->get_block(raw_word_size);
 297     if (p != NULL) {
 298       DEBUG_ONLY(InternalStats::inc_num_allocs_from_deallocated_blocks();)
 299       UL2(trace, "taken from fbl (now: %d, " SIZE_FORMAT ").",
 300           _fbl->count(), _fbl->total_size());
 301       // Note: Space in the freeblock dictionary counts as already used (see retire_current_chunk()) -
 302       // that means that we do not modify any counters and therefore can skip the epilog.
 303       return p;
 304     }
 305   }
 306 
 307   bool current_chunk_too_small = false;
 308   bool commit_failure = false;
 309 
 310   if (current_chunk() != NULL) {
 311 
 312     // 2) Attempt to satisfy the allocation from the current chunk.
 313 
 314     // If the current chunk is too small to hold the requested size, attempt to enlarge it.
 315     // If that fails, retire the chunk.
 316     if (current_chunk()->free_words() < raw_word_size) {
 317       if (!attempt_enlarge_current_chunk(raw_word_size)) {
 318         current_chunk_too_small = true;
 319       } else {
 320         DEBUG_ONLY(InternalStats::inc_num_chunks_enlarged();)
 321         UL(debug, "enlarged chunk.");
 322       }
 323     }
 324 
 325     // Commit the chunk far enough to hold the requested word size. If that fails, we
 326     // hit a limit (either GC threshold or MaxMetaspaceSize). In that case retire the
 327     // chunk.
 328     if (!current_chunk_too_small) {
 329       if (!current_chunk()->ensure_committed_additional(raw_word_size)) {
 330         UL2(info, "commit failure (requested size: " SIZE_FORMAT ")", raw_word_size);
 331         commit_failure = true;
 332       }
 333     }
 334 
 335     // Allocate from the current chunk. This should work now.
 336     if (!current_chunk_too_small && !commit_failure) {
 337       p = current_chunk()->allocate(raw_word_size);
 338       assert(p != NULL, "Allocation from chunk failed.");
 339     }
 340 
 341   }
 342 
 343   if (p == NULL) {
 344 
 345     // If we are here, we either had no current chunk to begin with or it was deemed insufficient.
 346     assert(current_chunk() == NULL ||
 347            current_chunk_too_small || commit_failure, "Sanity");
 348 
 349     Metachunk* new_chunk = allocate_new_chunk(raw_word_size);
 350 
 351     if (new_chunk != NULL) {
 352 
 353       UL2(debug, "allocated new chunk " METACHUNK_FORMAT " for requested word size " SIZE_FORMAT ".",
 354           METACHUNK_FORMAT_ARGS(new_chunk), requested_word_size);
 355 
 356       assert(new_chunk->free_below_committed_words() >= raw_word_size, "Sanity");
 357 
 358       // We have a new chunk. Before making it the current chunk, retire the old one.
 359       if (current_chunk() != NULL) {
 360         salvage_chunk(current_chunk());
 361         DEBUG_ONLY(InternalStats::inc_num_chunks_retired();)
 362       }
 363 
 364       _chunks.add(new_chunk);
 365 
 366       // Now, allocate from that chunk. That should work.
 367       p = current_chunk()->allocate(raw_word_size);
 368       assert(p != NULL, "Allocation from chunk failed.");
 369 
 370     } else {
 371       UL2(info, "failed to allocate new chunk for requested word size " SIZE_FORMAT ".", requested_word_size);
 372     }
 373 
 374   }
 375 
 376 #ifdef ASSERT
 377   // When using allocation guards, establish a prefix.
 378   if (p != NULL && Settings::use_allocation_guard()) {
 379     p = establish_prefix(p, raw_word_size);
 380   }
 381 #endif
 382 
 383   if (p == NULL) {
 384     InternalStats::inc_num_allocs_failed_limit();
 385   } else {
 386     DEBUG_ONLY(InternalStats::inc_num_allocs();)
 387     _total_used_words_counter->increment_by(raw_word_size);
 388   }
 389 
 390   SOMETIMES(verify_locked(true);)
 391 
 392   if (p == NULL) {
 393     UL(info, "allocation failed, returned NULL.");
 394   } else {
 395     UL2(trace, "returned " PTR_FORMAT ".", p2i(p));
 396   }
 397 
 398   return p;
 399 
 400 }
 401 
 402 // Prematurely returns a metaspace allocation to the _block_freelists
 403 // because it is not needed anymore (requires CLD lock to be active).
 404 void MetaspaceArena::deallocate_locked(MetaWord* p, size_t word_size) {
 405 
 406   if (Settings::handle_deallocations() == false) {
 407     return;
 408   }
 409 
 410   assert_lock_strong(lock());
 411 
 412   // At this point a current chunk must exist since we only deallocate if we did allocate before.
 413   assert(current_chunk() != NULL, "stray deallocation?");
 414 
 415   assert(is_valid_area(p, word_size),
 416          "Pointer range not part of this Arena and cannot be deallocated: (" PTR_FORMAT ".." PTR_FORMAT ").",
 417          p2i(p), p2i(p + word_size));
 418 
 419   UL2(trace, "deallocating " PTR_FORMAT ", word size: " SIZE_FORMAT ".",
 420       p2i(p), word_size);
 421 
 422   size_t raw_word_size = get_raw_word_size_for_requested_word_size(word_size);
 423   add_allocation_to_fbl(p, raw_word_size);
 424 
 425   DEBUG_ONLY(verify_locked(false);)
 426 
 427 }
 428 
 429 // Prematurely returns a metaspace allocation to the _block_freelists because it is not
 430 // needed anymore.
 431 void MetaspaceArena::deallocate(MetaWord* p, size_t word_size) {
 432   MutexLocker cl(lock(), Mutex::_no_safepoint_check_flag);
 433   deallocate_locked(p, word_size);
 434 }
 435 
 436 // Update statistics. This walks all in-use chunks.
 437 void MetaspaceArena::add_to_statistics(arena_stats_t* out) const {
 438 
 439   MutexLocker cl(lock(), Mutex::_no_safepoint_check_flag);
 440 
 441   for (const Metachunk* c = _chunks.first(); c != NULL; c = c->next()) {
 442     in_use_chunk_stats_t& ucs = out->stats[c->level()];
 443     ucs.num ++;
 444     ucs.word_size += c->word_size();
 445     ucs.committed_words += c->committed_words();
 446     ucs.used_words += c->used_words();
 447     // Note: for free and waste, we only count what's committed.
 448     if (c == current_chunk()) {
 449       ucs.free_words += c->free_below_committed_words();
 450     } else {
 451       ucs.waste_words += c->free_below_committed_words();
 452     }
 453   }
 454 
 455   if (_fbl != NULL) {
 456     out->free_blocks_num += _fbl->count();
 457     out->free_blocks_word_size += _fbl->total_size();
 458   }
 459 
 460   SOMETIMES(out->verify();)
 461 
 462 }
 463 
 464 // Convenience method to get the most important usage statistics.
 465 // For deeper analysis use add_to_statistics().
 466 void MetaspaceArena::usage_numbers(size_t* p_used_words, size_t* p_committed_words, size_t* p_capacity_words) const {
 467   MutexLocker cl(lock(), Mutex::_no_safepoint_check_flag);
 468   size_t used = 0, comm = 0, cap = 0;
 469   for (const Metachunk* c = _chunks.first(); c != NULL; c = c->next()) {
 470     used += c->used_words();
 471     comm += c->committed_words();
 472     cap += c->word_size();
 473   }
 474   if (p_used_words != NULL) {
 475     *p_used_words = used;
 476   }
 477   if (p_committed_words != NULL) {
 478     *p_committed_words = comm;
 479   }
 480   if (p_capacity_words != NULL) {
 481     *p_capacity_words = cap;
 482   }
 483 }
 484 
 485 
 486 #ifdef ASSERT
 487 
 488 void MetaspaceArena::verify_locked(bool slow) const {
 489 
 490   assert_lock_strong(lock());
 491 
 492   assert(_growth_policy != NULL && _chunk_manager != NULL, "Sanity");
 493 
 494   _chunks.verify();
 495 
 496   if (_fbl != NULL) {
 497     _fbl->verify();
 498   }
 499 
 500   // In slow mode, verify guard zones of all allocations
 501   if (slow && Settings::use_allocation_guard()) {
 502     for (const Metachunk* c = _chunks.first(); c != NULL; c = c->next()) {
 503       const MetaWord* p = c->base();
 504       while (p < c->top()) {
 505         const prefix_t* pp = (const prefix_t*)p;
 506         check_prefix(pp);
 507         p += pp->word_size;
 508       }
 509     }
 510   }
 511 
 512 }
 513 
 514 void MetaspaceArena::verify(bool slow) const {
 515 
 516   MutexLocker cl(lock(), Mutex::_no_safepoint_check_flag);
 517   verify_locked(slow);
 518 
 519 }
 520 
 521 // Returns true if the area indicated by pointer and size have actually been allocated
 522 // from this arena.
 523 bool MetaspaceArena::is_valid_area(MetaWord* p, size_t word_size) const {
 524   assert(p != NULL && word_size > 0, "Sanity");
 525   bool found = false;
 526   if (!found) {
 527     for (const Metachunk* c = _chunks.first(); c != NULL && !found; c = c->next()) {
 528       assert(c->is_valid_committed_pointer(p) ==
 529              c->is_valid_committed_pointer(p + word_size - 1), "range intersects");
 530       found = c->is_valid_committed_pointer(p);
 531     }
 532   }
 533   return found;
 534 }
 535 
 536 #endif // ASSERT
 537 
 538 void MetaspaceArena::print_on(outputStream* st) const {
 539   MutexLocker fcl(_lock, Mutex::_no_safepoint_check_flag);
 540   print_on_locked(st);
 541 }
 542 
 543 void MetaspaceArena::print_on_locked(outputStream* st) const {
 544   assert_lock_strong(_lock);
 545   st->print_cr("sm %s: %d chunks, total word size: " SIZE_FORMAT ", committed word size: " SIZE_FORMAT, _name,
 546                _chunks.count(), _chunks.calc_word_size(), _chunks.calc_committed_word_size());
 547   _chunks.print_on(st);
 548   st->cr();
 549   st->print_cr("growth-policy " PTR_FORMAT ", lock " PTR_FORMAT ", cm " PTR_FORMAT ", fbl " PTR_FORMAT,
 550                 p2i(_growth_policy), p2i(_lock), p2i(_chunk_manager), p2i(_fbl));
 551 }
 552 
 553 
 554 
 555 } // namespace metaspace
 556