src/hotspot/share/memory/metachunk.cpp
changeset 49365 825f006619e5
parent 47808 57752bd5d1b4
child 50066 bd3e4517dfa3
equal deleted inserted replaced
49347:edb65305d3ac 49365:825f006619e5
    46   return align_up(sizeof(Metachunk), object_alignment()) / BytesPerWord;
    46   return align_up(sizeof(Metachunk), object_alignment()) / BytesPerWord;
    47 }
    47 }
    48 
    48 
    49 // Metachunk methods
    49 // Metachunk methods
    50 
    50 
    51 Metachunk::Metachunk(size_t word_size,
    51 Metachunk::Metachunk(ChunkIndex chunktype, bool is_class, size_t word_size,
    52                      VirtualSpaceNode* container)
    52                      VirtualSpaceNode* container)
    53     : Metabase<Metachunk>(word_size),
    53     : Metabase<Metachunk>(word_size),
       
    54     _chunk_type(chunktype),
       
    55     _is_class(is_class),
       
    56     _sentinel(CHUNK_SENTINEL),
       
    57     _origin(origin_normal),
       
    58     _use_count(0),
    54     _top(NULL),
    59     _top(NULL),
    55     _container(container)
    60     _container(container)
    56 {
    61 {
    57   _top = initial_top();
    62   _top = initial_top();
    58   set_is_tagged_free(false);
    63   set_is_tagged_free(false);
    59 #ifdef ASSERT
    64 #ifdef ASSERT
    60   mangle(uninitMetaWordVal);
    65   mangle(uninitMetaWordVal);
       
    66   verify();
    61 #endif
    67 #endif
    62 }
    68 }
    63 
    69 
    64 MetaWord* Metachunk::allocate(size_t word_size) {
    70 MetaWord* Metachunk::allocate(size_t word_size) {
    65   MetaWord* result = NULL;
    71   MetaWord* result = NULL;
    81 }
    87 }
    82 
    88 
    83 void Metachunk::print_on(outputStream* st) const {
    89 void Metachunk::print_on(outputStream* st) const {
    84   st->print_cr("Metachunk:"
    90   st->print_cr("Metachunk:"
    85                " bottom " PTR_FORMAT " top " PTR_FORMAT
    91                " bottom " PTR_FORMAT " top " PTR_FORMAT
    86                " end " PTR_FORMAT " size " SIZE_FORMAT,
    92                " end " PTR_FORMAT " size " SIZE_FORMAT " (%s)",
    87                p2i(bottom()), p2i(_top), p2i(end()), word_size());
    93                p2i(bottom()), p2i(_top), p2i(end()), word_size(),
       
    94                chunk_size_name(get_chunk_type()));
    88   if (Verbose) {
    95   if (Verbose) {
    89     st->print_cr("    used " SIZE_FORMAT " free " SIZE_FORMAT,
    96     st->print_cr("    used " SIZE_FORMAT " free " SIZE_FORMAT,
    90                  used_word_size(), free_word_size());
    97                  used_word_size(), free_word_size());
    91   }
    98   }
    92 }
    99 }
    93 
   100 
    94 #ifndef PRODUCT
   101 #ifdef ASSERT
    95 void Metachunk::mangle(juint word_value) {
   102 void Metachunk::mangle(juint word_value) {
    96   // Overwrite the payload of the chunk and not the links that
   103   // Overwrite the payload of the chunk and not the links that
    97   // maintain list of chunks.
   104   // maintain list of chunks.
    98   HeapWord* start = (HeapWord*)initial_top();
   105   HeapWord* start = (HeapWord*)initial_top();
    99   size_t size = word_size() - overhead();
   106   size_t size = word_size() - overhead();
   100   Copy::fill_to_words(start, size, word_value);
   107   Copy::fill_to_words(start, size, word_value);
   101 }
   108 }
   102 #endif // PRODUCT
       
   103 
   109 
   104 void Metachunk::verify() {
   110 void Metachunk::verify() {
   105 #ifdef ASSERT
   111   assert(is_valid_sentinel(), "Chunk " PTR_FORMAT ": sentinel invalid", p2i(this));
   106   // Cannot walk through the blocks unless the blocks have
   112   const ChunkIndex chunk_type = get_chunk_type();
   107   // headers with sizes.
   113   assert(is_valid_chunktype(chunk_type), "Chunk " PTR_FORMAT ": Invalid chunk type.", p2i(this));
   108   assert(bottom() <= _top &&
   114   if (chunk_type != HumongousIndex) {
   109          _top <= (MetaWord*)end(),
   115     assert(word_size() == get_size_for_nonhumongous_chunktype(chunk_type, is_class()),
   110          "Chunk has been smashed");
   116            "Chunk " PTR_FORMAT ": wordsize " SIZE_FORMAT " does not fit chunk type %s.",
   111 #endif
   117            p2i(this), word_size(), chunk_size_name(chunk_type));
   112   return;
   118   }
       
   119   assert(is_valid_chunkorigin(get_origin()), "Chunk " PTR_FORMAT ": Invalid chunk origin.", p2i(this));
       
   120   assert(bottom() <= _top && _top <= (MetaWord*)end(),
       
   121          "Chunk " PTR_FORMAT ": Chunk top out of chunk bounds.", p2i(this));
       
   122 
       
   123   // For non-humongous chunks, starting address shall be aligned
       
   124   // to its chunk size. Humongous chunks start address is
       
   125   // aligned to specialized chunk size.
       
   126   const size_t required_alignment =
       
   127     (chunk_type != HumongousIndex ? word_size() : get_size_for_nonhumongous_chunktype(SpecializedIndex, is_class())) * sizeof(MetaWord);
       
   128   assert(is_aligned((address)this, required_alignment),
       
   129          "Chunk " PTR_FORMAT ": (size " SIZE_FORMAT ") not aligned to " SIZE_FORMAT ".",
       
   130          p2i(this), word_size() * sizeof(MetaWord), required_alignment);
   113 }
   131 }
   114 
   132 
       
   133 #endif // ASSERT
       
   134 
       
   135 // Helper, returns a descriptive name for the given index.
       
   136 const char* chunk_size_name(ChunkIndex index) {
       
   137   switch (index) {
       
   138     case SpecializedIndex:
       
   139       return "specialized";
       
   140     case SmallIndex:
       
   141       return "small";
       
   142     case MediumIndex:
       
   143       return "medium";
       
   144     case HumongousIndex:
       
   145       return "humongous";
       
   146     default:
       
   147       return "Invalid index";
       
   148   }
       
   149 }