85 // | | | | 86 // | | | free | 87 // | | | | 88 // | | | | size | capacity 89 // | | | | 90 // | | <- top -- + | 91 // | | | | 92 // | | | used | 93 // | | | | 94 // | | | | 95 // +--------------+ <- bottom --+ --+ 96 97 class Metachunk : public Metabase<Metachunk> { 98 friend class MetachunkTest; 99 // The VirtualSpaceNode containing this chunk. 100 VirtualSpaceNode* _container; 101 102 // Current allocation top. 103 MetaWord* _top; 104 105 DEBUG_ONLY(bool _is_tagged_free;) 106 107 MetaWord* initial_top() const { return (MetaWord*)this + overhead(); } 108 MetaWord* top() const { return _top; } 109 110 public: 111 // Metachunks are allocated out of a MetadataVirtualSpace and 112 // and use some of its space to describe itself (plus alignment 113 // considerations). Metadata is allocated in the rest of the chunk. 114 // This size is the overhead of maintaining the Metachunk within 115 // the space. 116 117 // Alignment of each allocation in the chunks. 118 static size_t object_alignment(); 119 120 // Size of the Metachunk header, including alignment. 121 static size_t overhead(); 122 123 Metachunk(size_t word_size , VirtualSpaceNode* container); 124 125 MetaWord* allocate(size_t word_size); 126 127 VirtualSpaceNode* container() const { return _container; } 128 129 MetaWord* bottom() const { return (MetaWord*) this; } 130 131 // Reset top to bottom so chunk can be reused. 132 void reset_empty() { _top = initial_top(); clear_next(); clear_prev(); } 133 bool is_empty() { return _top == initial_top(); } 134 135 // used (has been allocated) 136 // free (available for future allocations) 137 size_t word_size() const { return size(); } 138 size_t used_word_size() const; 139 size_t free_word_size() const; 140 141 #ifdef ASSERT 142 bool is_tagged_free() { return _is_tagged_free; } 143 void set_is_tagged_free(bool v) { _is_tagged_free = v; } 144 #endif 145 146 bool contains(const void* ptr) { return bottom() <= ptr && ptr < _top; } 147 148 #ifndef PRODUCT 149 void mangle(juint word_value); 150 #endif 151 152 void print_on(outputStream* st) const; 153 void verify(); 154 }; 155 156 // Metablock is the unit of allocation from a Chunk. 157 // 158 // A Metablock may be reused by its SpaceManager but are never moved between 159 // SpaceManagers. There is no explicit link to the Metachunk 160 // from which it was allocated. Metablock may be deallocated and 161 // put on a freelist but the space is never freed, rather | 85 // | | | | 86 // | | | free | 87 // | | | | 88 // | | | | size | capacity 89 // | | | | 90 // | | <- top -- + | 91 // | | | | 92 // | | | used | 93 // | | | | 94 // | | | | 95 // +--------------+ <- bottom --+ --+ 96 97 class Metachunk : public Metabase<Metachunk> { 98 friend class MetachunkTest; 99 // The VirtualSpaceNode containing this chunk. 100 VirtualSpaceNode* _container; 101 102 // Current allocation top. 103 MetaWord* _top; 104 105 #ifndef PRODUCT 106 bool _is_tagged_free; 107 #endif 108 109 MetaWord* initial_top() const { return (MetaWord*)this + overhead(); } 110 MetaWord* top() const { return _top; } 111 112 public: 113 // Metachunks are allocated out of a MetadataVirtualSpace and 114 // and use some of its space to describe itself (plus alignment 115 // considerations). Metadata is allocated in the rest of the chunk. 116 // This size is the overhead of maintaining the Metachunk within 117 // the space. 118 119 // Alignment of each allocation in the chunks. 120 static size_t object_alignment(); 121 122 // Size of the Metachunk header, including alignment. 123 static size_t overhead(); 124 125 Metachunk(size_t word_size , VirtualSpaceNode* container); 126 127 MetaWord* allocate(size_t word_size); 128 129 VirtualSpaceNode* container() const { return _container; } 130 131 MetaWord* bottom() const { return (MetaWord*) this; } 132 133 // Reset top to bottom so chunk can be reused. 134 void reset_empty() { _top = initial_top(); clear_next(); clear_prev(); } 135 bool is_empty() { return _top == initial_top(); } 136 137 // used (has been allocated) 138 // free (available for future allocations) 139 size_t word_size() const { return size(); } 140 size_t used_word_size() const; 141 size_t free_word_size() const; 142 143 #ifndef PRODUCT 144 bool is_tagged_free() { return _is_tagged_free; } 145 void set_is_tagged_free(bool v) { _is_tagged_free = v; } 146 #endif 147 148 bool contains(const void* ptr) { return bottom() <= ptr && ptr < _top; } 149 150 #ifndef PRODUCT 151 void mangle(juint word_value); 152 #endif 153 154 void print_on(outputStream* st) const; 155 void verify(); 156 }; 157 158 // Metablock is the unit of allocation from a Chunk. 159 // 160 // A Metablock may be reused by its SpaceManager but are never moved between 161 // SpaceManagers. There is no explicit link to the Metachunk 162 // from which it was allocated. Metablock may be deallocated and 163 // put on a freelist but the space is never freed, rather |