< prev index next >

src/hotspot/share/memory/metachunk.cpp

Print this page
rev 49010 : [mq]: metaspace-coalesc-patch
rev 49011 : [mq]: metaspace-coal-2

@@ -46,20 +46,28 @@
   return align_up(sizeof(Metachunk), object_alignment()) / BytesPerWord;
 }
 
 // Metachunk methods
 
-Metachunk::Metachunk(size_t word_size,
+Metachunk::Metachunk(ChunkIndex chunktype, bool is_class, size_t word_size,
                      VirtualSpaceNode* container)
     : Metabase<Metachunk>(word_size),
+    _chunk_type(chunktype),
+    _is_class(is_class),
+#ifdef ASSERT
+    _sentinel(CHUNK_SENTINEL),
+    _origin(origin_normal),
+    _use_count(0),
+#endif
     _top(NULL),
     _container(container)
 {
   _top = initial_top();
   set_is_tagged_free(false);
 #ifdef ASSERT
   mangle(uninitMetaWordVal);
+  verify();
 #endif
 }
 
 MetaWord* Metachunk::allocate(size_t word_size) {
   MetaWord* result = NULL;

@@ -81,34 +89,63 @@
 }
 
 void Metachunk::print_on(outputStream* st) const {
   st->print_cr("Metachunk:"
                " bottom " PTR_FORMAT " top " PTR_FORMAT
-               " end " PTR_FORMAT " size " SIZE_FORMAT,
-               p2i(bottom()), p2i(_top), p2i(end()), word_size());
+               " end " PTR_FORMAT " size " SIZE_FORMAT " (%s)",
+               p2i(bottom()), p2i(_top), p2i(end()), word_size(),
+               chunk_size_name(get_chunk_type()));
   if (Verbose) {
     st->print_cr("    used " SIZE_FORMAT " free " SIZE_FORMAT,
                  used_word_size(), free_word_size());
   }
 }
 
-#ifndef PRODUCT
+#ifdef ASSERT
 void Metachunk::mangle(juint word_value) {
   // Overwrite the payload of the chunk and not the links that
   // maintain list of chunks.
   HeapWord* start = (HeapWord*)initial_top();
   size_t size = word_size() - overhead();
   Copy::fill_to_words(start, size, word_value);
 }
-#endif // PRODUCT
 
 void Metachunk::verify() {
-#ifdef ASSERT
-  // Cannot walk through the blocks unless the blocks have
-  // headers with sizes.
-  assert(bottom() <= _top &&
-         _top <= (MetaWord*)end(),
-         "Chunk has been smashed");
-#endif
-  return;
+  assert(is_valid_sentinel(), "Chunk " PTR_FORMAT ": sentinel invalid", p2i(this));
+  const ChunkIndex chunk_type = get_chunk_type();
+  assert(is_valid_chunktype(chunk_type), "Chunk " PTR_FORMAT ": Invalid chunk type.", p2i(this));
+  if (chunk_type != HumongousIndex) {
+    assert(word_size() == get_size_for_nonhumongous_chunktype(chunk_type, is_class()),
+           "Chunk " PTR_FORMAT ": wordsize " SIZE_FORMAT " does not fit chunk type %s.",
+           p2i(this), word_size(), chunk_size_name(chunk_type));
+  }
+  assert(is_valid_chunkorigin(get_origin()), "Chunk " PTR_FORMAT ": Invalid chunk origin.", p2i(this));
+  assert(bottom() <= _top && _top <= (MetaWord*)end(),
+         "Chunk " PTR_FORMAT ": Chunk top out of chunk bounds.", p2i(this));
+
+  // For non-humongous chunks, starting address shall be aligned
+  // to its chunk size. Humongous chunks start address is
+  // aligned to specialized chunk size.
+  const size_t required_alignment =
+    (chunk_type != HumongousIndex ? word_size() : get_size_for_nonhumongous_chunktype(SpecializedIndex, is_class())) * sizeof(MetaWord);
+  assert(is_aligned((address)this, required_alignment),
+         "Chunk " PTR_FORMAT ": (size " SIZE_FORMAT ") not aligned to " SIZE_FORMAT ".",
+         p2i(this), word_size() * sizeof(MetaWord), required_alignment);
+}
+
+#endif // ASSERT
+
+// Helper, returns a descriptive name for the given index.
+const char* chunk_size_name(ChunkIndex index) {
+  switch (index) {
+    case SpecializedIndex:
+      return "specialized";
+    case SmallIndex:
+      return "small";
+    case MediumIndex:
+      return "medium";
+    case HumongousIndex:
+      return "humongous";
+    default:
+      return "Invalid index";
+  }
 }
-
< prev index next >