< 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,111 **** // | | | used | // | | | | // | | | | // +--------------+ <- bottom --+ --+ class Metachunk : public Metabase<Metachunk> { friend class MetachunkTest; // The VirtualSpaceNode containing this chunk. ! VirtualSpaceNode* _container; // Current allocation top. MetaWord* _top; bool _is_tagged_free; MetaWord* initial_top() const { return (MetaWord*)this + overhead(); } MetaWord* top() const { return _top; } public: // Metachunks are allocated out of a MetadataVirtualSpace and --- 92,184 ---- // | | | 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* 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,128 **** static size_t object_alignment(); // Size of the Metachunk header, including alignment. static size_t overhead(); ! Metachunk(size_t word_size , VirtualSpaceNode* container); MetaWord* allocate(size_t word_size); VirtualSpaceNode* container() const { return _container; } --- 191,201 ---- static size_t object_alignment(); // Size of the Metachunk header, including alignment. static size_t overhead(); ! Metachunk(ChunkIndex chunktype, bool is_class, size_t word_size, VirtualSpaceNode* container); MetaWord* allocate(size_t word_size); VirtualSpaceNode* container() const { return _container; }
*** 141,156 **** 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 void mangle(juint word_value); #endif void print_on(outputStream* st) const; void verify(); }; // Metablock is the unit of allocation from a Chunk. // // A Metablock may be reused by its SpaceManager but are never moved between --- 214,245 ---- 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; } ! #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 >