@@ -46,38 +46,41 @@ void InstanceMirrorKlass::oop_oop_iterate_statics(oop obj, OopClosureType* closu
4646 }
4747}
4848
49+ template <class OopClosureType >
50+ void InstanceMirrorKlass::do_metadata (oop obj, OopClosureType* closure) {
51+ Klass* klass = java_lang_Class::as_Klass (obj);
52+ if (klass != nullptr ) {
53+ if (klass->class_loader_data () == nullptr ) {
54+ // This is a mirror that belongs to a shared class that has not been loaded yet.
55+ assert (klass->is_shared (), " Must be" );
56+ } else if (klass->is_instance_klass () && klass->class_loader_data ()->has_class_mirror_holder ()) {
57+ // A non-strong hidden class doesn't have its own class loader,
58+ // so when handling the java mirror for the class we need to make sure its class
59+ // loader data is claimed, this is done by calling do_cld explicitly.
60+ // For non-strong hidden classes the call to do_cld is made when the class
61+ // loader itself is handled.
62+ Devirtualizer::do_cld (closure, klass->class_loader_data ());
63+ } else {
64+ Devirtualizer::do_klass (closure, klass);
65+ }
66+ } else {
67+ // Java mirror -> Klass* "nullptr" backlink means either:
68+ // 1. This is a Java mirror for a primitive class. We do not need to follow it,
69+ // these mirrors are always strong roots.
70+ // 2. This is a Java mirror for a newly allocated non-primitive class, and we
71+ // somehow managed to reach the newly allocated Java mirror with not yet
72+ // installed backlink. We cannot do anything here, this case would be handled
73+ // separately by GC, e.g. by keeping the relevant metadata alive during the GC.
74+ // Unfortunately, the existence of corner case (2) prevents us from asserting (1).
75+ }
76+ }
77+
4978template <typename T, class OopClosureType >
5079void InstanceMirrorKlass::oop_oop_iterate (oop obj, OopClosureType* closure) {
5180 InstanceKlass::oop_oop_iterate<T>(obj, closure);
5281
5382 if (Devirtualizer::do_metadata (closure)) {
54- Klass* klass = java_lang_Class::as_Klass (obj);
55- // We'll get null for primitive mirrors.
56- if (klass != nullptr ) {
57- if (klass->class_loader_data () == nullptr ) {
58- // This is a mirror that belongs to a shared class that has not be loaded yet.
59- assert (klass->is_shared (), " must be" );
60- } else if (klass->is_instance_klass () && klass->class_loader_data ()->has_class_mirror_holder ()) {
61- // A non-strong hidden class doesn't have its own class loader,
62- // so when handling the java mirror for the class we need to make sure its class
63- // loader data is claimed, this is done by calling do_cld explicitly.
64- // For non-strong hidden classes the call to do_cld is made when the class
65- // loader itself is handled.
66- Devirtualizer::do_cld (closure, klass->class_loader_data ());
67- } else {
68- Devirtualizer::do_klass (closure, klass);
69- }
70- } else {
71- // We would like to assert here (as below) that if klass has been null, then
72- // this has been a mirror for a primitive type that we do not need to follow
73- // as they are always strong roots.
74- // However, we might get across a klass that just changed during CMS concurrent
75- // marking if allocation occurred in the old generation.
76- // This is benign here, as we keep alive all CLDs that were loaded during the
77- // CMS concurrent phase in the class loading, i.e. they will be iterated over
78- // and kept alive during remark.
79- // assert(java_lang_Class::is_primitive(obj), "Sanity check");
80- }
83+ do_metadata<OopClosureType>(obj, closure);
8184 }
8285
8386 oop_oop_iterate_statics<T>(obj, closure);
@@ -121,11 +124,7 @@ void InstanceMirrorKlass::oop_oop_iterate_bounded(oop obj, OopClosureType* closu
121124
122125 if (Devirtualizer::do_metadata (closure)) {
123126 if (mr.contains (obj)) {
124- Klass* klass = java_lang_Class::as_Klass (obj);
125- // We'll get null for primitive mirrors.
126- if (klass != nullptr ) {
127- Devirtualizer::do_klass (closure, klass);
128- }
127+ do_metadata<OopClosureType>(obj, closure);
129128 }
130129 }
131130
0 commit comments