src/hotspot/share/memory/metaspace/spaceManager.cpp
branchstuefe-new-metaspace-branch
changeset 59155 b537e6386306
parent 59107 245a39d9e24d
equal deleted inserted replaced
59138:714474295e0a 59155:b537e6386306
    24  */
    24  */
    25 #include "precompiled.hpp"
    25 #include "precompiled.hpp"
    26 
    26 
    27 #include "logging/log.hpp"
    27 #include "logging/log.hpp"
    28 #include "logging/logStream.hpp"
    28 #include "logging/logStream.hpp"
       
    29 #include "memory/metaspace/blockFreelist.hpp"
    29 #include "memory/metaspace/chunkManager.hpp"
    30 #include "memory/metaspace/chunkManager.hpp"
    30 #include "memory/metaspace/internStat.hpp"
    31 #include "memory/metaspace/internStat.hpp"
       
    32 #include "memory/metaspace/leftOverBins.inline.hpp"
    31 #include "memory/metaspace/metachunk.hpp"
    33 #include "memory/metaspace/metachunk.hpp"
    32 #include "memory/metaspace/metaDebug.hpp"
    34 #include "memory/metaspace/metaDebug.hpp"
    33 #include "memory/metaspace/metaspaceCommon.hpp"
    35 #include "memory/metaspace/metaspaceCommon.hpp"
    34 #include "memory/metaspace/metaspaceStatistics.hpp"
    36 #include "memory/metaspace/metaspaceStatistics.hpp"
    35 #include "memory/metaspace/smallBlocks.hpp"
    37 #include "memory/metaspace/smallBlocks.hpp"
   155     _block_freelist = new BlockFreelist(); // Create only on demand
   157     _block_freelist = new BlockFreelist(); // Create only on demand
   156   }
   158   }
   157   _block_freelist->return_block(p, word_size);
   159   _block_freelist->return_block(p, word_size);
   158 }
   160 }
   159 
   161 
       
   162 
       
   163 void SpaceManager::create_lom() {
       
   164   assert(_lom == NULL, "Only call once");
       
   165   _lom = new LeftOverManager();
       
   166 }
       
   167 
       
   168 void SpaceManager::add_allocation_to_lom(MetaWord* p, size_t word_size) {
       
   169   if (_lom == NULL) {
       
   170     _lom = new LeftOverManager(); // Create only on demand
       
   171   }
       
   172   _lom->add_block(p, word_size);
       
   173 }
       
   174 
   160 SpaceManager::SpaceManager(ChunkManager* chunk_manager,
   175 SpaceManager::SpaceManager(ChunkManager* chunk_manager,
   161              const ChunkAllocSequence* alloc_sequence,
   176              const ChunkAllocSequence* alloc_sequence,
   162              Mutex* lock,
   177              Mutex* lock,
   163              SizeAtomicCounter* total_used_words_counter,
   178              SizeAtomicCounter* total_used_words_counter,
   164              const char* name,
   179              const char* name,
   165              bool is_micro_loader)
   180              bool is_micro_loader)
   166 : _lock(lock),
   181 : _lock(lock),
   167   _chunk_manager(chunk_manager),
   182   _chunk_manager(chunk_manager),
   168   _chunk_alloc_sequence(alloc_sequence),
   183   _chunk_alloc_sequence(alloc_sequence),
   169   _chunks(),
   184   _chunks(),
   170   _block_freelist(NULL),
   185   _block_freelist(NULL), _lom(NULL),
   171   _total_used_words_counter(total_used_words_counter),
   186   _total_used_words_counter(total_used_words_counter),
   172   _name(name),
   187   _name(name),
   173   _is_micro_loader(is_micro_loader)
   188   _is_micro_loader(is_micro_loader)
   174 {
   189 {
   175 }
   190 }
   189   }
   204   }
   190 
   205 
   191   DEBUG_ONLY(chunk_manager()->verify(true);)
   206   DEBUG_ONLY(chunk_manager()->verify(true);)
   192 
   207 
   193   delete _block_freelist;
   208   delete _block_freelist;
       
   209   delete _lom;
   194 
   210 
   195 }
   211 }
   196 
   212 
   197 // The remaining committed free space in the current chunk is chopped up and stored in the block
   213 // The remaining committed free space in the current chunk is chopped up and stored in the block
   198 // free list for later use. As a result, the current chunk will remain current but completely
   214 // free list for later use. As a result, the current chunk will remain current but completely
   228                          LOGFMT_SPCMGR_ARGS, p2i(this), METACHUNK_FULL_FORMAT_ARGS(c));
   244                          LOGFMT_SPCMGR_ARGS, p2i(this), METACHUNK_FULL_FORMAT_ARGS(c));
   229 
   245 
   230     bool did_hit_limit = false;
   246     bool did_hit_limit = false;
   231     MetaWord* ptr = c->allocate(net_remaining_words, &did_hit_limit);
   247     MetaWord* ptr = c->allocate(net_remaining_words, &did_hit_limit);
   232     assert(ptr != NULL && did_hit_limit == false, "Should have worked");
   248     assert(ptr != NULL && did_hit_limit == false, "Should have worked");
   233     add_allocation_to_block_freelist(ptr, net_remaining_words);
   249 
       
   250     if (Settings::use_lom()) {
       
   251       add_allocation_to_lom(ptr, net_remaining_words);
       
   252     } else {
       
   253       add_allocation_to_block_freelist(ptr, net_remaining_words);
       
   254     }
       
   255 
   234     _total_used_words_counter->increment_by(net_remaining_words);
   256     _total_used_words_counter->increment_by(net_remaining_words);
   235 
   257 
   236     // After this operation: the current chunk should have (almost) no free committed space left.
   258     // After this operation: the current chunk should have (almost) no free committed space left.
   237     assert(current_chunk()->free_below_committed_words() <= highest_possible_delta_between_raw_and_net_size,
   259     assert(current_chunk()->free_below_committed_words() <= highest_possible_delta_between_raw_and_net_size,
   238            "Chunk retiring did not work (current chunk " METACHUNK_FULL_FORMAT ").",
   260            "Chunk retiring did not work (current chunk " METACHUNK_FULL_FORMAT ").",
   279   // Allocation from the dictionary is expensive in the sense that
   301   // Allocation from the dictionary is expensive in the sense that
   280   // the dictionary has to be searched for a size.  Don't allocate
   302   // the dictionary has to be searched for a size.  Don't allocate
   281   // from the dictionary until it starts to get fat.  Is this
   303   // from the dictionary until it starts to get fat.  Is this
   282   // a reasonable policy?  Maybe an skinny dictionary is fast enough
   304   // a reasonable policy?  Maybe an skinny dictionary is fast enough
   283   // for allocations.  Do some profiling.  JJJ
   305   // for allocations.  Do some profiling.  JJJ
       
   306   if (Settings::use_lom()) {
       
   307     if (_lom != NULL) {
       
   308       p = _lom->get_block(raw_word_size);
       
   309       if (p != NULL) {
       
   310         DEBUG_ONLY(InternalStats::inc_num_allocs_from_deallocated_blocks();)
       
   311         log_trace(metaspace)(LOGFMT_SPCMGR ": .. taken from freelist.", LOGFMT_SPCMGR_ARGS);
       
   312         // Note: space in the freeblock dictionary counts as used (see retire_current_chunk()) -
       
   313         // that means that we must not increase the used counter again when allocating from the dictionary.
       
   314         // Therefore we return here.
       
   315         return p;
       
   316       }
       
   317     }
       
   318   } else {
   284   if (_block_freelist != NULL && _block_freelist->total_size() > Settings::allocation_from_dictionary_limit()) {
   319   if (_block_freelist != NULL && _block_freelist->total_size() > Settings::allocation_from_dictionary_limit()) {
   285     p = _block_freelist->get_block(raw_word_size);
   320     p = _block_freelist->get_block(raw_word_size);
   286 
   321 
   287     if (p != NULL) {
   322     if (p != NULL) {
   288       DEBUG_ONLY(InternalStats::inc_num_allocs_from_deallocated_blocks();)
   323       DEBUG_ONLY(InternalStats::inc_num_allocs_from_deallocated_blocks();)
   291       // that means that we must not increase the used counter again when allocating from the dictionary.
   326       // that means that we must not increase the used counter again when allocating from the dictionary.
   292       // Therefore we return here.
   327       // Therefore we return here.
   293       return p;
   328       return p;
   294     }
   329     }
   295 
   330 
       
   331   }
   296   }
   332   }
   297 
   333 
   298   // 2) Failing that, attempt to allocate from the current chunk. If we hit commit limit, return NULL.
   334   // 2) Failing that, attempt to allocate from the current chunk. If we hit commit limit, return NULL.
   299   if (p == NULL && !did_hit_limit) {
   335   if (p == NULL && !did_hit_limit) {
   300     p = current_chunk()->allocate(raw_word_size, &did_hit_limit);
   336     p = current_chunk()->allocate(raw_word_size, &did_hit_limit);
   403   if (current_chunk()->attempt_rollback_allocation(p, raw_word_size)) {
   439   if (current_chunk()->attempt_rollback_allocation(p, raw_word_size)) {
   404     log_trace(metaspace)(LOGFMT_SPCMGR ": ... rollback succeeded.", LOGFMT_SPCMGR_ARGS);
   440     log_trace(metaspace)(LOGFMT_SPCMGR ": ... rollback succeeded.", LOGFMT_SPCMGR_ARGS);
   405     return;
   441     return;
   406   }
   442   }
   407 
   443 
   408   add_allocation_to_block_freelist(p, raw_word_size);
   444   if (Settings::use_lom()) {
       
   445     add_allocation_to_lom(p, raw_word_size);
       
   446   } else {
       
   447     add_allocation_to_block_freelist(p, raw_word_size);
       
   448   }
   409 
   449 
   410   DEBUG_ONLY(verify_locked();)
   450   DEBUG_ONLY(verify_locked();)
   411 
   451 
   412 }
   452 }
   413 
   453 
   435     } else {
   475     } else {
   436       ucs.waste_words += c->free_below_committed_words();
   476       ucs.waste_words += c->free_below_committed_words();
   437     }
   477     }
   438   }
   478   }
   439 
   479 
   440   if (block_freelist() != NULL) {
   480   if (Settings::use_lom()) {
   441     out->free_blocks_num += block_freelist()->num_blocks();
   481     if (lom() != NULL) {
   442     out->free_blocks_word_size += block_freelist()->total_size();
   482       block_stats_t s;
       
   483       lom()->statistics(&s);
       
   484       out->free_blocks_num += s.num_blocks;
       
   485       out->free_blocks_word_size += s.word_size;
       
   486     }
       
   487   } else {
       
   488     if (block_freelist() != NULL) {
       
   489       out->free_blocks_num += block_freelist()->num_blocks();
       
   490       out->free_blocks_word_size += block_freelist()->total_size();
       
   491     }
   443   }
   492   }
   444 
   493 
   445   SOMETIMES(out->verify();)
   494   SOMETIMES(out->verify();)
   446 
   495 
   447 }
   496 }
   453   assert_lock_strong(lock());
   502   assert_lock_strong(lock());
   454 
   503 
   455   assert(_chunk_alloc_sequence != NULL && _chunk_manager != NULL, "Sanity");
   504   assert(_chunk_alloc_sequence != NULL && _chunk_manager != NULL, "Sanity");
   456 
   505 
   457   _chunks.verify();
   506   _chunks.verify();
       
   507 
       
   508   if (Settings::use_lom()) {
       
   509     if (lom() != NULL) {
       
   510       lom()->verify();
       
   511     }
       
   512   }
   458 
   513 
   459 }
   514 }
   460 
   515 
   461 void SpaceManager::verify() const {
   516 void SpaceManager::verify() const {
   462 
   517