63 class MetaWord;
64 class Mutex;
65 class outputStream;
66 class PrintCLDMetaspaceInfoClosure;
67 class SpaceManager;
68 class VirtualSpaceList;
69
70 // Metaspaces each have a SpaceManager and allocations
71 // are done by the SpaceManager. Allocations are done
72 // out of the current Metachunk. When the current Metachunk
73 // is exhausted, the SpaceManager gets a new one from
74 // the current VirtualSpace. When the VirtualSpace is exhausted
75 // the SpaceManager gets a new one. The SpaceManager
76 // also manages freelists of available Chunks.
77 //
78 // Currently the space manager maintains the list of
79 // virtual spaces and the list of chunks in use. Its
80 // allocate() method returns a block for use as a
81 // quantum of metadata.
82
83 class Metaspace : public CHeapObj<mtClass> {
84 friend class VMStructs;
85 friend class SpaceManager;
86 friend class VM_CollectForMetadataAllocation;
87 friend class MetaspaceGC;
88 friend class MetaspaceUtils;
89 friend class MetaspaceShared;
90 friend class CollectedHeap;
91 friend class PrintCLDMetaspaceInfoClosure;
92 friend class MetaspaceAllocationTest;
93
94 public:
95 enum MetadataType {
96 ClassType,
97 NonClassType,
98 MetadataTypeCount
99 };
100 enum MetaspaceType {
101 StandardMetaspaceType,
102 BootMetaspaceType,
103 AnonymousMetaspaceType,
104 ReflectionMetaspaceType
105 };
106
107 private:
108 static void verify_global_initialization();
109
110 void initialize(Mutex* lock, MetaspaceType type);
111
112 // Initialize the first chunk for a Metaspace. Used for
113 // special cases such as the boot class loader, reflection
114 // class loader and anonymous class loader.
115 void initialize_first_chunk(MetaspaceType type, MetadataType mdtype);
116 Metachunk* get_initialization_chunk(MetaspaceType type, MetadataType mdtype);
117
118 // Align up the word size to the allocation word size
119 static size_t align_word_size_up(size_t);
120
121 // Aligned size of the metaspace.
122 static size_t _compressed_class_space_size;
123
124 static size_t compressed_class_space_size() {
125 return _compressed_class_space_size;
126 }
127
128 static void set_compressed_class_space_size(size_t size) {
129 _compressed_class_space_size = size;
130 }
131
132 static size_t _first_chunk_word_size;
133 static size_t _first_class_chunk_word_size;
134
135 static size_t _commit_alignment;
136 static size_t _reserve_alignment;
137 DEBUG_ONLY(static bool _frozen;)
138
139 SpaceManager* _vsm;
140 SpaceManager* vsm() const { return _vsm; }
141
142 SpaceManager* _class_vsm;
143 SpaceManager* class_vsm() const { return _class_vsm; }
144 SpaceManager* get_space_manager(MetadataType mdtype) {
145 assert(mdtype != MetadataTypeCount, "MetadaTypeCount can't be used as mdtype");
146 return mdtype == ClassType ? class_vsm() : vsm();
147 }
148
149 // Allocate space for metadata of type mdtype. This is space
150 // within a Metachunk and is used by
151 // allocate(ClassLoaderData*, size_t, bool, MetadataType, TRAPS)
152 MetaWord* allocate(size_t word_size, MetadataType mdtype);
153
154 MetaWord* expand_and_allocate(size_t size, MetadataType mdtype);
155
156 // Virtual Space lists for both classes and other metadata
157 static VirtualSpaceList* _space_list;
158 static VirtualSpaceList* _class_space_list;
159
160 static ChunkManager* _chunk_manager_metadata;
161 static ChunkManager* _chunk_manager_class;
162
163 static const MetaspaceTracer* _tracer;
164
165 public:
166 static VirtualSpaceList* space_list() { return _space_list; }
167 static VirtualSpaceList* class_space_list() { return _class_space_list; }
168 static VirtualSpaceList* get_space_list(MetadataType mdtype) {
169 assert(mdtype != MetadataTypeCount, "MetadaTypeCount can't be used as mdtype");
170 return mdtype == ClassType ? class_space_list() : space_list();
171 }
172
173 static ChunkManager* chunk_manager_metadata() { return _chunk_manager_metadata; }
174 static ChunkManager* chunk_manager_class() { return _chunk_manager_class; }
175 static ChunkManager* get_chunk_manager(MetadataType mdtype) {
176 assert(mdtype != MetadataTypeCount, "MetadaTypeCount can't be used as mdtype");
177 return mdtype == ClassType ? chunk_manager_class() : chunk_manager_metadata();
178 }
179
180 // convenience function
181 static ChunkManager* get_chunk_manager(bool is_class) {
182 return is_class ? chunk_manager_class() : chunk_manager_metadata();
183 }
184
185 static const MetaspaceTracer* tracer() { return _tracer; }
186 static void freeze() {
187 assert(DumpSharedSpaces, "sanity");
188 DEBUG_ONLY(_frozen = true;)
189 }
190 #ifdef _LP64
191 static void allocate_metaspace_compressed_klass_ptrs(char* requested_addr, address cds_base);
192 #endif
193
194 private:
195
196 #ifdef _LP64
197 static void set_narrow_klass_base_and_shift(address metaspace_base, address cds_base);
198
199 // Returns true if can use CDS with metaspace allocated as specified address.
200 static bool can_use_cds_with_metaspace_addr(char* metaspace_base, address cds_base);
201
202 static void initialize_class_space(ReservedSpace rs);
203 #endif
204 size_t class_chunk_size(size_t word_size);
205
206 public:
207
208 Metaspace(Mutex* lock, MetaspaceType type);
209 ~Metaspace();
210
211 static void ergo_initialize();
212 static void global_initialize();
213 static void post_initialize();
214
215 static size_t first_chunk_word_size() { return _first_chunk_word_size; }
216 static size_t first_class_chunk_word_size() { return _first_class_chunk_word_size; }
217
218 static size_t reserve_alignment() { return _reserve_alignment; }
219 static size_t reserve_alignment_words() { return _reserve_alignment / BytesPerWord; }
220 static size_t commit_alignment() { return _commit_alignment; }
221 static size_t commit_alignment_words() { return _commit_alignment / BytesPerWord; }
222
223 size_t used_words_slow(MetadataType mdtype) const;
224 size_t free_words_slow(MetadataType mdtype) const;
225 size_t capacity_words_slow(MetadataType mdtype) const;
226
227 size_t used_bytes_slow(MetadataType mdtype) const;
228 size_t capacity_bytes_slow(MetadataType mdtype) const;
229
230 size_t allocated_blocks_bytes() const;
231 size_t allocated_chunks_bytes() const;
232
233 static MetaWord* allocate(ClassLoaderData* loader_data, size_t word_size,
234 MetaspaceObj::Type type, TRAPS);
235 void deallocate(MetaWord* ptr, size_t byte_size, bool is_class);
236
237 static bool contains(const void* ptr);
238 static bool contains_non_shared(const void* ptr);
239
240 void dump(outputStream* const out) const;
241
242 // Free empty virtualspaces
243 static void purge(MetadataType mdtype);
244 static void purge();
245
246 static void report_metadata_oome(ClassLoaderData* loader_data, size_t word_size,
247 MetaspaceObj::Type type, MetadataType mdtype, TRAPS);
248
249 static const char* metadata_type_name(Metaspace::MetadataType mdtype);
250
251 void print_on(outputStream* st) const;
252 // Debugging support
253 void verify();
254
255 static void print_compressed_class_space(outputStream* st, const char* requested_addr = 0) NOT_LP64({});
256
257 // Return TRUE only if UseCompressedClassPointers is True.
258 static bool using_class_space() {
259 return NOT_LP64(false) LP64_ONLY(UseCompressedClassPointers);
260 }
261
262 static bool is_class_space_allocation(MetadataType mdType) {
263 return mdType == ClassType && using_class_space();
264 }
265
266 };
267
268 class MetaspaceUtils : AllStatic {
269 static size_t free_chunks_total_words(Metaspace::MetadataType mdtype);
270
271 // These methods iterate over the classloader data graph
272 // for the given Metaspace type. These are slow.
273 static size_t used_bytes_slow(Metaspace::MetadataType mdtype);
274 static size_t free_bytes_slow(Metaspace::MetadataType mdtype);
275 static size_t capacity_bytes_slow(Metaspace::MetadataType mdtype);
276 static size_t capacity_bytes_slow();
277
278 // Running sum of space in all Metachunks that has been
279 // allocated to a Metaspace. This is used instead of
280 // iterating over all the classloaders. One for each
281 // type of Metadata
282 static size_t _capacity_words[Metaspace:: MetadataTypeCount];
283 // Running sum of space in all Metachunks that
284 // are being used for metadata. One for each
285 // type of Metadata.
286 static volatile size_t _used_words[Metaspace:: MetadataTypeCount];
|
63 class MetaWord;
64 class Mutex;
65 class outputStream;
66 class PrintCLDMetaspaceInfoClosure;
67 class SpaceManager;
68 class VirtualSpaceList;
69
70 // Metaspaces each have a SpaceManager and allocations
71 // are done by the SpaceManager. Allocations are done
72 // out of the current Metachunk. When the current Metachunk
73 // is exhausted, the SpaceManager gets a new one from
74 // the current VirtualSpace. When the VirtualSpace is exhausted
75 // the SpaceManager gets a new one. The SpaceManager
76 // also manages freelists of available Chunks.
77 //
78 // Currently the space manager maintains the list of
79 // virtual spaces and the list of chunks in use. Its
80 // allocate() method returns a block for use as a
81 // quantum of metadata.
82
83 // Namespace for important central static functions
84 // (auxiliary stuff goes into MetaspaceUtils)
85 class Metaspace : public AllStatic {
86 /* friend class VMStructs;
87 friend class SpaceManager;
88 friend class VM_CollectForMetadataAllocation;
89 friend class MetaspaceGC;
90 friend class MetaspaceUtils;
91
92 friend class CollectedHeap;
93 friend class PrintCLDMetaspaceInfoClosure;
94 friend class MetaspaceAllocationTest;
95 */
96 friend class MetaspaceShared;
97
98
99 public:
100 enum MetadataType {
101 ClassType,
102 NonClassType,
103 MetadataTypeCount
104 };
105 enum MetaspaceType {
106 StandardMetaspaceType,
107 BootMetaspaceType,
108 AnonymousMetaspaceType,
109 ReflectionMetaspaceType
110 };
111
112 private:
113
114 // Align up the word size to the allocation word size
115 static size_t align_word_size_up(size_t);
116
117 // Aligned size of the metaspace.
118 static size_t _compressed_class_space_size;
119
120 static size_t compressed_class_space_size() {
121 return _compressed_class_space_size;
122 }
123
124 static void set_compressed_class_space_size(size_t size) {
125 _compressed_class_space_size = size;
126 }
127
128 static size_t _first_chunk_word_size;
129 static size_t _first_class_chunk_word_size;
130
131 static size_t _commit_alignment;
132 static size_t _reserve_alignment;
133 DEBUG_ONLY(static bool _frozen;)
134
135 // Virtual Space lists for both classes and other metadata
136 static VirtualSpaceList* _space_list;
137 static VirtualSpaceList* _class_space_list;
138
139 static ChunkManager* _chunk_manager_metadata;
140 static ChunkManager* _chunk_manager_class;
141
142 static const MetaspaceTracer* _tracer;
143
144 public:
145 static VirtualSpaceList* space_list() { return _space_list; }
146 static VirtualSpaceList* class_space_list() { return _class_space_list; }
147 static VirtualSpaceList* get_space_list(MetadataType mdtype) {
148 assert(mdtype != MetadataTypeCount, "MetadaTypeCount can't be used as mdtype");
149 return mdtype == ClassType ? class_space_list() : space_list();
150 }
151
152 static ChunkManager* chunk_manager_metadata() { return _chunk_manager_metadata; }
153 static ChunkManager* chunk_manager_class() { return _chunk_manager_class; }
154 static ChunkManager* get_chunk_manager(MetadataType mdtype) {
155 assert(mdtype != MetadataTypeCount, "MetadaTypeCount can't be used as mdtype");
156 return mdtype == ClassType ? chunk_manager_class() : chunk_manager_metadata();
157 }
158
159 // convenience function
160 static ChunkManager* get_chunk_manager(bool is_class) {
161 return is_class ? chunk_manager_class() : chunk_manager_metadata();
162 }
163
164 static const MetaspaceTracer* tracer() { return _tracer; }
165 static void freeze() {
166 assert(DumpSharedSpaces, "sanity");
167 DEBUG_ONLY(_frozen = true;)
168 }
169 static void assert_not_frozen() {
170 assert(!_frozen, "sanity");
171 }
172 #ifdef _LP64
173 static void allocate_metaspace_compressed_klass_ptrs(char* requested_addr, address cds_base);
174 #endif
175
176 private:
177
178 #ifdef _LP64
179 static void set_narrow_klass_base_and_shift(address metaspace_base, address cds_base);
180
181 // Returns true if can use CDS with metaspace allocated as specified address.
182 static bool can_use_cds_with_metaspace_addr(char* metaspace_base, address cds_base);
183
184 static void initialize_class_space(ReservedSpace rs);
185 #endif
186
187 public:
188
189 static void ergo_initialize();
190 static void global_initialize();
191 static void post_initialize();
192
193 static void verify_global_initialization();
194
195 static size_t first_chunk_word_size() { return _first_chunk_word_size; }
196 static size_t first_class_chunk_word_size() { return _first_class_chunk_word_size; }
197
198 static size_t reserve_alignment() { return _reserve_alignment; }
199 static size_t reserve_alignment_words() { return _reserve_alignment / BytesPerWord; }
200 static size_t commit_alignment() { return _commit_alignment; }
201 static size_t commit_alignment_words() { return _commit_alignment / BytesPerWord; }
202
203 static MetaWord* allocate(ClassLoaderData* loader_data, size_t word_size,
204 MetaspaceObj::Type type, TRAPS);
205 void deallocate(MetaWord* ptr, size_t byte_size, bool is_class);
206
207 static bool contains(const void* ptr);
208 static bool contains_non_shared(const void* ptr);
209
210 // Free empty virtualspaces
211 static void purge(MetadataType mdtype);
212 static void purge();
213
214 static void report_metadata_oome(ClassLoaderData* loader_data, size_t word_size,
215 MetaspaceObj::Type type, MetadataType mdtype, TRAPS);
216
217 static const char* metadata_type_name(Metaspace::MetadataType mdtype);
218
219 static void print_compressed_class_space(outputStream* st, const char* requested_addr = 0) NOT_LP64({});
220
221 // Return TRUE only if UseCompressedClassPointers is True.
222 static bool using_class_space() {
223 return NOT_LP64(false) LP64_ONLY(UseCompressedClassPointers);
224 }
225
226 static bool is_class_space_allocation(MetadataType mdType) {
227 return mdType == ClassType && using_class_space();
228 }
229
230 };
231
232 // Manages the metaspace portion belonging to a class loader
233 class ClassLoaderMetaspace : public CHeapObj<mtClass> {
234 /* friend class VMStructs;
235 friend class SpaceManager;
236 friend class VM_CollectForMetadataAllocation;
237 friend class MetaspaceGC;
238
239 friend class MetaspaceShared;
240
241 friend class PrintCLDMetaspaceInfoClosure;
242 friend class MetaspaceAllocationTest;
243 */
244
245 friend class CollectedHeap; // For expand_and_allocate()
246 friend class Metaspace;
247 friend class MetaspaceUtils;
248 friend class PrintCLDMetaspaceInfoClosure;
249 friend class VM_CollectForMetadataAllocation; // For expand_and_allocate()
250
251 private:
252
253 void initialize(Mutex* lock, Metaspace::MetaspaceType type);
254
255 // Initialize the first chunk for a Metaspace. Used for
256 // special cases such as the boot class loader, reflection
257 // class loader and anonymous class loader.
258 void initialize_first_chunk(Metaspace::MetaspaceType type, Metaspace::MetadataType mdtype);
259 Metachunk* get_initialization_chunk(Metaspace::MetaspaceType type, Metaspace::MetadataType mdtype);
260
261 SpaceManager* _vsm;
262 SpaceManager* vsm() const { return _vsm; }
263
264 SpaceManager* _class_vsm;
265 SpaceManager* class_vsm() const { return _class_vsm; }
266 SpaceManager* get_space_manager(Metaspace::MetadataType mdtype) {
267 assert(mdtype != Metaspace::MetadataTypeCount, "MetadaTypeCount can't be used as mdtype");
268 return mdtype == Metaspace::ClassType ? class_vsm() : vsm();
269 }
270
271 MetaWord* expand_and_allocate(size_t size, Metaspace::MetadataType mdtype);
272
273 size_t class_chunk_size(size_t word_size);
274
275 public:
276
277 ClassLoaderMetaspace(Mutex* lock, Metaspace::MetaspaceType type);
278 ~ClassLoaderMetaspace();
279
280 // Allocate space for metadata of type mdtype. This is space
281 // within a Metachunk and is used by
282 // allocate(ClassLoaderData*, size_t, bool, MetadataType, TRAPS)
283 MetaWord* allocate(size_t word_size, Metaspace::MetadataType mdtype);
284
285 size_t used_words_slow(Metaspace::MetadataType mdtype) const;
286 size_t free_words_slow(Metaspace::MetadataType mdtype) const;
287 size_t capacity_words_slow(Metaspace::MetadataType mdtype) const;
288
289 size_t used_bytes_slow(Metaspace::MetadataType mdtype) const;
290 size_t capacity_bytes_slow(Metaspace::MetadataType mdtype) const;
291
292 size_t allocated_blocks_bytes() const;
293 size_t allocated_chunks_bytes() const;
294
295 void deallocate(MetaWord* ptr, size_t byte_size, bool is_class);
296
297 void dump(outputStream* const out) const;
298
299 void print_on(outputStream* st) const;
300 // Debugging support
301 void verify();
302
303 }; // ClassLoaderMetaspace
304
305
306 class MetaspaceUtils : AllStatic {
307 static size_t free_chunks_total_words(Metaspace::MetadataType mdtype);
308
309 // These methods iterate over the classloader data graph
310 // for the given Metaspace type. These are slow.
311 static size_t used_bytes_slow(Metaspace::MetadataType mdtype);
312 static size_t free_bytes_slow(Metaspace::MetadataType mdtype);
313 static size_t capacity_bytes_slow(Metaspace::MetadataType mdtype);
314 static size_t capacity_bytes_slow();
315
316 // Running sum of space in all Metachunks that has been
317 // allocated to a Metaspace. This is used instead of
318 // iterating over all the classloaders. One for each
319 // type of Metadata
320 static size_t _capacity_words[Metaspace:: MetadataTypeCount];
321 // Running sum of space in all Metachunks that
322 // are being used for metadata. One for each
323 // type of Metadata.
324 static volatile size_t _used_words[Metaspace:: MetadataTypeCount];
|