src/hotspot/share/memory/metaspace/spaceManager.cpp
branchstuefe-new-metaspace-branch
changeset 58882 58b20be7bc04
parent 58840 7678903a348f
child 58883 08102295011d
equal deleted inserted replaced
58881:24152dbf6c78 58882:58b20be7bc04
    42 #include "utilities/debug.hpp"
    42 #include "utilities/debug.hpp"
    43 #include "utilities/globalDefinitions.hpp"
    43 #include "utilities/globalDefinitions.hpp"
    44 
    44 
    45 namespace metaspace {
    45 namespace metaspace {
    46 
    46 
       
    47 #define LOGFMT_SPCMGR         "SpcMgr @" PTR_FORMAT " (%s)"
       
    48 #define LOGFMT_SPCMGR_ARGS    p2i(this), this->_name
       
    49 
       
    50 
    47 // Given a net allocation word size, return the raw word size
    51 // Given a net allocation word size, return the raw word size
    48 // we need to actually allocate in order to:
    52 // we need to actually allocate in order to:
    49 // 1) be able to deallocate the allocation - deallocated blocks are stored either in SmallBlocks
    53 // 1) be able to deallocate the allocation - deallocated blocks are stored either in SmallBlocks
    50 //    (an array of short lists) or, beyond a certain size, in a dictionary tree.
    54 //    (an array of short lists) or, beyond a certain size, in a dictionary tree.
    51 //    For that to work the allocated block must be at least three words.
    55 //    For that to work the allocated block must be at least three words.
   106 
   110 
   107   if (pref_level > min_level) {
   111   if (pref_level > min_level) {
   108     pref_level = min_level;
   112     pref_level = min_level;
   109   }
   113   }
   110 
   114 
   111   log_trace(metaspace)("SpaceManager %s: requested word size_ " SIZE_FORMAT ", num chunks so far: %d, preferred level: "
   115   log_trace(metaspace)(LOGFMT_SPCMGR ": requested word size_ " SIZE_FORMAT ", num chunks so far: %d, preferred level: "
   112                        CHKLVL_FORMAT ", min level: " CHKLVL_FORMAT ".",
   116                        CHKLVL_FORMAT ", min level: " CHKLVL_FORMAT ".",
   113                        _name, requested_word_size, _chunks.size(), pref_level, min_level);
   117                        LOGFMT_SPCMGR_ARGS, requested_word_size, _chunks.size(), pref_level, min_level);
   114 
   118 
   115   Metachunk* c = _chunk_manager->get_chunk(min_level, pref_level);
   119   Metachunk* c = _chunk_manager->get_chunk(min_level, pref_level);
   116   if (c == NULL) {
   120   if (c == NULL) {
   117     log_debug(metaspace)("SpaceManager %s: failed to allocate new chunk for requested word size " SIZE_FORMAT ".",
   121     log_debug(metaspace)(LOGFMT_SPCMGR ": failed to allocate new chunk for requested word size " SIZE_FORMAT ".",
   118                          _name, requested_word_size);
   122                          LOGFMT_SPCMGR_ARGS, requested_word_size);
   119     return false;
   123     return false;
   120   }
   124   }
   121 
   125 
   122   assert(c->is_in_use(), "Wrong chunk state.");
   126   assert(c->is_in_use(), "Wrong chunk state.");
   123   assert(c->level() <= min_level && c->level() >= pref_level, "Sanity");
   127   assert(c->level() <= min_level && c->level() >= pref_level, "Sanity");
   124 
   128 
   125   _chunks.add(c);
   129   _chunks.add(c);
   126 
   130 
   127   log_debug(metaspace)("SpaceManager %s: allocated new chunk " METACHUNK_FORMAT " for requested word size " SIZE_FORMAT ".",
   131   log_debug(metaspace)(LOGFMT_SPCMGR ": allocated new chunk " METACHUNK_FORMAT " for requested word size " SIZE_FORMAT ".",
   128                        _name, METACHUNK_FORMAT_ARGS(c), requested_word_size);
   132                        LOGFMT_SPCMGR_ARGS, METACHUNK_FORMAT_ARGS(c), requested_word_size);
   129 
   133 
   130   // Workaround for JDK-8233019: never return space allocated at a 32bit aligned address
   134   // Workaround for JDK-8233019: never return space allocated at a 32bit aligned address
   131   if (Settings::do_not_return_32bit_aligned_addresses() &&
   135   if (Settings::do_not_return_32bit_aligned_addresses() &&
   132       (((intptr_t)c->base()) & 0xFFFFFFFF) == 0)
   136       (((intptr_t)c->base()) & 0xFFFFFFFF) == 0)
   133   {
   137   {
   193   assert_lock_strong(lock());
   197   assert_lock_strong(lock());
   194 
   198 
   195   Metachunk* c = current_chunk();
   199   Metachunk* c = current_chunk();
   196   assert(c != NULL, "Sanity");
   200   assert(c != NULL, "Sanity");
   197 
   201 
   198   log_debug(metaspace)("SpaceManager %s: retiring chunk " METACHUNK_FULL_FORMAT ".",
       
   199                        _name, METACHUNK_FULL_FORMAT_ARGS(c));
       
   200 
       
   201   // Side note:
   202   // Side note:
   202   // In theory it could happen that we are asked to retire a completely empty chunk. This may be the
   203   // In theory it could happen that we are asked to retire a completely empty chunk. This may be the
   203   // result of rolled back allocations (see deallocate in place) and a lot of luck.
   204   // result of rolled back allocations (see deallocate in place) and a lot of luck.
   204   // But since these cases should be exceedingly rare, we do not handle them special in order to keep
   205   // But since these cases should be exceedingly rare, we do not handle them special in order to keep
   205   // the code simple.
   206   // the code simple.
   206 
   207 
   207   size_t raw_remaining_words = c->free_below_committed_words();
   208   size_t raw_remaining_words = c->free_below_committed_words();
   208   size_t net_remaining_words = get_net_allocation_word_size(raw_remaining_words);
   209   size_t net_remaining_words = get_net_allocation_word_size(raw_remaining_words);
   209   if (net_remaining_words > 0) {
   210   if (net_remaining_words > 0) {
       
   211 
       
   212     log_debug(metaspace)(LOGFMT_SPCMGR " @" PTR_FORMAT " : retiring chunk " METACHUNK_FULL_FORMAT ".",
       
   213                          LOGFMT_SPCMGR_ARGS, p2i(this), METACHUNK_FULL_FORMAT_ARGS(c));
       
   214 
   210     bool did_hit_limit = false;
   215     bool did_hit_limit = false;
   211     MetaWord* ptr = c->allocate(net_remaining_words, &did_hit_limit);
   216     MetaWord* ptr = c->allocate(net_remaining_words, &did_hit_limit);
   212     assert(ptr != NULL && did_hit_limit == false, "Should have worked");
   217     assert(ptr != NULL && did_hit_limit == false, "Should have worked");
   213     add_allocation_to_block_freelist(ptr, net_remaining_words);
   218     add_allocation_to_block_freelist(ptr, net_remaining_words);
   214     _total_used_words_counter->increment_by(net_remaining_words);
   219     _total_used_words_counter->increment_by(net_remaining_words);
   215   }
   220 
   216 
   221     // After this operation: the current chunk should have (almost) no free committed space left.
   217   // After this operation: the current chunk should have (almost) no free committed space left.
   222     assert(current_chunk()->free_below_committed_words() <= highest_possible_delta_between_raw_and_net_size,
   218   assert(current_chunk()->free_below_committed_words() <= highest_possible_delta_between_raw_and_net_size,
   223            "Chunk retiring did not work (current chunk " METACHUNK_FULL_FORMAT ").",
   219          "Chunk retiring did not work (current chunk " METACHUNK_FULL_FORMAT ").",
   224            METACHUNK_FULL_FORMAT_ARGS(current_chunk()));
   220          METACHUNK_FULL_FORMAT_ARGS(current_chunk()));
   225 
   221 
   226     DEBUG_ONLY(verify_locked();)
   222   DEBUG_ONLY(verify_locked();)
   227 
       
   228   }
   223 
   229 
   224 }
   230 }
   225 
   231 
   226 // Allocate memory from Metaspace.
   232 // Allocate memory from Metaspace.
   227 // 1) Attempt to allocate from the dictionary of deallocated blocks.
   233 // 1) Attempt to allocate from the dictionary of deallocated blocks.
   233 
   239 
   234   MutexLocker cl(lock(), Mutex::_no_safepoint_check_flag);
   240   MutexLocker cl(lock(), Mutex::_no_safepoint_check_flag);
   235 
   241 
   236   const size_t raw_word_size = get_raw_allocation_word_size(requested_word_size);
   242   const size_t raw_word_size = get_raw_allocation_word_size(requested_word_size);
   237 
   243 
   238   log_trace(metaspace)("SpaceManager %s: requested " SIZE_FORMAT " words, "
   244   log_debug(metaspace)(LOGFMT_SPCMGR ": requested " SIZE_FORMAT " words, "
   239                        "raw word size: " SIZE_FORMAT ".",
   245                        "raw word size: " SIZE_FORMAT ".",
   240                        _name, requested_word_size, raw_word_size);
   246                        LOGFMT_SPCMGR_ARGS, requested_word_size, raw_word_size);
   241 
   247 
   242   MetaWord* p = NULL;
   248   MetaWord* p = NULL;
   243 
   249 
   244   bool did_hit_limit = false;
   250   bool did_hit_limit = false;
   245 
   251 
   262   if (_block_freelist != NULL && _block_freelist->total_size() > Settings::allocation_from_dictionary_limit()) {
   268   if (_block_freelist != NULL && _block_freelist->total_size() > Settings::allocation_from_dictionary_limit()) {
   263     p = _block_freelist->get_block(raw_word_size);
   269     p = _block_freelist->get_block(raw_word_size);
   264 
   270 
   265     if (p != NULL) {
   271     if (p != NULL) {
   266       DEBUG_ONLY(InternalStats::inc_num_allocs_from_deallocated_blocks();)
   272       DEBUG_ONLY(InternalStats::inc_num_allocs_from_deallocated_blocks();)
   267       log_trace(metaspace)("SpaceManager %s: .. taken from freelist.", _name);
   273       log_trace(metaspace)(LOGFMT_SPCMGR ": .. taken from freelist.", LOGFMT_SPCMGR_ARGS);
   268       // Note: space in the freeblock dictionary counts as used (see retire_current_chunk()) -
   274       // Note: space in the freeblock dictionary counts as used (see retire_current_chunk()) -
   269       // that means that we must not increase the used counter again when allocating from the dictionary.
   275       // that means that we must not increase the used counter again when allocating from the dictionary.
   270       // Therefore we return here.
   276       // Therefore we return here.
   271       return p;
   277       return p;
   272     }
   278     }
   274   }
   280   }
   275 
   281 
   276   // 2) Failing that, attempt to allocate from the current chunk. If we hit commit limit, return NULL.
   282   // 2) Failing that, attempt to allocate from the current chunk. If we hit commit limit, return NULL.
   277   if (p == NULL && !did_hit_limit) {
   283   if (p == NULL && !did_hit_limit) {
   278     p = current_chunk()->allocate(raw_word_size, &did_hit_limit);
   284     p = current_chunk()->allocate(raw_word_size, &did_hit_limit);
   279     log_trace(metaspace)("SpaceManager %s: .. taken from current chunk.", _name);
   285     log_trace(metaspace)(LOGFMT_SPCMGR ": .. taken from current chunk.", LOGFMT_SPCMGR_ARGS);
   280   }
   286   }
   281 
   287 
   282   // 3) Failing that because the remaining chunk space is too small for the requested size
   288   // 3) Failing that because the remaining chunk space is too small for the requested size
   283   //     (and not because commit limit), attempt to enlarge the chunk in place.
   289   //     (and not because commit limit), attempt to enlarge the chunk in place.
   284   if (p == NULL && !did_hit_limit) {
   290   if (p == NULL && !did_hit_limit) {
   309         // Re-attempt allocation.
   315         // Re-attempt allocation.
   310         p = current_chunk()->allocate(raw_word_size, &did_hit_limit);
   316         p = current_chunk()->allocate(raw_word_size, &did_hit_limit);
   311 
   317 
   312         if (p != NULL) {
   318         if (p != NULL) {
   313           DEBUG_ONLY(InternalStats::inc_num_chunk_enlarged();)
   319           DEBUG_ONLY(InternalStats::inc_num_chunk_enlarged();)
   314           log_trace(metaspace)("SpaceManager %s: .. taken from current chunk (enlarged chunk).", _name);
   320           log_trace(metaspace)(LOGFMT_SPCMGR ": .. taken from current chunk (enlarged chunk).", LOGFMT_SPCMGR_ARGS);
   315         }
   321         }
   316       }
   322       }
   317     }
   323     }
   318   }
   324   }
   319 
   325 
   334     if (allocate_new_current_chunk(raw_word_size) == false) {
   340     if (allocate_new_current_chunk(raw_word_size) == false) {
   335       did_hit_limit = true;
   341       did_hit_limit = true;
   336     } else {
   342     } else {
   337       assert(current_chunk() != NULL && current_chunk()->free_words() >= raw_word_size, "Sanity");
   343       assert(current_chunk() != NULL && current_chunk()->free_words() >= raw_word_size, "Sanity");
   338       p = current_chunk()->allocate(raw_word_size, &did_hit_limit);
   344       p = current_chunk()->allocate(raw_word_size, &did_hit_limit);
   339       log_trace(metaspace)("SpaceManager %s: .. allocated new chunk " CHKLVL_FORMAT " and taken from that.",
   345       log_trace(metaspace)(LOGFMT_SPCMGR ": .. allocated new chunk " CHKLVL_FORMAT " and taken from that.",
   340                            _name, current_chunk()->level());
   346                            LOGFMT_SPCMGR_ARGS, current_chunk()->level());
   341     }
   347     }
   342 
   348 
   343   }
   349   }
   344 
   350 
   345   assert(p != NULL || (p == NULL && did_hit_limit), "Sanity");
   351   assert(p != NULL || (p == NULL && did_hit_limit), "Sanity");
   351   } else {
   357   } else {
   352     DEBUG_ONLY(InternalStats::inc_num_allocs();)
   358     DEBUG_ONLY(InternalStats::inc_num_allocs();)
   353     _total_used_words_counter->increment_by(raw_word_size);
   359     _total_used_words_counter->increment_by(raw_word_size);
   354   }
   360   }
   355 
   361 
   356   log_trace(metaspace)("SpaceManager %s: returned " PTR_FORMAT ".",
   362   log_trace(metaspace)(LOGFMT_SPCMGR ": returned " PTR_FORMAT ".",
   357                        _name, p2i(p));
   363                        LOGFMT_SPCMGR_ARGS, p2i(p));
   358 
   364 
   359   return p;
   365   return p;
   360 
   366 
   361 }
   367 }
   362 
   368 
   366   assert_lock_strong(lock());
   372   assert_lock_strong(lock());
   367 
   373 
   368   // Allocations and deallocations are in raw_word_size
   374   // Allocations and deallocations are in raw_word_size
   369   size_t raw_word_size = get_raw_allocation_word_size(word_size);
   375   size_t raw_word_size = get_raw_allocation_word_size(word_size);
   370 
   376 
   371   log_debug(metaspace)("SpaceManager %s: deallocating " PTR_FORMAT
   377   log_debug(metaspace)(LOGFMT_SPCMGR ": deallocating " PTR_FORMAT
   372                        ", word size: " SIZE_FORMAT ", raw size: " SIZE_FORMAT ".",
   378                        ", word size: " SIZE_FORMAT ", raw size: " SIZE_FORMAT ".",
   373                        _name, p2i(p), word_size, raw_word_size);
   379                        LOGFMT_SPCMGR_ARGS, p2i(p), word_size, raw_word_size);
   374 
   380 
   375   assert(current_chunk() != NULL, "SpaceManager is empty.");
   381   assert(current_chunk() != NULL, "SpaceManager is empty.");
   376 
   382 
   377   assert(is_valid_area(p, word_size),
   383   assert(is_valid_area(p, word_size),
   378          "Pointer range not part of this SpaceManager and cannot be deallocated: (" PTR_FORMAT ".." PTR_FORMAT ").",
   384          "Pointer range not part of this SpaceManager and cannot be deallocated: (" PTR_FORMAT ".." PTR_FORMAT ").",
   379          p2i(p), p2i(p + word_size));
   385          p2i(p), p2i(p + word_size));
   380 
   386 
   381   // If this allocation has just been allocated from the current chunk, it may still be on the top of the
   387   // If this allocation has just been allocated from the current chunk, it may still be on the top of the
   382   // current chunk. In that case, just roll back the allocation.
   388   // current chunk. In that case, just roll back the allocation.
   383   if (current_chunk()->attempt_rollback_allocation(p, raw_word_size)) {
   389   if (current_chunk()->attempt_rollback_allocation(p, raw_word_size)) {
   384     log_trace(metaspace)("SpaceManager %s: ... rollback succeeded.", _name);
   390     log_trace(metaspace)(LOGFMT_SPCMGR ": ... rollback succeeded.", LOGFMT_SPCMGR_ARGS);
   385     return;
   391     return;
   386   }
   392   }
   387 
   393 
   388   add_allocation_to_block_freelist(p, raw_word_size);
   394   add_allocation_to_block_freelist(p, raw_word_size);
   389 
   395