Mercurial > hg > graal-jvmci-8
comparison src/share/vm/memory/metaspace.hpp @ 14422:2b8e28fdf503
Merge
author | kvn |
---|---|
date | Tue, 05 Nov 2013 17:38:04 -0800 |
parents | 209aa13ab8c0 |
children | ce86c36b8921 15120a36272d |
comparison
equal
deleted
inserted
replaced
14421:3068270ba476 | 14422:2b8e28fdf503 |
---|---|
54 // | | | 54 // | | |
55 // | | | 55 // | | |
56 // +-------------------+ | 56 // +-------------------+ |
57 // | 57 // |
58 | 58 |
59 class ChunkManager; | |
59 class ClassLoaderData; | 60 class ClassLoaderData; |
60 class Metablock; | 61 class Metablock; |
62 class Metachunk; | |
61 class MetaWord; | 63 class MetaWord; |
62 class Mutex; | 64 class Mutex; |
63 class outputStream; | 65 class outputStream; |
64 class SpaceManager; | 66 class SpaceManager; |
67 class VirtualSpaceList; | |
65 | 68 |
66 // Metaspaces each have a SpaceManager and allocations | 69 // Metaspaces each have a SpaceManager and allocations |
67 // are done by the SpaceManager. Allocations are done | 70 // are done by the SpaceManager. Allocations are done |
68 // out of the current Metachunk. When the current Metachunk | 71 // out of the current Metachunk. When the current Metachunk |
69 // is exhausted, the SpaceManager gets a new one from | 72 // is exhausted, the SpaceManager gets a new one from |
74 // Currently the space manager maintains the list of | 77 // Currently the space manager maintains the list of |
75 // virtual spaces and the list of chunks in use. Its | 78 // virtual spaces and the list of chunks in use. Its |
76 // allocate() method returns a block for use as a | 79 // allocate() method returns a block for use as a |
77 // quantum of metadata. | 80 // quantum of metadata. |
78 | 81 |
79 class VirtualSpaceList; | |
80 | |
81 class Metaspace : public CHeapObj<mtClass> { | 82 class Metaspace : public CHeapObj<mtClass> { |
82 friend class VMStructs; | 83 friend class VMStructs; |
83 friend class SpaceManager; | 84 friend class SpaceManager; |
84 friend class VM_CollectForMetadataAllocation; | 85 friend class VM_CollectForMetadataAllocation; |
85 friend class MetaspaceGC; | 86 friend class MetaspaceGC; |
86 friend class MetaspaceAux; | 87 friend class MetaspaceAux; |
87 | 88 |
88 public: | 89 public: |
89 enum MetadataType {ClassType = 0, | 90 enum MetadataType { |
90 NonClassType = ClassType + 1, | 91 ClassType, |
91 MetadataTypeCount = ClassType + 2 | 92 NonClassType, |
93 MetadataTypeCount | |
92 }; | 94 }; |
93 enum MetaspaceType { | 95 enum MetaspaceType { |
94 StandardMetaspaceType, | 96 StandardMetaspaceType, |
95 BootMetaspaceType, | 97 BootMetaspaceType, |
96 ROMetaspaceType, | 98 ROMetaspaceType, |
100 }; | 102 }; |
101 | 103 |
102 private: | 104 private: |
103 void initialize(Mutex* lock, MetaspaceType type); | 105 void initialize(Mutex* lock, MetaspaceType type); |
104 | 106 |
107 // Get the first chunk for a Metaspace. Used for | |
108 // special cases such as the boot class loader, reflection | |
109 // class loader and anonymous class loader. | |
110 Metachunk* get_initialization_chunk(MetadataType mdtype, | |
111 size_t chunk_word_size, | |
112 size_t chunk_bunch); | |
113 | |
105 // Align up the word size to the allocation word size | 114 // Align up the word size to the allocation word size |
106 static size_t align_word_size_up(size_t); | 115 static size_t align_word_size_up(size_t); |
107 | 116 |
108 // Aligned size of the metaspace. | 117 // Aligned size of the metaspace. |
109 static size_t _class_metaspace_size; | 118 static size_t _compressed_class_space_size; |
110 | 119 |
111 static size_t class_metaspace_size() { | 120 static size_t compressed_class_space_size() { |
112 return _class_metaspace_size; | 121 return _compressed_class_space_size; |
113 } | 122 } |
114 static void set_class_metaspace_size(size_t metaspace_size) { | 123 static void set_compressed_class_space_size(size_t size) { |
115 _class_metaspace_size = metaspace_size; | 124 _compressed_class_space_size = size; |
116 } | 125 } |
117 | 126 |
118 static size_t _first_chunk_word_size; | 127 static size_t _first_chunk_word_size; |
119 static size_t _first_class_chunk_word_size; | 128 static size_t _first_class_chunk_word_size; |
129 | |
130 static size_t _commit_alignment; | |
131 static size_t _reserve_alignment; | |
120 | 132 |
121 SpaceManager* _vsm; | 133 SpaceManager* _vsm; |
122 SpaceManager* vsm() const { return _vsm; } | 134 SpaceManager* vsm() const { return _vsm; } |
123 | 135 |
124 SpaceManager* _class_vsm; | 136 SpaceManager* _class_vsm; |
125 SpaceManager* class_vsm() const { return _class_vsm; } | 137 SpaceManager* class_vsm() const { return _class_vsm; } |
126 | 138 |
127 // Allocate space for metadata of type mdtype. This is space | 139 // Allocate space for metadata of type mdtype. This is space |
128 // within a Metachunk and is used by | 140 // within a Metachunk and is used by |
129 // allocate(ClassLoaderData*, size_t, bool, MetadataType, TRAPS) | 141 // allocate(ClassLoaderData*, size_t, bool, MetadataType, TRAPS) |
130 // which returns a Metablock. | |
131 MetaWord* allocate(size_t word_size, MetadataType mdtype); | 142 MetaWord* allocate(size_t word_size, MetadataType mdtype); |
132 | 143 |
133 // Virtual Space lists for both classes and other metadata | 144 // Virtual Space lists for both classes and other metadata |
134 static VirtualSpaceList* _space_list; | 145 static VirtualSpaceList* _space_list; |
135 static VirtualSpaceList* _class_space_list; | 146 static VirtualSpaceList* _class_space_list; |
136 | 147 |
148 static ChunkManager* _chunk_manager_metadata; | |
149 static ChunkManager* _chunk_manager_class; | |
150 | |
151 public: | |
137 static VirtualSpaceList* space_list() { return _space_list; } | 152 static VirtualSpaceList* space_list() { return _space_list; } |
138 static VirtualSpaceList* class_space_list() { return _class_space_list; } | 153 static VirtualSpaceList* class_space_list() { return _class_space_list; } |
139 static VirtualSpaceList* get_space_list(MetadataType mdtype) { | 154 static VirtualSpaceList* get_space_list(MetadataType mdtype) { |
140 assert(mdtype != MetadataTypeCount, "MetadaTypeCount can't be used as mdtype"); | 155 assert(mdtype != MetadataTypeCount, "MetadaTypeCount can't be used as mdtype"); |
141 return mdtype == ClassType ? class_space_list() : space_list(); | 156 return mdtype == ClassType ? class_space_list() : space_list(); |
142 } | 157 } |
143 | 158 |
159 static ChunkManager* chunk_manager_metadata() { return _chunk_manager_metadata; } | |
160 static ChunkManager* chunk_manager_class() { return _chunk_manager_class; } | |
161 static ChunkManager* get_chunk_manager(MetadataType mdtype) { | |
162 assert(mdtype != MetadataTypeCount, "MetadaTypeCount can't be used as mdtype"); | |
163 return mdtype == ClassType ? chunk_manager_class() : chunk_manager_metadata(); | |
164 } | |
165 | |
166 private: | |
144 // This is used by DumpSharedSpaces only, where only _vsm is used. So we will | 167 // This is used by DumpSharedSpaces only, where only _vsm is used. So we will |
145 // maintain a single list for now. | 168 // maintain a single list for now. |
146 void record_allocation(void* ptr, MetaspaceObj::Type type, size_t word_size); | 169 void record_allocation(void* ptr, MetaspaceObj::Type type, size_t word_size); |
147 | 170 |
148 #ifdef _LP64 | 171 #ifdef _LP64 |
167 }; | 190 }; |
168 | 191 |
169 AllocRecord * _alloc_record_head; | 192 AllocRecord * _alloc_record_head; |
170 AllocRecord * _alloc_record_tail; | 193 AllocRecord * _alloc_record_tail; |
171 | 194 |
195 size_t class_chunk_size(size_t word_size); | |
196 | |
172 public: | 197 public: |
173 | 198 |
174 Metaspace(Mutex* lock, MetaspaceType type); | 199 Metaspace(Mutex* lock, MetaspaceType type); |
175 ~Metaspace(); | 200 ~Metaspace(); |
176 | 201 |
177 // Initialize globals for Metaspace | 202 static void ergo_initialize(); |
178 static void global_initialize(); | 203 static void global_initialize(); |
179 | 204 |
180 static size_t first_chunk_word_size() { return _first_chunk_word_size; } | 205 static size_t first_chunk_word_size() { return _first_chunk_word_size; } |
181 static size_t first_class_chunk_word_size() { return _first_class_chunk_word_size; } | 206 static size_t first_class_chunk_word_size() { return _first_class_chunk_word_size; } |
182 | 207 |
208 static size_t reserve_alignment() { return _reserve_alignment; } | |
209 static size_t reserve_alignment_words() { return _reserve_alignment / BytesPerWord; } | |
210 static size_t commit_alignment() { return _commit_alignment; } | |
211 static size_t commit_alignment_words() { return _commit_alignment / BytesPerWord; } | |
212 | |
183 char* bottom() const; | 213 char* bottom() const; |
184 size_t used_words_slow(MetadataType mdtype) const; | 214 size_t used_words_slow(MetadataType mdtype) const; |
185 size_t free_words(MetadataType mdtype) const; | 215 size_t free_words_slow(MetadataType mdtype) const; |
186 size_t capacity_words_slow(MetadataType mdtype) const; | 216 size_t capacity_words_slow(MetadataType mdtype) const; |
187 size_t waste_words(MetadataType mdtype) const; | |
188 | 217 |
189 size_t used_bytes_slow(MetadataType mdtype) const; | 218 size_t used_bytes_slow(MetadataType mdtype) const; |
190 size_t capacity_bytes_slow(MetadataType mdtype) const; | 219 size_t capacity_bytes_slow(MetadataType mdtype) const; |
191 | 220 |
192 static Metablock* allocate(ClassLoaderData* loader_data, size_t word_size, | 221 static MetaWord* allocate(ClassLoaderData* loader_data, size_t word_size, |
193 bool read_only, MetaspaceObj::Type type, TRAPS); | 222 bool read_only, MetaspaceObj::Type type, TRAPS); |
194 void deallocate(MetaWord* ptr, size_t byte_size, bool is_class); | 223 void deallocate(MetaWord* ptr, size_t byte_size, bool is_class); |
195 | 224 |
196 MetaWord* expand_and_allocate(size_t size, | 225 MetaWord* expand_and_allocate(size_t size, |
197 MetadataType mdtype); | 226 MetadataType mdtype); |
198 | 227 |
199 static bool contains(const void *ptr); | 228 static bool contains(const void *ptr); |
200 void dump(outputStream* const out) const; | 229 void dump(outputStream* const out) const; |
201 | 230 |
202 // Free empty virtualspaces | 231 // Free empty virtualspaces |
232 static void purge(MetadataType mdtype); | |
203 static void purge(); | 233 static void purge(); |
234 | |
235 static void report_metadata_oome(ClassLoaderData* loader_data, size_t word_size, | |
236 MetadataType mdtype, TRAPS); | |
204 | 237 |
205 void print_on(outputStream* st) const; | 238 void print_on(outputStream* st) const; |
206 // Debugging support | 239 // Debugging support |
207 void verify(); | 240 void verify(); |
208 | 241 |
211 virtual void doit(address ptr, MetaspaceObj::Type type, int byte_size) = 0; | 244 virtual void doit(address ptr, MetaspaceObj::Type type, int byte_size) = 0; |
212 }; | 245 }; |
213 | 246 |
214 void iterate(AllocRecordClosure *closure); | 247 void iterate(AllocRecordClosure *closure); |
215 | 248 |
216 // Return TRUE only if UseCompressedKlassPointers is True and DumpSharedSpaces is False. | 249 // Return TRUE only if UseCompressedClassPointers is True and DumpSharedSpaces is False. |
217 static bool using_class_space() { | 250 static bool using_class_space() { |
218 return NOT_LP64(false) LP64_ONLY(UseCompressedKlassPointers && !DumpSharedSpaces); | 251 return NOT_LP64(false) LP64_ONLY(UseCompressedClassPointers && !DumpSharedSpaces); |
252 } | |
253 | |
254 static bool is_class_space_allocation(MetadataType mdType) { | |
255 return mdType == ClassType && using_class_space(); | |
219 } | 256 } |
220 | 257 |
221 }; | 258 }; |
222 | 259 |
223 class MetaspaceAux : AllStatic { | 260 class MetaspaceAux : AllStatic { |
224 static size_t free_chunks_total(Metaspace::MetadataType mdtype); | 261 static size_t free_chunks_total_words(Metaspace::MetadataType mdtype); |
225 | |
226 public: | |
227 // Statistics for class space and data space in metaspace. | |
228 | 262 |
229 // These methods iterate over the classloader data graph | 263 // These methods iterate over the classloader data graph |
230 // for the given Metaspace type. These are slow. | 264 // for the given Metaspace type. These are slow. |
231 static size_t used_bytes_slow(Metaspace::MetadataType mdtype); | 265 static size_t used_bytes_slow(Metaspace::MetadataType mdtype); |
232 static size_t free_in_bytes(Metaspace::MetadataType mdtype); | 266 static size_t free_bytes_slow(Metaspace::MetadataType mdtype); |
233 static size_t capacity_bytes_slow(Metaspace::MetadataType mdtype); | 267 static size_t capacity_bytes_slow(Metaspace::MetadataType mdtype); |
234 | 268 static size_t capacity_bytes_slow(); |
235 // Iterates over the virtual space list. | |
236 static size_t reserved_in_bytes(Metaspace::MetadataType mdtype); | |
237 | 269 |
238 // Running sum of space in all Metachunks that has been | 270 // Running sum of space in all Metachunks that has been |
239 // allocated to a Metaspace. This is used instead of | 271 // allocated to a Metaspace. This is used instead of |
240 // iterating over all the classloaders. One for each | 272 // iterating over all the classloaders. One for each |
241 // type of Metadata | 273 // type of Metadata |
261 return used_bytes_slow(Metaspace::ClassType) + | 293 return used_bytes_slow(Metaspace::ClassType) + |
262 used_bytes_slow(Metaspace::NonClassType); | 294 used_bytes_slow(Metaspace::NonClassType); |
263 } | 295 } |
264 | 296 |
265 // Used by MetaspaceCounters | 297 // Used by MetaspaceCounters |
266 static size_t free_chunks_total(); | 298 static size_t free_chunks_total_words(); |
267 static size_t free_chunks_total_in_bytes(); | 299 static size_t free_chunks_total_bytes(); |
268 static size_t free_chunks_total_in_bytes(Metaspace::MetadataType mdtype); | 300 static size_t free_chunks_total_bytes(Metaspace::MetadataType mdtype); |
269 | 301 |
270 static size_t allocated_capacity_words(Metaspace::MetadataType mdtype) { | 302 static size_t allocated_capacity_words(Metaspace::MetadataType mdtype) { |
271 return _allocated_capacity_words[mdtype]; | 303 return _allocated_capacity_words[mdtype]; |
272 } | 304 } |
273 static size_t allocated_capacity_words() { | 305 static size_t allocated_capacity_words() { |
274 return _allocated_capacity_words[Metaspace::NonClassType] + | 306 return allocated_capacity_words(Metaspace::NonClassType) + |
275 (Metaspace::using_class_space() ? | 307 allocated_capacity_words(Metaspace::ClassType); |
276 _allocated_capacity_words[Metaspace::ClassType] : 0); | |
277 } | 308 } |
278 static size_t allocated_capacity_bytes(Metaspace::MetadataType mdtype) { | 309 static size_t allocated_capacity_bytes(Metaspace::MetadataType mdtype) { |
279 return allocated_capacity_words(mdtype) * BytesPerWord; | 310 return allocated_capacity_words(mdtype) * BytesPerWord; |
280 } | 311 } |
281 static size_t allocated_capacity_bytes() { | 312 static size_t allocated_capacity_bytes() { |
284 | 315 |
285 static size_t allocated_used_words(Metaspace::MetadataType mdtype) { | 316 static size_t allocated_used_words(Metaspace::MetadataType mdtype) { |
286 return _allocated_used_words[mdtype]; | 317 return _allocated_used_words[mdtype]; |
287 } | 318 } |
288 static size_t allocated_used_words() { | 319 static size_t allocated_used_words() { |
289 return _allocated_used_words[Metaspace::NonClassType] + | 320 return allocated_used_words(Metaspace::NonClassType) + |
290 (Metaspace::using_class_space() ? | 321 allocated_used_words(Metaspace::ClassType); |
291 _allocated_used_words[Metaspace::ClassType] : 0); | |
292 } | 322 } |
293 static size_t allocated_used_bytes(Metaspace::MetadataType mdtype) { | 323 static size_t allocated_used_bytes(Metaspace::MetadataType mdtype) { |
294 return allocated_used_words(mdtype) * BytesPerWord; | 324 return allocated_used_words(mdtype) * BytesPerWord; |
295 } | 325 } |
296 static size_t allocated_used_bytes() { | 326 static size_t allocated_used_bytes() { |
298 } | 328 } |
299 | 329 |
300 static size_t free_bytes(); | 330 static size_t free_bytes(); |
301 static size_t free_bytes(Metaspace::MetadataType mdtype); | 331 static size_t free_bytes(Metaspace::MetadataType mdtype); |
302 | 332 |
303 // Total capacity in all Metaspaces | 333 static size_t reserved_bytes(Metaspace::MetadataType mdtype); |
304 static size_t capacity_bytes_slow() { | 334 static size_t reserved_bytes() { |
305 #ifdef PRODUCT | 335 return reserved_bytes(Metaspace::ClassType) + |
306 // Use allocated_capacity_bytes() in PRODUCT instead of this function. | 336 reserved_bytes(Metaspace::NonClassType); |
307 guarantee(false, "Should not call capacity_bytes_slow() in the PRODUCT"); | 337 } |
308 #endif | 338 |
309 size_t class_capacity = capacity_bytes_slow(Metaspace::ClassType); | 339 static size_t committed_bytes(Metaspace::MetadataType mdtype); |
310 size_t non_class_capacity = capacity_bytes_slow(Metaspace::NonClassType); | 340 static size_t committed_bytes() { |
311 assert(allocated_capacity_bytes() == class_capacity + non_class_capacity, | 341 return committed_bytes(Metaspace::ClassType) + |
312 err_msg("bad accounting: allocated_capacity_bytes() " SIZE_FORMAT | 342 committed_bytes(Metaspace::NonClassType); |
313 " class_capacity + non_class_capacity " SIZE_FORMAT | 343 } |
314 " class_capacity " SIZE_FORMAT " non_class_capacity " SIZE_FORMAT, | 344 |
315 allocated_capacity_bytes(), class_capacity + non_class_capacity, | 345 static size_t min_chunk_size_words(); |
316 class_capacity, non_class_capacity)); | 346 static size_t min_chunk_size_bytes() { |
317 | 347 return min_chunk_size_words() * BytesPerWord; |
318 return class_capacity + non_class_capacity; | 348 } |
319 } | |
320 | |
321 // Total space reserved in all Metaspaces | |
322 static size_t reserved_in_bytes() { | |
323 return reserved_in_bytes(Metaspace::ClassType) + | |
324 reserved_in_bytes(Metaspace::NonClassType); | |
325 } | |
326 | |
327 static size_t min_chunk_size(); | |
328 | 349 |
329 // Print change in used metadata. | 350 // Print change in used metadata. |
330 static void print_metaspace_change(size_t prev_metadata_used); | 351 static void print_metaspace_change(size_t prev_metadata_used); |
331 static void print_on(outputStream * out); | 352 static void print_on(outputStream * out); |
332 static void print_on(outputStream * out, Metaspace::MetadataType mdtype); | 353 static void print_on(outputStream * out, Metaspace::MetadataType mdtype); |
346 // This class implements a policy for inducing GC's to recover | 367 // This class implements a policy for inducing GC's to recover |
347 // Metaspaces. | 368 // Metaspaces. |
348 | 369 |
349 class MetaspaceGC : AllStatic { | 370 class MetaspaceGC : AllStatic { |
350 | 371 |
351 // The current high-water-mark for inducing a GC. When | 372 // The current high-water-mark for inducing a GC. |
352 // the capacity of all space in the virtual lists reaches this value, | 373 // When committed memory of all metaspaces reaches this value, |
353 // a GC is induced and the value is increased. This should be changed | 374 // a GC is induced and the value is increased. Size is in bytes. |
354 // to the space actually used for allocations to avoid affects of | 375 static volatile intptr_t _capacity_until_GC; |
355 // fragmentation losses to partially used chunks. Size is in words. | |
356 static size_t _capacity_until_GC; | |
357 | |
358 // After a GC is done any allocation that fails should try to expand | |
359 // the capacity of the Metaspaces. This flag is set during attempts | |
360 // to allocate in the VMGCOperation that does the GC. | |
361 static bool _expand_after_GC; | |
362 | 376 |
363 // For a CMS collection, signal that a concurrent collection should | 377 // For a CMS collection, signal that a concurrent collection should |
364 // be started. | 378 // be started. |
365 static bool _should_concurrent_collect; | 379 static bool _should_concurrent_collect; |
366 | 380 |
367 static uint _shrink_factor; | 381 static uint _shrink_factor; |
368 | 382 |
369 static void set_capacity_until_GC(size_t v) { _capacity_until_GC = v; } | |
370 | |
371 static size_t shrink_factor() { return _shrink_factor; } | 383 static size_t shrink_factor() { return _shrink_factor; } |
372 void set_shrink_factor(uint v) { _shrink_factor = v; } | 384 void set_shrink_factor(uint v) { _shrink_factor = v; } |
373 | 385 |
374 public: | 386 public: |
375 | 387 |
376 static size_t capacity_until_GC() { return _capacity_until_GC; } | 388 static void initialize() { _capacity_until_GC = MetaspaceSize; } |
377 static void inc_capacity_until_GC(size_t v) { _capacity_until_GC += v; } | 389 |
378 static void dec_capacity_until_GC(size_t v) { | 390 static size_t capacity_until_GC(); |
379 _capacity_until_GC = _capacity_until_GC > v ? _capacity_until_GC - v : 0; | 391 static size_t inc_capacity_until_GC(size_t v); |
380 } | 392 static size_t dec_capacity_until_GC(size_t v); |
381 static bool expand_after_GC() { return _expand_after_GC; } | |
382 static void set_expand_after_GC(bool v) { _expand_after_GC = v; } | |
383 | 393 |
384 static bool should_concurrent_collect() { return _should_concurrent_collect; } | 394 static bool should_concurrent_collect() { return _should_concurrent_collect; } |
385 static void set_should_concurrent_collect(bool v) { | 395 static void set_should_concurrent_collect(bool v) { |
386 _should_concurrent_collect = v; | 396 _should_concurrent_collect = v; |
387 } | 397 } |
388 | 398 |
389 // The amount to increase the high-water-mark (_capacity_until_GC) | 399 // The amount to increase the high-water-mark (_capacity_until_GC) |
390 static size_t delta_capacity_until_GC(size_t word_size); | 400 static size_t delta_capacity_until_GC(size_t bytes); |
391 | 401 |
392 // It is expected that this will be called when the current capacity | 402 // Tells if we have can expand metaspace without hitting set limits. |
393 // has been used and a GC should be considered. | 403 static bool can_expand(size_t words, bool is_class); |
394 static bool should_expand(VirtualSpaceList* vsl, size_t word_size); | 404 |
405 // Returns amount that we can expand without hitting a GC, | |
406 // measured in words. | |
407 static size_t allowed_expansion(); | |
395 | 408 |
396 // Calculate the new high-water mark at which to induce | 409 // Calculate the new high-water mark at which to induce |
397 // a GC. | 410 // a GC. |
398 static void compute_new_size(); | 411 static void compute_new_size(); |
399 }; | 412 }; |