< prev index next >

src/hotspot/share/memory/metachunk.hpp

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


  77   bool is_free()                 { return true; }
  78 };
  79 
  80 //  Metachunk - Quantum of allocation from a Virtualspace
  81 //    Metachunks are reused (when freed are put on a global freelist) and
  82 //    have no permanent association to a SpaceManager.
  83 
  84 //            +--------------+ <- end    --+       --+
  85 //            |              |             |         |
  86 //            |              |             | free    |
  87 //            |              |             |         |
  88 //            |              |             |         | size | capacity
  89 //            |              |             |         |
  90 //            |              | <- top   -- +         |
  91 //            |              |             |         |
  92 //            |              |             | used    |
  93 //            |              |             |         |
  94 //            |              |             |         |
  95 //            +--------------+ <- bottom --+       --+
  96 



























































  97 class Metachunk : public Metabase<Metachunk> {
  98   friend class MetachunkTest;
  99   // The VirtualSpaceNode containing this chunk.
 100   VirtualSpaceNode* _container;
 101 
 102   // Current allocation top.
 103   MetaWord* _top;
 104 









 105   bool _is_tagged_free;
 106 





 107   MetaWord* initial_top() const { return (MetaWord*)this + overhead(); }
 108   MetaWord* top() const         { return _top; }
 109 
 110  public:
 111   // Metachunks are allocated out of a MetadataVirtualSpace and
 112   // and use some of its space to describe itself (plus alignment
 113   // considerations).  Metadata is allocated in the rest of the chunk.
 114   // This size is the overhead of maintaining the Metachunk within
 115   // the space.
 116 
 117   // Alignment of each allocation in the chunks.
 118   static size_t object_alignment();
 119 
 120   // Size of the Metachunk header, including alignment.
 121   static size_t overhead();
 122 
 123   Metachunk(size_t word_size , VirtualSpaceNode* container);
 124 
 125   MetaWord* allocate(size_t word_size);
 126 
 127   VirtualSpaceNode* container() const { return _container; }
 128 
 129   MetaWord* bottom() const { return (MetaWord*) this; }
 130 
 131   // Reset top to bottom so chunk can be reused.
 132   void reset_empty() { _top = initial_top(); clear_next(); clear_prev(); }
 133   bool is_empty() { return _top == initial_top(); }
 134 
 135   // used (has been allocated)
 136   // free (available for future allocations)
 137   size_t word_size() const { return size(); }
 138   size_t used_word_size() const;
 139   size_t free_word_size() const;
 140 
 141   bool is_tagged_free() { return _is_tagged_free; }
 142   void set_is_tagged_free(bool v) { _is_tagged_free = v; }
 143 
 144   bool contains(const void* ptr) { return bottom() <= ptr && ptr < _top; }
 145 
 146 #ifndef PRODUCT
 147   void mangle(juint word_value);
 148 #endif
 149 
 150   void print_on(outputStream* st) const;


 151   void verify();














 152 };
 153 
 154 // Metablock is the unit of allocation from a Chunk.
 155 //
 156 // A Metablock may be reused by its SpaceManager but are never moved between
 157 // SpaceManagers.  There is no explicit link to the Metachunk
 158 // from which it was allocated.  Metablock may be deallocated and
 159 // put on a freelist but the space is never freed, rather
 160 // the Metachunk it is a part of will be deallocated when it's
 161 // associated class loader is collected.
 162 
 163 class Metablock : public Metabase<Metablock> {
 164   friend class VMStructs;
 165  public:
 166   Metablock(size_t word_size) : Metabase<Metablock>(word_size) {}
 167 };
 168 
 169 #endif  // SHARE_VM_MEMORY_METACHUNK_HPP


  77   bool is_free()                 { return true; }
  78 };
  79 
  80 //  Metachunk - Quantum of allocation from a Virtualspace
  81 //    Metachunks are reused (when freed are put on a global freelist) and
  82 //    have no permanent association to a SpaceManager.
  83 
  84 //            +--------------+ <- end    --+       --+
  85 //            |              |             |         |
  86 //            |              |             | free    |
  87 //            |              |             |         |
  88 //            |              |             |         | size | capacity
  89 //            |              |             |         |
  90 //            |              | <- top   -- +         |
  91 //            |              |             |         |
  92 //            |              |             | used    |
  93 //            |              |             |         |
  94 //            |              |             |         |
  95 //            +--------------+ <- bottom --+       --+
  96 
  97 // ChunkIndex (todo: rename?) defines the type of chunk. Chunk types
  98 // differ by size: specialized < small < medium, chunks larger than
  99 // medium are humongous chunks of varying size.
 100 enum ChunkIndex {
 101   ZeroIndex = 0,
 102   SpecializedIndex = ZeroIndex,
 103   SmallIndex = SpecializedIndex + 1,
 104   MediumIndex = SmallIndex + 1,
 105   HumongousIndex = MediumIndex + 1,
 106   NumberOfFreeLists = 3,
 107   NumberOfInUseLists = 4
 108 };
 109 
 110 // Utility functions.
 111 size_t get_size_for_nonhumongous_chunktype(ChunkIndex chunk_type, bool is_class);
 112 ChunkIndex get_chunk_type_by_size(size_t size, bool is_class);
 113 
 114 // Returns a descriptive name for a chunk type.
 115 const char* chunk_size_name(ChunkIndex index);
 116 
 117 // Verify chunk type.
 118 inline bool is_valid_chunktype(ChunkIndex index) {
 119   return index == SpecializedIndex || index == SmallIndex ||
 120          index == MediumIndex || index == HumongousIndex;
 121 }
 122 
 123 inline bool is_valid_nonhumongous_chunktype(ChunkIndex index) {
 124   return is_valid_chunktype(index) && index != HumongousIndex;
 125 }
 126 
 127 #ifdef ASSERT
 128 
 129 enum ChunkOrigin {
 130   // Chunk normally born (via take_from_committed)
 131   origin_normal = 1,
 132   // Chunk was born as padding chunk
 133   origin_pad = 2,
 134   // Chunk was born as leftover chunk in VirtualSpaceNode::retire
 135   origin_leftover = 3,
 136   // Chunk was born as result of a coalescation of smaller chunks
 137   origin_coalescation = 4,
 138   // Chunk was born as result of a split of a larger chunk
 139   origin_split = 5,
 140 
 141   origin_minimum = origin_normal,
 142   origin_maximum = origin_split,
 143   origins_count = origin_maximum + 1
 144 };
 145 
 146 inline bool is_valid_chunkorigin(ChunkOrigin origin) {
 147   return origin == origin_normal ||
 148     origin == origin_pad ||
 149     origin == origin_leftover ||
 150     origin == origin_coalescation ||
 151     origin == origin_split;
 152 }
 153 
 154 #endif
 155 
 156 class Metachunk : public Metabase<Metachunk> {
 157   friend class MetachunkTest;
 158   // The VirtualSpaceNode containing this chunk.
 159   VirtualSpaceNode* const _container;
 160 
 161   // Current allocation top.
 162   MetaWord* _top;
 163 
 164 #ifdef ASSERT
 165   // A 32bit sentinel for debugging purposes.
 166 #define CHUNK_SENTINEL          0x4d4554EF  // "MET"
 167 #define CHUNK_SENTINEL_INVALID  0xFEEEEEEF
 168   uint32_t _sentinel;
 169 #endif
 170   const ChunkIndex _chunk_type;
 171   const bool _is_class;
 172   // Whether the chunk is free (in freelist) or in use by some class loader.
 173   bool _is_tagged_free;
 174 
 175 #ifdef ASSERT
 176   ChunkOrigin _origin;
 177   int _use_count;
 178 #endif
 179 
 180   MetaWord* initial_top() const { return (MetaWord*)this + overhead(); }
 181   MetaWord* top() const         { return _top; }
 182 
 183  public:
 184   // Metachunks are allocated out of a MetadataVirtualSpace and
 185   // and use some of its space to describe itself (plus alignment
 186   // considerations).  Metadata is allocated in the rest of the chunk.
 187   // This size is the overhead of maintaining the Metachunk within
 188   // the space.
 189 
 190   // Alignment of each allocation in the chunks.
 191   static size_t object_alignment();
 192 
 193   // Size of the Metachunk header, including alignment.
 194   static size_t overhead();
 195 
 196   Metachunk(ChunkIndex chunktype, bool is_class, size_t word_size, VirtualSpaceNode* container);
 197 
 198   MetaWord* allocate(size_t word_size);
 199 
 200   VirtualSpaceNode* container() const { return _container; }
 201 
 202   MetaWord* bottom() const { return (MetaWord*) this; }
 203 
 204   // Reset top to bottom so chunk can be reused.
 205   void reset_empty() { _top = initial_top(); clear_next(); clear_prev(); }
 206   bool is_empty() { return _top == initial_top(); }
 207 
 208   // used (has been allocated)
 209   // free (available for future allocations)
 210   size_t word_size() const { return size(); }
 211   size_t used_word_size() const;
 212   size_t free_word_size() const;
 213 
 214   bool is_tagged_free() { return _is_tagged_free; }
 215   void set_is_tagged_free(bool v) { _is_tagged_free = v; }
 216 
 217   bool contains(const void* ptr) { return bottom() <= ptr && ptr < _top; }
 218 
 219 #ifdef ASSERT
 220   void mangle(juint word_value);
 221 #endif
 222 
 223   void print_on(outputStream* st) const;
 224 
 225 #ifdef ASSERT
 226   void verify();
 227 
 228   bool is_valid_sentinel() const        { return _sentinel == CHUNK_SENTINEL; }
 229   void remove_sentinel()                { _sentinel = CHUNK_SENTINEL_INVALID; }
 230 
 231   ChunkOrigin get_origin() const        { return _origin; }
 232   void set_origin(ChunkOrigin orig)     { _origin = orig; }
 233 
 234   int get_use_count() const             { return _use_count; }
 235   void inc_use_count()                  { _use_count ++; }
 236 #endif
 237 
 238   ChunkIndex get_chunk_type() const     { return _chunk_type; }
 239   bool is_class() const                 { return _is_class; }
 240 
 241 };
 242 
 243 // Metablock is the unit of allocation from a Chunk.
 244 //
 245 // A Metablock may be reused by its SpaceManager but are never moved between
 246 // SpaceManagers.  There is no explicit link to the Metachunk
 247 // from which it was allocated.  Metablock may be deallocated and
 248 // put on a freelist but the space is never freed, rather
 249 // the Metachunk it is a part of will be deallocated when it's
 250 // associated class loader is collected.
 251 
 252 class Metablock : public Metabase<Metablock> {
 253   friend class VMStructs;
 254  public:
 255   Metablock(size_t word_size) : Metabase<Metablock>(word_size) {}
 256 };
 257 
 258 #endif  // SHARE_VM_MEMORY_METACHUNK_HPP
< prev index next >