< prev index next >

src/hotspot/share/memory/metachunk.hpp

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

@@ -92,20 +92,93 @@
 //            |              |             | used    |
 //            |              |             |         |
 //            |              |             |         |
 //            +--------------+ <- bottom --+       --+
 
+// ChunkIndex (todo: rename?) 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;
+}
+
+#ifdef ASSERT
+
+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 coalescation of smaller chunks
+  origin_coalescation = 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_coalescation ||
+    origin == origin_split;
+}
+
+#endif
+
 class Metachunk : public Metabase<Metachunk> {
   friend class MetachunkTest;
   // The VirtualSpaceNode containing this chunk.
-  VirtualSpaceNode* _container;
+  VirtualSpaceNode* const _container;
 
   // Current allocation top.
   MetaWord* _top;
 
+#ifdef ASSERT
+  // A 32bit sentinel for debugging purposes.
+#define CHUNK_SENTINEL          0x4d4554EF  // "MET"
+#define CHUNK_SENTINEL_INVALID  0xFEEEEEEF
+  uint32_t _sentinel;
+#endif
+  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;
 
+#ifdef ASSERT
+  ChunkOrigin _origin;
+  int _use_count;
+#endif
+
   MetaWord* initial_top() const { return (MetaWord*)this + overhead(); }
   MetaWord* top() const         { return _top; }
 
  public:
   // Metachunks are allocated out of a MetadataVirtualSpace and

@@ -118,11 +191,11 @@
   static size_t object_alignment();
 
   // 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);
 
   VirtualSpaceNode* container() const { return _container; }
 

@@ -141,16 +214,32 @@
   bool is_tagged_free() { return _is_tagged_free; }
   void set_is_tagged_free(bool v) { _is_tagged_free = v; }
 
   bool contains(const void* ptr) { return bottom() <= ptr && ptr < _top; }
 
-#ifndef PRODUCT
+#ifdef ASSERT
   void mangle(juint word_value);
 #endif
 
   void print_on(outputStream* st) const;
+
+#ifdef ASSERT
   void verify();
+
+  bool is_valid_sentinel() const        { return _sentinel == CHUNK_SENTINEL; }
+  void remove_sentinel()                { _sentinel = CHUNK_SENTINEL_INVALID; }
+
+  ChunkOrigin get_origin() const        { return _origin; }
+  void set_origin(ChunkOrigin orig)     { _origin = orig; }
+
+  int get_use_count() const             { return _use_count; }
+  void inc_use_count()                  { _use_count ++; }
+#endif
+
+  ChunkIndex get_chunk_type() const     { return _chunk_type; }
+  bool is_class() const                 { return _is_class; }
+
 };
 
 // Metablock is the unit of allocation from a Chunk.
 //
 // A Metablock may be reused by its SpaceManager but are never moved between
< prev index next >