src/hotspot/share/memory/metachunk.hpp
changeset 49365 825f006619e5
parent 47808 57752bd5d1b4
child 49366 f95ef5511e1f
--- a/src/hotspot/share/memory/metachunk.hpp	Tue Mar 06 08:36:44 2018 +0100
+++ b/src/hotspot/share/memory/metachunk.hpp	Tue Mar 06 19:24:13 2018 +0100
@@ -94,16 +94,84 @@
 //            |              |             |         |
 //            +--------------+ <- bottom --+       --+
 
+// ChunkIndex defines the type of chunk.
+// Chunk types differ by size: specialized < small < medium, chunks
+// larger than medium are humongous chunks of varying size.
+enum ChunkIndex {
+  ZeroIndex = 0,
+  SpecializedIndex = ZeroIndex,
+  SmallIndex = SpecializedIndex + 1,
+  MediumIndex = SmallIndex + 1,
+  HumongousIndex = MediumIndex + 1,
+  NumberOfFreeLists = 3,
+  NumberOfInUseLists = 4
+};
+
+// Utility functions.
+size_t get_size_for_nonhumongous_chunktype(ChunkIndex chunk_type, bool is_class);
+ChunkIndex get_chunk_type_by_size(size_t size, bool is_class);
+
+// Returns a descriptive name for a chunk type.
+const char* chunk_size_name(ChunkIndex index);
+
+// Verify chunk type.
+inline bool is_valid_chunktype(ChunkIndex index) {
+  return index == SpecializedIndex || index == SmallIndex ||
+         index == MediumIndex || index == HumongousIndex;
+}
+
+inline bool is_valid_nonhumongous_chunktype(ChunkIndex index) {
+  return is_valid_chunktype(index) && index != HumongousIndex;
+}
+
+enum ChunkOrigin {
+  // Chunk normally born (via take_from_committed)
+  origin_normal = 1,
+  // Chunk was born as padding chunk
+  origin_pad = 2,
+  // Chunk was born as leftover chunk in VirtualSpaceNode::retire
+  origin_leftover = 3,
+  // Chunk was born as result of a merge of smaller chunks
+  origin_merge = 4,
+  // Chunk was born as result of a split of a larger chunk
+  origin_split = 5,
+
+  origin_minimum = origin_normal,
+  origin_maximum = origin_split,
+  origins_count = origin_maximum + 1
+};
+
+inline bool is_valid_chunkorigin(ChunkOrigin origin) {
+  return origin == origin_normal ||
+    origin == origin_pad ||
+    origin == origin_leftover ||
+    origin == origin_merge ||
+    origin == origin_split;
+}
+
 class Metachunk : public Metabase<Metachunk> {
   friend class MetachunkTest;
   // The VirtualSpaceNode containing this chunk.
-  VirtualSpaceNode* _container;
+  VirtualSpaceNode* const _container;
 
   // Current allocation top.
   MetaWord* _top;
 
+  // A 32bit sentinel for debugging purposes.
+  enum { CHUNK_SENTINEL = 0x4d4554EF,  // "MET"
+         CHUNK_SENTINEL_INVALID = 0xFEEEEEEF
+  };
+
+  uint32_t _sentinel;
+
+  const ChunkIndex _chunk_type;
+  const bool _is_class;
+  // Whether the chunk is free (in freelist) or in use by some class loader.
   bool _is_tagged_free;
 
+  ChunkOrigin _origin;
+  int _use_count;
+
   MetaWord* initial_top() const { return (MetaWord*)this + overhead(); }
   MetaWord* top() const         { return _top; }
 
@@ -120,7 +188,7 @@
   // Size of the Metachunk header, including alignment.
   static size_t overhead();
 
-  Metachunk(size_t word_size , VirtualSpaceNode* container);
+  Metachunk(ChunkIndex chunktype, bool is_class, size_t word_size, VirtualSpaceNode* container);
 
   MetaWord* allocate(size_t word_size);
 
@@ -143,12 +211,23 @@
 
   bool contains(const void* ptr) { return bottom() <= ptr && ptr < _top; }
 
-#ifndef PRODUCT
-  void mangle(juint word_value);
-#endif
+  void print_on(outputStream* st) const;
+
+  bool is_valid_sentinel() const        { return _sentinel == CHUNK_SENTINEL; }
+  void remove_sentinel()                { _sentinel = CHUNK_SENTINEL_INVALID; }
+
+  int get_use_count() const             { return _use_count; }
+  void inc_use_count()                  { _use_count ++; }
 
-  void print_on(outputStream* st) const;
-  void verify();
+  ChunkOrigin get_origin() const        { return _origin; }
+  void set_origin(ChunkOrigin orig)     { _origin = orig; }
+
+  ChunkIndex get_chunk_type() const     { return _chunk_type; }
+  bool is_class() const                 { return _is_class; }
+
+  DEBUG_ONLY(void mangle(juint word_value);)
+  DEBUG_ONLY(void verify();)
+
 };
 
 // Metablock is the unit of allocation from a Chunk.