Mercurial > hg > truffle
comparison src/share/vm/oops/instanceMirrorKlass.cpp @ 6725:da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes
Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland
Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com>
author | coleenp |
---|---|
date | Sat, 01 Sep 2012 13:25:18 -0400 |
parents | e5928e7dab26 |
children | aed758eda82a |
comparison
equal
deleted
inserted
replaced
6724:36d1d483d5d6 | 6725:da91efe96a93 |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
27 #include "classfile/systemDictionary.hpp" | 27 #include "classfile/systemDictionary.hpp" |
28 #include "gc_implementation/shared/markSweep.inline.hpp" | 28 #include "gc_implementation/shared/markSweep.inline.hpp" |
29 #include "gc_interface/collectedHeap.inline.hpp" | 29 #include "gc_interface/collectedHeap.inline.hpp" |
30 #include "memory/genOopClosures.inline.hpp" | 30 #include "memory/genOopClosures.inline.hpp" |
31 #include "memory/oopFactory.hpp" | 31 #include "memory/oopFactory.hpp" |
32 #include "memory/permGen.hpp" | |
33 #include "oops/instanceKlass.hpp" | 32 #include "oops/instanceKlass.hpp" |
34 #include "oops/instanceMirrorKlass.hpp" | 33 #include "oops/instanceMirrorKlass.hpp" |
35 #include "oops/instanceOop.hpp" | 34 #include "oops/instanceOop.hpp" |
36 #include "oops/oop.inline.hpp" | 35 #include "oops/oop.inline.hpp" |
37 #include "oops/symbol.hpp" | 36 #include "oops/symbol.hpp" |
38 #include "runtime/handles.inline.hpp" | 37 #include "runtime/handles.inline.hpp" |
39 #ifndef SERIALGC | 38 #ifndef SERIALGC |
39 #include "gc_implementation/concurrentMarkSweep/cmsOopClosures.inline.hpp" | |
40 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" | 40 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" |
41 #include "gc_implementation/g1/g1OopClosures.inline.hpp" | 41 #include "gc_implementation/g1/g1OopClosures.inline.hpp" |
42 #include "gc_implementation/g1/g1RemSet.inline.hpp" | 42 #include "gc_implementation/g1/g1RemSet.inline.hpp" |
43 #include "gc_implementation/g1/heapRegionSeq.inline.hpp" | 43 #include "gc_implementation/g1/heapRegionSeq.inline.hpp" |
44 #include "gc_implementation/parNew/parOopClosures.inline.hpp" | 44 #include "gc_implementation/parNew/parOopClosures.inline.hpp" |
147 } \ | 147 } \ |
148 } | 148 } |
149 | 149 |
150 | 150 |
151 void instanceMirrorKlass::oop_follow_contents(oop obj) { | 151 void instanceMirrorKlass::oop_follow_contents(oop obj) { |
152 instanceKlass::oop_follow_contents(obj); | 152 InstanceKlass::oop_follow_contents(obj); |
153 | |
154 // Follow the klass field in the mirror. | |
155 Klass* klass = java_lang_Class::as_Klass(obj); | |
156 if (klass != NULL) { | |
157 MarkSweep::follow_klass(klass); | |
158 } else { | |
159 // If klass is NULL then this a mirror for a primitive type. | |
160 // We don't have to follow them, since they are handled as strong | |
161 // roots in Universe::oops_do. | |
162 assert(java_lang_Class::is_primitive(obj), "Sanity check"); | |
163 } | |
164 | |
153 InstanceMirrorKlass_OOP_ITERATE( \ | 165 InstanceMirrorKlass_OOP_ITERATE( \ |
154 start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj), \ | 166 start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj), \ |
155 MarkSweep::mark_and_push(p), \ | 167 MarkSweep::mark_and_push(p), \ |
156 assert_is_in_closed_subset) | 168 assert_is_in_closed_subset) |
157 } | 169 } |
158 | 170 |
159 #ifndef SERIALGC | 171 #ifndef SERIALGC |
160 void instanceMirrorKlass::oop_follow_contents(ParCompactionManager* cm, | 172 void instanceMirrorKlass::oop_follow_contents(ParCompactionManager* cm, |
161 oop obj) { | 173 oop obj) { |
162 instanceKlass::oop_follow_contents(cm, obj); | 174 InstanceKlass::oop_follow_contents(cm, obj); |
175 | |
176 // Follow the klass field in the mirror. | |
177 Klass* klass = java_lang_Class::as_Klass(obj); | |
178 if (klass != NULL) { | |
179 PSParallelCompact::follow_klass(cm, klass); | |
180 } else { | |
181 // If klass is NULL then this a mirror for a primitive type. | |
182 // We don't have to follow them, since they are handled as strong | |
183 // roots in Universe::oops_do. | |
184 assert(java_lang_Class::is_primitive(obj), "Sanity check"); | |
185 } | |
186 | |
163 InstanceMirrorKlass_OOP_ITERATE( \ | 187 InstanceMirrorKlass_OOP_ITERATE( \ |
164 start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj), \ | 188 start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj), \ |
165 PSParallelCompact::mark_and_push(cm, p), \ | 189 PSParallelCompact::mark_and_push(cm, p), \ |
166 assert_is_in) | 190 assert_is_in) |
167 } | 191 } |
168 #endif // SERIALGC | 192 #endif // SERIALGC |
169 | 193 |
170 int instanceMirrorKlass::oop_adjust_pointers(oop obj) { | 194 int instanceMirrorKlass::oop_adjust_pointers(oop obj) { |
171 int size = oop_size(obj); | 195 int size = oop_size(obj); |
172 instanceKlass::oop_adjust_pointers(obj); | 196 InstanceKlass::oop_adjust_pointers(obj); |
197 | |
198 // Follow the klass field in the mirror. | |
199 Klass* klass = java_lang_Class::as_Klass(obj); | |
200 if (klass != NULL) { | |
201 MarkSweep::adjust_klass(klass); | |
202 } else { | |
203 // If klass is NULL then this a mirror for a primitive type. | |
204 // We don't have to follow them, since they are handled as strong | |
205 // roots in Universe::oops_do. | |
206 assert(java_lang_Class::is_primitive(obj), "Sanity check"); | |
207 } | |
208 | |
173 InstanceMirrorKlass_OOP_ITERATE( \ | 209 InstanceMirrorKlass_OOP_ITERATE( \ |
174 start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj), \ | 210 start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj), \ |
175 MarkSweep::adjust_pointer(p), \ | 211 MarkSweep::adjust_pointer(p), \ |
176 assert_nothing) | 212 assert_nothing) |
177 return size; | 213 return size; |
191 (closure)->do_oop##nv_suffix(p), \ | 227 (closure)->do_oop##nv_suffix(p), \ |
192 assert_is_in_closed_subset) \ | 228 assert_is_in_closed_subset) \ |
193 return oop_size(obj); \ | 229 return oop_size(obj); \ |
194 | 230 |
195 | 231 |
232 #define if_do_metadata_checked(closure, nv_suffix) \ | |
233 /* Make sure the non-virtual and the virtual versions match. */ \ | |
234 assert(closure->do_metadata##nv_suffix() == closure->do_metadata(), \ | |
235 "Inconsistency in do_metadata"); \ | |
236 if (closure->do_metadata##nv_suffix()) | |
237 | |
196 // Macro to define instanceMirrorKlass::oop_oop_iterate for virtual/nonvirtual for | 238 // Macro to define instanceMirrorKlass::oop_oop_iterate for virtual/nonvirtual for |
197 // all closures. Macros calling macros above for each oop size. | 239 // all closures. Macros calling macros above for each oop size. |
198 | 240 |
199 #define InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix) \ | 241 #define InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix) \ |
200 \ | 242 \ |
201 int instanceMirrorKlass:: \ | 243 int instanceMirrorKlass:: \ |
202 oop_oop_iterate##nv_suffix(oop obj, OopClosureType* closure) { \ | 244 oop_oop_iterate##nv_suffix(oop obj, OopClosureType* closure) { \ |
203 /* Get size before changing pointers */ \ | 245 /* Get size before changing pointers */ \ |
204 SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk); \ | 246 SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk); \ |
205 \ | 247 \ |
206 instanceKlass::oop_oop_iterate##nv_suffix(obj, closure); \ | 248 InstanceKlass::oop_oop_iterate##nv_suffix(obj, closure); \ |
249 \ | |
250 if_do_metadata_checked(closure, nv_suffix) { \ | |
251 Klass* klass = java_lang_Class::as_Klass(obj); \ | |
252 /* We'll get NULL for primitive mirrors. */ \ | |
253 if (klass != NULL) { \ | |
254 closure->do_klass##nv_suffix(klass); \ | |
255 } \ | |
256 } \ | |
207 \ | 257 \ |
208 if (UseCompressedOops) { \ | 258 if (UseCompressedOops) { \ |
209 InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(narrowOop, nv_suffix); \ | 259 InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(narrowOop, nv_suffix); \ |
210 } else { \ | 260 } else { \ |
211 InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(oop, nv_suffix); \ | 261 InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(oop, nv_suffix); \ |
218 int instanceMirrorKlass:: \ | 268 int instanceMirrorKlass:: \ |
219 oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* closure) { \ | 269 oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* closure) { \ |
220 /* Get size before changing pointers */ \ | 270 /* Get size before changing pointers */ \ |
221 SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk); \ | 271 SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk); \ |
222 \ | 272 \ |
223 instanceKlass::oop_oop_iterate_backwards##nv_suffix(obj, closure); \ | 273 InstanceKlass::oop_oop_iterate_backwards##nv_suffix(obj, closure); \ |
224 \ | 274 \ |
225 if (UseCompressedOops) { \ | 275 if (UseCompressedOops) { \ |
226 InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(narrowOop, nv_suffix); \ | 276 InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(narrowOop, nv_suffix); \ |
227 } else { \ | 277 } else { \ |
228 InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(oop, nv_suffix); \ | 278 InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(oop, nv_suffix); \ |
237 oop_oop_iterate##nv_suffix##_m(oop obj, \ | 287 oop_oop_iterate##nv_suffix##_m(oop obj, \ |
238 OopClosureType* closure, \ | 288 OopClosureType* closure, \ |
239 MemRegion mr) { \ | 289 MemRegion mr) { \ |
240 SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk); \ | 290 SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk); \ |
241 \ | 291 \ |
242 instanceKlass::oop_oop_iterate##nv_suffix##_m(obj, closure, mr); \ | 292 InstanceKlass::oop_oop_iterate##nv_suffix##_m(obj, closure, mr); \ |
293 \ | |
294 if_do_metadata_checked(closure, nv_suffix) { \ | |
295 if (mr.contains(obj)) { \ | |
296 Klass* klass = java_lang_Class::as_Klass(obj); \ | |
297 /* We'll get NULL for primitive mirrors. */ \ | |
298 if (klass != NULL) { \ | |
299 closure->do_klass##nv_suffix(klass); \ | |
300 } \ | |
301 } \ | |
302 } \ | |
303 \ | |
243 if (UseCompressedOops) { \ | 304 if (UseCompressedOops) { \ |
244 InstanceMirrorKlass_BOUNDED_SPECIALIZED_OOP_ITERATE(narrowOop, nv_suffix, mr); \ | 305 InstanceMirrorKlass_BOUNDED_SPECIALIZED_OOP_ITERATE(narrowOop, nv_suffix, mr); \ |
245 } else { \ | 306 } else { \ |
246 InstanceMirrorKlass_BOUNDED_SPECIALIZED_OOP_ITERATE(oop, nv_suffix, mr); \ | 307 InstanceMirrorKlass_BOUNDED_SPECIALIZED_OOP_ITERATE(oop, nv_suffix, mr); \ |
247 } \ | 308 } \ |
256 ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN_m) | 317 ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN_m) |
257 ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN_m) | 318 ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN_m) |
258 | 319 |
259 #ifndef SERIALGC | 320 #ifndef SERIALGC |
260 void instanceMirrorKlass::oop_push_contents(PSPromotionManager* pm, oop obj) { | 321 void instanceMirrorKlass::oop_push_contents(PSPromotionManager* pm, oop obj) { |
261 instanceKlass::oop_push_contents(pm, obj); | 322 // Note that we don't have to follow the mirror -> klass pointer, since all |
323 // klasses that are dirty will be scavenged when we iterate over the | |
324 // ClassLoaderData objects. | |
325 | |
326 InstanceKlass::oop_push_contents(pm, obj); | |
262 InstanceMirrorKlass_OOP_ITERATE( \ | 327 InstanceMirrorKlass_OOP_ITERATE( \ |
263 start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj),\ | 328 start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj),\ |
264 if (PSScavenge::should_scavenge(p)) { \ | 329 if (PSScavenge::should_scavenge(p)) { \ |
265 pm->claim_or_forward_depth(p); \ | 330 pm->claim_or_forward_depth(p); \ |
266 }, \ | 331 }, \ |
267 assert_nothing ) | 332 assert_nothing ) |
268 } | 333 } |
269 | 334 |
270 int instanceMirrorKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) { | 335 int instanceMirrorKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) { |
271 instanceKlass::oop_update_pointers(cm, obj); | 336 int size = oop_size(obj); |
337 InstanceKlass::oop_update_pointers(cm, obj); | |
338 | |
339 // Follow the klass field in the mirror. | |
340 Klass* klass = java_lang_Class::as_Klass(obj); | |
341 if (klass != NULL) { | |
342 PSParallelCompact::adjust_klass(cm, klass); | |
343 } else { | |
344 // If klass is NULL then this a mirror for a primitive type. | |
345 // We don't have to follow them, since they are handled as strong | |
346 // roots in Universe::oops_do. | |
347 assert(java_lang_Class::is_primitive(obj), "Sanity check"); | |
348 } | |
349 | |
272 InstanceMirrorKlass_OOP_ITERATE( \ | 350 InstanceMirrorKlass_OOP_ITERATE( \ |
273 start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj),\ | 351 start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj),\ |
274 PSParallelCompact::adjust_pointer(p), \ | 352 PSParallelCompact::adjust_pointer(p), \ |
275 assert_nothing) | 353 assert_nothing) |
276 return oop_size(obj); | 354 return size; |
277 } | 355 } |
278 #endif // SERIALGC | 356 #endif // SERIALGC |
279 | 357 |
280 int instanceMirrorKlass::instance_size(KlassHandle k) { | 358 int instanceMirrorKlass::instance_size(KlassHandle k) { |
281 if (k() != NULL && k->oop_is_instance()) { | 359 if (k() != NULL && k->oop_is_instance()) { |
282 return align_object_size(size_helper() + instanceKlass::cast(k())->static_field_size()); | 360 return align_object_size(size_helper() + InstanceKlass::cast(k())->static_field_size()); |
283 } | 361 } |
284 return size_helper(); | 362 return size_helper(); |
285 } | 363 } |
286 | 364 |
287 instanceOop instanceMirrorKlass::allocate_instance(KlassHandle k, TRAPS) { | 365 instanceOop instanceMirrorKlass::allocate_instance(KlassHandle k, TRAPS) { |
288 // Query before forming handle. | 366 // Query before forming handle. |
289 int size = instance_size(k); | 367 int size = instance_size(k); |
290 KlassHandle h_k(THREAD, as_klassOop()); | 368 KlassHandle h_k(THREAD, this); |
291 instanceOop i = (instanceOop) CollectedHeap::Class_obj_allocate(h_k, size, k, CHECK_NULL); | 369 instanceOop i = (instanceOop) CollectedHeap::Class_obj_allocate(h_k, size, k, CHECK_NULL); |
292 return i; | 370 return i; |
293 } | 371 } |
294 | 372 |
295 int instanceMirrorKlass::oop_size(oop obj) const { | 373 int instanceMirrorKlass::oop_size(oop obj) const { |
296 return java_lang_Class::oop_size(obj); | 374 return java_lang_Class::oop_size(obj); |
297 } | 375 } |
298 | 376 |
299 int instanceMirrorKlass::compute_static_oop_field_count(oop obj) { | 377 int instanceMirrorKlass::compute_static_oop_field_count(oop obj) { |
300 klassOop k = java_lang_Class::as_klassOop(obj); | 378 Klass* k = java_lang_Class::as_Klass(obj); |
301 if (k != NULL && k->klass_part()->oop_is_instance()) { | 379 if (k != NULL && k->oop_is_instance()) { |
302 return instanceKlass::cast(k)->static_oop_field_count(); | 380 return InstanceKlass::cast(k)->static_oop_field_count(); |
303 } | 381 } |
304 return 0; | 382 return 0; |
305 } | 383 } |