src/hotspot/share/memory/metachunk.hpp
changeset 49365 825f006619e5
parent 47808 57752bd5d1b4
child 49366 f95ef5511e1f
equal deleted inserted replaced
49347:edb65305d3ac 49365:825f006619e5
    92 //            |              |             | used    |
    92 //            |              |             | used    |
    93 //            |              |             |         |
    93 //            |              |             |         |
    94 //            |              |             |         |
    94 //            |              |             |         |
    95 //            +--------------+ <- bottom --+       --+
    95 //            +--------------+ <- bottom --+       --+
    96 
    96 
       
    97 // ChunkIndex defines the type of chunk.
       
    98 // Chunk types differ by size: specialized < small < medium, chunks
       
    99 // larger than 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 enum ChunkOrigin {
       
   128   // Chunk normally born (via take_from_committed)
       
   129   origin_normal = 1,
       
   130   // Chunk was born as padding chunk
       
   131   origin_pad = 2,
       
   132   // Chunk was born as leftover chunk in VirtualSpaceNode::retire
       
   133   origin_leftover = 3,
       
   134   // Chunk was born as result of a merge of smaller chunks
       
   135   origin_merge = 4,
       
   136   // Chunk was born as result of a split of a larger chunk
       
   137   origin_split = 5,
       
   138 
       
   139   origin_minimum = origin_normal,
       
   140   origin_maximum = origin_split,
       
   141   origins_count = origin_maximum + 1
       
   142 };
       
   143 
       
   144 inline bool is_valid_chunkorigin(ChunkOrigin origin) {
       
   145   return origin == origin_normal ||
       
   146     origin == origin_pad ||
       
   147     origin == origin_leftover ||
       
   148     origin == origin_merge ||
       
   149     origin == origin_split;
       
   150 }
       
   151 
    97 class Metachunk : public Metabase<Metachunk> {
   152 class Metachunk : public Metabase<Metachunk> {
    98   friend class MetachunkTest;
   153   friend class MetachunkTest;
    99   // The VirtualSpaceNode containing this chunk.
   154   // The VirtualSpaceNode containing this chunk.
   100   VirtualSpaceNode* _container;
   155   VirtualSpaceNode* const _container;
   101 
   156 
   102   // Current allocation top.
   157   // Current allocation top.
   103   MetaWord* _top;
   158   MetaWord* _top;
   104 
   159 
       
   160   // A 32bit sentinel for debugging purposes.
       
   161   enum { CHUNK_SENTINEL = 0x4d4554EF,  // "MET"
       
   162          CHUNK_SENTINEL_INVALID = 0xFEEEEEEF
       
   163   };
       
   164 
       
   165   uint32_t _sentinel;
       
   166 
       
   167   const ChunkIndex _chunk_type;
       
   168   const bool _is_class;
       
   169   // Whether the chunk is free (in freelist) or in use by some class loader.
   105   bool _is_tagged_free;
   170   bool _is_tagged_free;
       
   171 
       
   172   ChunkOrigin _origin;
       
   173   int _use_count;
   106 
   174 
   107   MetaWord* initial_top() const { return (MetaWord*)this + overhead(); }
   175   MetaWord* initial_top() const { return (MetaWord*)this + overhead(); }
   108   MetaWord* top() const         { return _top; }
   176   MetaWord* top() const         { return _top; }
   109 
   177 
   110  public:
   178  public:
   118   static size_t object_alignment();
   186   static size_t object_alignment();
   119 
   187 
   120   // Size of the Metachunk header, including alignment.
   188   // Size of the Metachunk header, including alignment.
   121   static size_t overhead();
   189   static size_t overhead();
   122 
   190 
   123   Metachunk(size_t word_size , VirtualSpaceNode* container);
   191   Metachunk(ChunkIndex chunktype, bool is_class, size_t word_size, VirtualSpaceNode* container);
   124 
   192 
   125   MetaWord* allocate(size_t word_size);
   193   MetaWord* allocate(size_t word_size);
   126 
   194 
   127   VirtualSpaceNode* container() const { return _container; }
   195   VirtualSpaceNode* container() const { return _container; }
   128 
   196 
   141   bool is_tagged_free() { return _is_tagged_free; }
   209   bool is_tagged_free() { return _is_tagged_free; }
   142   void set_is_tagged_free(bool v) { _is_tagged_free = v; }
   210   void set_is_tagged_free(bool v) { _is_tagged_free = v; }
   143 
   211 
   144   bool contains(const void* ptr) { return bottom() <= ptr && ptr < _top; }
   212   bool contains(const void* ptr) { return bottom() <= ptr && ptr < _top; }
   145 
   213 
   146 #ifndef PRODUCT
       
   147   void mangle(juint word_value);
       
   148 #endif
       
   149 
       
   150   void print_on(outputStream* st) const;
   214   void print_on(outputStream* st) const;
   151   void verify();
   215 
       
   216   bool is_valid_sentinel() const        { return _sentinel == CHUNK_SENTINEL; }
       
   217   void remove_sentinel()                { _sentinel = CHUNK_SENTINEL_INVALID; }
       
   218 
       
   219   int get_use_count() const             { return _use_count; }
       
   220   void inc_use_count()                  { _use_count ++; }
       
   221 
       
   222   ChunkOrigin get_origin() const        { return _origin; }
       
   223   void set_origin(ChunkOrigin orig)     { _origin = orig; }
       
   224 
       
   225   ChunkIndex get_chunk_type() const     { return _chunk_type; }
       
   226   bool is_class() const                 { return _is_class; }
       
   227 
       
   228   DEBUG_ONLY(void mangle(juint word_value);)
       
   229   DEBUG_ONLY(void verify();)
       
   230 
   152 };
   231 };
   153 
   232 
   154 // Metablock is the unit of allocation from a Chunk.
   233 // Metablock is the unit of allocation from a Chunk.
   155 //
   234 //
   156 // A Metablock may be reused by its SpaceManager but are never moved between
   235 // A Metablock may be reused by its SpaceManager but are never moved between