< 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 >