< prev index next >

src/hotspot/share/memory/metachunk.hpp

Print this page
rev 49184 : 8198423: Improve metaspace chunk allocation
Reviewed-by: goetz, coleenp

*** 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,179 ---- // | | | used | // | | | | // | | | | // +--------------+ <- 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* 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; } 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; } --- 186,196 ---- 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 --- 209,235 ---- 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; } 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 ++; } ! ! 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. // // A Metablock may be reused by its SpaceManager but are never moved between
< prev index next >