77 bool is_free() { return true; }
78 };
79
80 // Metachunk - Quantum of allocation from a Virtualspace
81 // Metachunks are reused (when freed are put on a global freelist) and
82 // have no permanent association to a SpaceManager.
83
84 // +--------------+ <- end --+ --+
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 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 bool is_tagged_free() { return _is_tagged_free; }
142 void set_is_tagged_free(bool v) { _is_tagged_free = v; }
143
144 bool contains(const void* ptr) { return bottom() <= ptr && ptr < _top; }
145
146 #ifndef PRODUCT
147 void mangle(juint word_value);
148 #endif
149
150 void print_on(outputStream* st) const;
151 void verify();
152 };
153
154 // Metablock is the unit of allocation from a Chunk.
155 //
156 // A Metablock may be reused by its SpaceManager but are never moved between
157 // SpaceManagers. There is no explicit link to the Metachunk
158 // from which it was allocated. Metablock may be deallocated and
159 // put on a freelist but the space is never freed, rather
160 // the Metachunk it is a part of will be deallocated when it's
161 // associated class loader is collected.
162
163 class Metablock : public Metabase<Metablock> {
164 friend class VMStructs;
165 public:
166 Metablock(size_t word_size) : Metabase<Metablock>(word_size) {}
167 };
168
169 #endif // SHARE_VM_MEMORY_METACHUNK_HPP
|
77 bool is_free() { return true; }
78 };
79
80 // Metachunk - Quantum of allocation from a Virtualspace
81 // Metachunks are reused (when freed are put on a global freelist) and
82 // have no permanent association to a SpaceManager.
83
84 // +--------------+ <- end --+ --+
85 // | | | |
86 // | | | free |
87 // | | | |
88 // | | | | size | capacity
89 // | | | |
90 // | | <- top -- + |
91 // | | | |
92 // | | | used |
93 // | | | |
94 // | | | |
95 // +--------------+ <- bottom --+ --+
96
97 // ChunkIndex (todo: rename?) defines the type of chunk. Chunk types
98 // differ by size: specialized < small < medium, chunks larger than
99 // medium are humongous chunks of varying size.
100 enum ChunkIndex {
101 ZeroIndex = 0,
102 SpecializedIndex = ZeroIndex,
103 SmallIndex = SpecializedIndex + 1,
104 MediumIndex = SmallIndex + 1,
105 HumongousIndex = MediumIndex + 1,
106 NumberOfFreeLists = 3,
107 NumberOfInUseLists = 4
108 };
109
110 // Utility functions.
111 size_t get_size_for_nonhumongous_chunktype(ChunkIndex chunk_type, bool is_class);
112 ChunkIndex get_chunk_type_by_size(size_t size, bool is_class);
113
114 // Returns a descriptive name for a chunk type.
115 const char* chunk_size_name(ChunkIndex index);
116
117 // Verify chunk type.
118 inline bool is_valid_chunktype(ChunkIndex index) {
119 return index == SpecializedIndex || index == SmallIndex ||
120 index == MediumIndex || index == HumongousIndex;
121 }
122
123 inline bool is_valid_nonhumongous_chunktype(ChunkIndex index) {
124 return is_valid_chunktype(index) && index != HumongousIndex;
125 }
126
127 #ifdef ASSERT
128
129 enum ChunkOrigin {
130 // Chunk normally born (via take_from_committed)
131 origin_normal = 1,
132 // Chunk was born as padding chunk
133 origin_pad = 2,
134 // Chunk was born as leftover chunk in VirtualSpaceNode::retire
135 origin_leftover = 3,
136 // Chunk was born as result of a coalescation of smaller chunks
137 origin_coalescation = 4,
138 // Chunk was born as result of a split of a larger chunk
139 origin_split = 5,
140
141 origin_minimum = origin_normal,
142 origin_maximum = origin_split,
143 origins_count = origin_maximum + 1
144 };
145
146 inline bool is_valid_chunkorigin(ChunkOrigin origin) {
147 return origin == origin_normal ||
148 origin == origin_pad ||
149 origin == origin_leftover ||
150 origin == origin_coalescation ||
151 origin == origin_split;
152 }
153
154 #endif
155
156 class Metachunk : public Metabase<Metachunk> {
157 friend class MetachunkTest;
158 // The VirtualSpaceNode containing this chunk.
159 VirtualSpaceNode* const _container;
160
161 // Current allocation top.
162 MetaWord* _top;
163
164 #ifdef ASSERT
165 // A 32bit sentinel for debugging purposes.
166 #define CHUNK_SENTINEL 0x4d4554EF // "MET"
167 #define CHUNK_SENTINEL_INVALID 0xFEEEEEEF
168 uint32_t _sentinel;
169 #endif
170 const ChunkIndex _chunk_type;
171 const bool _is_class;
172 // Whether the chunk is free (in freelist) or in use by some class loader.
173 bool _is_tagged_free;
174
175 #ifdef ASSERT
176 ChunkOrigin _origin;
177 int _use_count;
178 #endif
179
180 MetaWord* initial_top() const { return (MetaWord*)this + overhead(); }
181 MetaWord* top() const { return _top; }
182
183 public:
184 // Metachunks are allocated out of a MetadataVirtualSpace and
185 // and use some of its space to describe itself (plus alignment
186 // considerations). Metadata is allocated in the rest of the chunk.
187 // This size is the overhead of maintaining the Metachunk within
188 // the space.
189
190 // Alignment of each allocation in the chunks.
191 static size_t object_alignment();
192
193 // Size of the Metachunk header, including alignment.
194 static size_t overhead();
195
196 Metachunk(ChunkIndex chunktype, bool is_class, size_t word_size, VirtualSpaceNode* container);
197
198 MetaWord* allocate(size_t word_size);
199
200 VirtualSpaceNode* container() const { return _container; }
201
202 MetaWord* bottom() const { return (MetaWord*) this; }
203
204 // Reset top to bottom so chunk can be reused.
205 void reset_empty() { _top = initial_top(); clear_next(); clear_prev(); }
206 bool is_empty() { return _top == initial_top(); }
207
208 // used (has been allocated)
209 // free (available for future allocations)
210 size_t word_size() const { return size(); }
211 size_t used_word_size() const;
212 size_t free_word_size() const;
213
214 bool is_tagged_free() { return _is_tagged_free; }
215 void set_is_tagged_free(bool v) { _is_tagged_free = v; }
216
217 bool contains(const void* ptr) { return bottom() <= ptr && ptr < _top; }
218
219 #ifdef ASSERT
220 void mangle(juint word_value);
221 #endif
222
223 void print_on(outputStream* st) const;
224
225 #ifdef ASSERT
226 void verify();
227
228 bool is_valid_sentinel() const { return _sentinel == CHUNK_SENTINEL; }
229 void remove_sentinel() { _sentinel = CHUNK_SENTINEL_INVALID; }
230
231 ChunkOrigin get_origin() const { return _origin; }
232 void set_origin(ChunkOrigin orig) { _origin = orig; }
233
234 int get_use_count() const { return _use_count; }
235 void inc_use_count() { _use_count ++; }
236 #endif
237
238 ChunkIndex get_chunk_type() const { return _chunk_type; }
239 bool is_class() const { return _is_class; }
240
241 };
242
243 // Metablock is the unit of allocation from a Chunk.
244 //
245 // A Metablock may be reused by its SpaceManager but are never moved between
246 // SpaceManagers. There is no explicit link to the Metachunk
247 // from which it was allocated. Metablock may be deallocated and
248 // put on a freelist but the space is never freed, rather
249 // the Metachunk it is a part of will be deallocated when it's
250 // associated class loader is collected.
251
252 class Metablock : public Metabase<Metablock> {
253 friend class VMStructs;
254 public:
255 Metablock(size_t word_size) : Metabase<Metablock>(word_size) {}
256 };
257
258 #endif // SHARE_VM_MEMORY_METACHUNK_HPP
|