hotspot/src/share/vm/memory/metaspace.cpp
changeset 14635 6a3c85b8111c
parent 14590 7d6b69f12b36
child 14842 4cdc5a61a7c2
equal deleted inserted replaced
14634:fdd9909928ae 14635:6a3c85b8111c
    50 
    50 
    51 // Parameters for stress mode testing
    51 // Parameters for stress mode testing
    52 const uint metadata_deallocate_a_lot_block = 10;
    52 const uint metadata_deallocate_a_lot_block = 10;
    53 const uint metadata_deallocate_a_lock_chunk = 3;
    53 const uint metadata_deallocate_a_lock_chunk = 3;
    54 size_t const allocation_from_dictionary_limit = 64 * K;
    54 size_t const allocation_from_dictionary_limit = 64 * K;
    55 const size_t metadata_chunk_initialize = 0xf7f7f7f7;
       
    56 const size_t metadata_deallocate = 0xf5f5f5f5;
    55 const size_t metadata_deallocate = 0xf5f5f5f5;
    57 
    56 
    58 MetaWord* last_allocated = 0;
    57 MetaWord* last_allocated = 0;
    59 
    58 
    60 // Used in declarations in SpaceManager and ChunkManager
    59 // Used in declarations in SpaceManager and ChunkManager
    90 // Each SpaceManager maintains a
    89 // Each SpaceManager maintains a
    91 // list of the chunks it is using and the current chunk.  The current
    90 // list of the chunks it is using and the current chunk.  The current
    92 // chunk is the chunk from which allocations are done.  Space freed in
    91 // chunk is the chunk from which allocations are done.  Space freed in
    93 // a chunk is placed on the free list of blocks (BlockFreelist) and
    92 // a chunk is placed on the free list of blocks (BlockFreelist) and
    94 // reused from there.
    93 // reused from there.
    95 //
       
    96 // Future modification
       
    97 //
       
    98 // The Metachunk can conceivable be replaced by the Chunk in
       
    99 // allocation.hpp.  Note that the latter Chunk is the space for
       
   100 // allocation (allocations from the chunk are out of the space in
       
   101 // the Chunk after the header for the Chunk) where as Metachunks
       
   102 // point to space in a VirtualSpace.  To replace Metachunks with
       
   103 // Chunks, change Chunks so that they can be allocated out of a VirtualSpace.
       
   104 size_t Metablock::_min_block_byte_size = sizeof(Metablock);
       
   105 #ifdef ASSERT
       
   106   size_t Metablock::_overhead =
       
   107     Chunk::aligned_overhead_size(sizeof(Metablock)) / BytesPerWord;
       
   108 #else
       
   109   size_t Metablock::_overhead = 0;
       
   110 #endif
       
   111 
    94 
   112 // Pointer to list of Metachunks.
    95 // Pointer to list of Metachunks.
   113 class ChunkList VALUE_OBJ_CLASS_SPEC {
    96 class ChunkList VALUE_OBJ_CLASS_SPEC {
   114   // List of free chunks
    97   // List of free chunks
   115   Metachunk* _head;
    98   Metachunk* _head;
   621   void dump(outputStream* const out) const;
   604   void dump(outputStream* const out) const;
   622   void print_on(outputStream* st) const;
   605   void print_on(outputStream* st) const;
   623   void locked_print_chunks_in_use_on(outputStream* st) const;
   606   void locked_print_chunks_in_use_on(outputStream* st) const;
   624 
   607 
   625   void verify();
   608   void verify();
       
   609   void verify_chunk_size(Metachunk* chunk);
   626   NOT_PRODUCT(void mangle_freed_chunks();)
   610   NOT_PRODUCT(void mangle_freed_chunks();)
   627 #ifdef ASSERT
   611 #ifdef ASSERT
   628   void verify_allocation_total();
   612   void verify_allocation_total();
   629 #endif
   613 #endif
   630 };
   614 };
   631 
   615 
   632 uint const SpaceManager::_small_chunk_limit = 4;
   616 uint const SpaceManager::_small_chunk_limit = 4;
   633 
       
   634 
       
   635 
   617 
   636 const char* SpaceManager::_expand_lock_name =
   618 const char* SpaceManager::_expand_lock_name =
   637   "SpaceManager chunk allocation lock";
   619   "SpaceManager chunk allocation lock";
   638 const int SpaceManager::_expand_lock_rank = Monitor::leaf - 1;
   620 const int SpaceManager::_expand_lock_rank = Monitor::leaf - 1;
   639 Mutex* const SpaceManager::_expand_lock =
   621 Mutex* const SpaceManager::_expand_lock =
   640   new Mutex(SpaceManager::_expand_lock_rank,
   622   new Mutex(SpaceManager::_expand_lock_rank,
   641             SpaceManager::_expand_lock_name,
   623             SpaceManager::_expand_lock_name,
   642             Mutex::_allow_vm_block_flag);
   624             Mutex::_allow_vm_block_flag);
   643 
       
   644 size_t Metachunk::_overhead =
       
   645   Chunk::aligned_overhead_size(sizeof(Metachunk)) / BytesPerWord;
       
   646 
       
   647 // New blocks returned by the Metaspace are zero initialized.
       
   648 // We should fix the constructors to not assume this instead.
       
   649 Metablock* Metablock::initialize(MetaWord* p, size_t word_size) {
       
   650   if (p == NULL) {
       
   651     return NULL;
       
   652   }
       
   653 
       
   654   Metablock* result = (Metablock*) p;
       
   655 
       
   656   // Clear the memory
       
   657   Copy::fill_to_aligned_words((HeapWord*)result, word_size);
       
   658 #ifdef ASSERT
       
   659   result->set_word_size(word_size);
       
   660 #endif
       
   661   return result;
       
   662 }
       
   663 
       
   664 // Metachunk methods
       
   665 
       
   666 Metachunk* Metachunk::initialize(MetaWord* ptr, size_t word_size) {
       
   667   // Set bottom, top, and end.  Allow space for the Metachunk itself
       
   668   Metachunk* chunk = (Metachunk*) ptr;
       
   669 
       
   670   MetaWord* chunk_bottom = ptr + _overhead;
       
   671   chunk->set_bottom(ptr);
       
   672   chunk->set_top(chunk_bottom);
       
   673   MetaWord* chunk_end = ptr + word_size;
       
   674   assert(chunk_end > chunk_bottom, "Chunk must be too small");
       
   675   chunk->set_end(chunk_end);
       
   676   chunk->set_next(NULL);
       
   677   chunk->set_word_size(word_size);
       
   678 #ifdef ASSERT
       
   679   size_t data_word_size = pointer_delta(chunk_end, chunk_bottom, sizeof(MetaWord));
       
   680   Copy::fill_to_words((HeapWord*) chunk_bottom, data_word_size, metadata_chunk_initialize);
       
   681 #endif
       
   682   return chunk;
       
   683 }
       
   684 
       
   685 
       
   686 MetaWord* Metachunk::allocate(size_t word_size) {
       
   687   MetaWord* result = NULL;
       
   688   // If available, bump the pointer to allocate.
       
   689   if (free_word_size() >= word_size) {
       
   690     result = _top;
       
   691     _top = _top + word_size;
       
   692   }
       
   693   return result;
       
   694 }
       
   695 
       
   696 // _bottom points to the start of the chunk including the overhead.
       
   697 size_t Metachunk::used_word_size() {
       
   698   return pointer_delta(_top, _bottom, sizeof(MetaWord));
       
   699 }
       
   700 
       
   701 size_t Metachunk::free_word_size() {
       
   702   return pointer_delta(_end, _top, sizeof(MetaWord));
       
   703 }
       
   704 
       
   705 size_t Metachunk::capacity_word_size() {
       
   706   return pointer_delta(_end, _bottom, sizeof(MetaWord));
       
   707 }
       
   708 
       
   709 void Metachunk::print_on(outputStream* st) const {
       
   710   st->print_cr("Metachunk:"
       
   711                " bottom " PTR_FORMAT " top " PTR_FORMAT
       
   712                " end " PTR_FORMAT " size " SIZE_FORMAT,
       
   713                bottom(), top(), end(), word_size());
       
   714 }
       
   715 
       
   716 #ifndef PRODUCT
       
   717 void Metachunk::mangle() {
       
   718   // Mangle the payload of the chunk and not the links that
       
   719   // maintain list of chunks.
       
   720   HeapWord* start = (HeapWord*)(bottom() + overhead());
       
   721   size_t word_size = capacity_word_size() - overhead();
       
   722   Copy::fill_to_words(start, word_size, metadata_chunk_initialize);
       
   723 }
       
   724 #endif // PRODUCT
       
   725 
       
   726 void Metachunk::verify() {
       
   727 #ifdef ASSERT
       
   728   // Cannot walk through the blocks unless the blocks have
       
   729   // headers with sizes.
       
   730   assert(_bottom <= _top &&
       
   731          _top <= _end,
       
   732          "Chunk has been smashed");
       
   733   assert(SpaceManager::is_humongous(_word_size) ||
       
   734          _word_size == SpaceManager::MediumChunk ||
       
   735          _word_size == SpaceManager::SmallChunk,
       
   736          "Chunk size is wrong");
       
   737 #endif
       
   738   return;
       
   739 }
       
   740 
   625 
   741 // BlockFreelist methods
   626 // BlockFreelist methods
   742 
   627 
   743 BlockFreelist::BlockFreelist() : _dictionary(NULL) {}
   628 BlockFreelist::BlockFreelist() : _dictionary(NULL) {}
   744 
   629 
  2212     // like of the small chunk.
  2097     // like of the small chunk.
  2213     for (ChunkIndex i = MediumIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) {
  2098     for (ChunkIndex i = MediumIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) {
  2214       Metachunk* curr = chunks_in_use(i);
  2099       Metachunk* curr = chunks_in_use(i);
  2215       while (curr != NULL) {
  2100       while (curr != NULL) {
  2216         curr->verify();
  2101         curr->verify();
       
  2102         verify_chunk_size(curr);
  2217         curr = curr->next();
  2103         curr = curr->next();
  2218       }
  2104       }
  2219     }
  2105     }
  2220   }
  2106   }
       
  2107 }
       
  2108 
       
  2109 void SpaceManager::verify_chunk_size(Metachunk* chunk) {
       
  2110   assert(is_humongous(chunk->word_size()) ||
       
  2111          chunk->word_size() == MediumChunk ||
       
  2112          chunk->word_size() == SmallChunk,
       
  2113          "Chunk size is wrong");
       
  2114   return;
  2221 }
  2115 }
  2222 
  2116 
  2223 #ifdef ASSERT
  2117 #ifdef ASSERT
  2224 void SpaceManager::verify_allocation_total() {
  2118 void SpaceManager::verify_allocation_total() {
  2225 #if 0
  2119 #if 0