< 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,20 +92,93 @@
// | | | 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* _container;
+ 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,11 +191,11 @@
static size_t object_alignment();
// Size of the Metachunk header, including alignment.
static size_t overhead();
- Metachunk(size_t word_size , VirtualSpaceNode* container);
+ Metachunk(ChunkIndex chunktype, bool is_class, size_t word_size, VirtualSpaceNode* container);
MetaWord* allocate(size_t word_size);
VirtualSpaceNode* container() const { return _container; }
@@ -141,16 +214,32 @@
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
+#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 >