7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24 #ifndef SHARE_VM_MEMORY_METACHUNK_HPP
25 #define SHARE_VM_MEMORY_METACHUNK_HPP
26
27 #include "utilities/debug.hpp"
28 #include "utilities/globalDefinitions.hpp"
29
30 class VirtualSpaceNode;
31
32 // Super class of Metablock and Metachunk to allow them to
33 // be put on the FreeList and in the BinaryTreeDictionary.
34 template <class T>
35 class Metabase {
36 size_t _word_size;
37 T* _next;
38 T* _prev;
39
40 protected:
41 Metabase(size_t word_size) : _word_size(word_size), _next(NULL), _prev(NULL) {}
42
43 public:
44 T* next() const { return _next; }
45 T* prev() const { return _prev; }
46 void set_next(T* v) { _next = v; assert(v != this, "Boom");}
47 void set_prev(T* v) { _prev = v; assert(v != this, "Boom");}
48 void clear_next() { set_next(NULL); }
49 void clear_prev() { set_prev(NULL); }
50
51 size_t size() const volatile { return _word_size; }
52 void set_size(size_t v) { _word_size = v; }
53
54 void link_next(T* ptr) { set_next(ptr); }
55 void link_prev(T* ptr) { set_prev(ptr); }
56 void link_after(T* ptr) {
57 link_next(ptr);
58 if (ptr != NULL) ptr->link_prev((T*)this);
59 }
60
61 uintptr_t* end() const { return ((uintptr_t*) this) + size(); }
62
63 bool cantCoalesce() const { return false; }
64
65 // Debug support
66 #ifdef ASSERT
67 void* prev_addr() const { return (void*)&_prev; }
68 void* next_addr() const { return (void*)&_next; }
69 void* size_addr() const { return (void*)&_word_size; }
70 #endif
71 bool verify_chunk_in_free_list(T* tc) const { return true; }
72 bool verify_par_locked() { return true; }
73
74 void assert_is_mangled() const {/* Don't check "\*/}
75
76 bool is_free() { return true; }
77 };
78
79 // Metachunk - Quantum of allocation from a Virtualspace
80 // Metachunks are reused (when freed are put on a global freelist) and
81 // have no permanent association to a SpaceManager.
82
83 // +--------------+ <- end --+ --+
84 // | | | |
85 // | | | free |
86 // | | | |
87 // | | | | size | capacity
88 // | | | |
89 // | | <- top -- + |
90 // | | | |
91 // | | | used |
92 // | | | |
93 // | | | |
94 // +--------------+ <- bottom --+ --+
95
96 // ChunkIndex defines the type of chunk.
97 // Chunk types differ by size: specialized < small < medium, chunks
98 // larger than medium are humongous chunks of varying size.
99 enum ChunkIndex {
100 ZeroIndex = 0,
101 SpecializedIndex = ZeroIndex,
102 SmallIndex = SpecializedIndex + 1,
103 MediumIndex = SmallIndex + 1,
104 HumongousIndex = MediumIndex + 1,
105 NumberOfFreeLists = 3,
106 NumberOfInUseLists = 4
107 };
108
109 // Utility functions.
110 size_t get_size_for_nonhumongous_chunktype(ChunkIndex chunk_type, bool is_class);
111 ChunkIndex get_chunk_type_by_size(size_t size, bool is_class);
112
113 ChunkIndex next_chunk_index(ChunkIndex i);
114 ChunkIndex prev_chunk_index(ChunkIndex i);
115
116 // Returns a descriptive name for a chunk type.
117 const char* chunk_size_name(ChunkIndex index);
118
119 // Verify chunk type.
120 inline bool is_valid_chunktype(ChunkIndex index) {
121 return index == SpecializedIndex || index == SmallIndex ||
122 index == MediumIndex || index == HumongousIndex;
123 }
124
125 inline bool is_valid_nonhumongous_chunktype(ChunkIndex index) {
126 return is_valid_chunktype(index) && index != HumongousIndex;
127 }
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 merge of smaller chunks
137 origin_merge = 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_merge ||
151 origin == origin_split;
152 }
153
154 class Metachunk : public Metabase<Metachunk> {
155 friend class MetachunkTest;
156 // The VirtualSpaceNode containing this chunk.
157 VirtualSpaceNode* const _container;
158
159 // Current allocation top.
160 MetaWord* _top;
161
162 // A 32bit sentinel for debugging purposes.
163 enum { CHUNK_SENTINEL = 0x4d4554EF, // "MET"
164 CHUNK_SENTINEL_INVALID = 0xFEEEEEEF
165 };
166
167 uint32_t _sentinel;
168
169 const ChunkIndex _chunk_type;
170 const bool _is_class;
171 // Whether the chunk is free (in freelist) or in use by some class loader.
172 bool _is_tagged_free;
173
174 ChunkOrigin _origin;
175 int _use_count;
215
216 void print_on(outputStream* st) const;
217
218 bool is_valid_sentinel() const { return _sentinel == CHUNK_SENTINEL; }
219 void remove_sentinel() { _sentinel = CHUNK_SENTINEL_INVALID; }
220
221 int get_use_count() const { return _use_count; }
222 void inc_use_count() { _use_count ++; }
223
224 ChunkOrigin get_origin() const { return _origin; }
225 void set_origin(ChunkOrigin orig) { _origin = orig; }
226
227 ChunkIndex get_chunk_type() const { return _chunk_type; }
228 bool is_class() const { return _is_class; }
229
230 DEBUG_ONLY(void mangle(juint word_value);)
231 DEBUG_ONLY(void verify() const;)
232
233 };
234
235 // Metablock is the unit of allocation from a Chunk.
236 //
237 // A Metablock may be reused by its SpaceManager but are never moved between
238 // SpaceManagers. There is no explicit link to the Metachunk
239 // from which it was allocated. Metablock may be deallocated and
240 // put on a freelist but the space is never freed, rather
241 // the Metachunk it is a part of will be deallocated when it's
242 // associated class loader is collected.
243
244 class Metablock : public Metabase<Metablock> {
245 friend class VMStructs;
246 public:
247 Metablock(size_t word_size) : Metabase<Metablock>(word_size) {}
248 };
249
250 #endif // SHARE_VM_MEMORY_METACHUNK_HPP
|
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24 #ifndef SHARE_VM_MEMORY_METACHUNK_HPP
25 #define SHARE_VM_MEMORY_METACHUNK_HPP
26
27 #include "memory/metaspace/metabase.hpp"
28 #include "memory/metaspace/metaspaceCommon.hpp"
29 #include "utilities/debug.hpp"
30 #include "utilities/globalDefinitions.hpp"
31
32 class MetachunkTest;
33
34 namespace metaspace {
35 namespace internals {
36
37 class VirtualSpaceNode;
38
39 // Metachunk - Quantum of allocation from a Virtualspace
40 // Metachunks are reused (when freed are put on a global freelist) and
41 // have no permanent association to a SpaceManager.
42
43 // +--------------+ <- end --+ --+
44 // | | | |
45 // | | | free |
46 // | | | |
47 // | | | | size | capacity
48 // | | | |
49 // | | <- top -- + |
50 // | | | |
51 // | | | used |
52 // | | | |
53 // | | | |
54 // +--------------+ <- bottom --+ --+
55
56 enum ChunkOrigin {
57 // Chunk normally born (via take_from_committed)
58 origin_normal = 1,
59 // Chunk was born as padding chunk
60 origin_pad = 2,
61 // Chunk was born as leftover chunk in VirtualSpaceNode::retire
62 origin_leftover = 3,
63 // Chunk was born as result of a merge of smaller chunks
64 origin_merge = 4,
65 // Chunk was born as result of a split of a larger chunk
66 origin_split = 5,
67
68 origin_minimum = origin_normal,
69 origin_maximum = origin_split,
70 origins_count = origin_maximum + 1
71 };
72
73 inline bool is_valid_chunkorigin(ChunkOrigin origin) {
74 return origin == origin_normal ||
75 origin == origin_pad ||
76 origin == origin_leftover ||
77 origin == origin_merge ||
78 origin == origin_split;
79 }
80
81 class Metachunk : public Metabase<Metachunk> {
82
83 friend class ::MetachunkTest;
84
85 // The VirtualSpaceNode containing this chunk.
86 VirtualSpaceNode* const _container;
87
88 // Current allocation top.
89 MetaWord* _top;
90
91 // A 32bit sentinel for debugging purposes.
92 enum { CHUNK_SENTINEL = 0x4d4554EF, // "MET"
93 CHUNK_SENTINEL_INVALID = 0xFEEEEEEF
94 };
95
96 uint32_t _sentinel;
97
98 const ChunkIndex _chunk_type;
99 const bool _is_class;
100 // Whether the chunk is free (in freelist) or in use by some class loader.
101 bool _is_tagged_free;
102
103 ChunkOrigin _origin;
104 int _use_count;
144
145 void print_on(outputStream* st) const;
146
147 bool is_valid_sentinel() const { return _sentinel == CHUNK_SENTINEL; }
148 void remove_sentinel() { _sentinel = CHUNK_SENTINEL_INVALID; }
149
150 int get_use_count() const { return _use_count; }
151 void inc_use_count() { _use_count ++; }
152
153 ChunkOrigin get_origin() const { return _origin; }
154 void set_origin(ChunkOrigin orig) { _origin = orig; }
155
156 ChunkIndex get_chunk_type() const { return _chunk_type; }
157 bool is_class() const { return _is_class; }
158
159 DEBUG_ONLY(void mangle(juint word_value);)
160 DEBUG_ONLY(void verify() const;)
161
162 };
163
164
165 // Helper function that does a bunch of checks for a chunk.
166 DEBUG_ONLY(void do_verify_chunk(Metachunk* chunk);)
167
168 // Given a Metachunk, update its in-use information (both in the
169 // chunk and the occupancy map).
170 void do_update_in_use_info_for_chunk(Metachunk* chunk, bool inuse);
171
172 } // namespace metaspace
173 } // namespace internals
174
175 #endif // SHARE_VM_MEMORY_METACHUNK_HPP
|