Where do obj-array-element-classes get checked for marking?

Stefan Karlsson stefan.karlsson at oracle.com
Mon Feb 8 20:36:01 UTC 2021


Hi Roman,

On 2021-02-08 20:37, Roman Kennke wrote:
> Hello friends,
>
> I need your help:
>
> We have a testcase that is failing only very rarely, and hard to 
> reproduce, but we have caught a hs_err file:
>
> https://bugs.openjdk.java.net/browse/JDK-8261341
>
> as far as we can tell, we see an object which has it's Klass* damaged 
> because the class has been unloaded earlier.
>
> The testcase generates lots of Class<ArraysNewInstanceBug> and then 
> lots of empty (!) arrays of that type. Which means that the only way 
> that the class is referenced is via the element-type of objArrayKlass.
>
> array->objArrayKlass->element_type->_java_mirror
>
> Now I'm wondering how this is supposed to be found during marking. For 
> example, the ObjArrayKlass::oop_oop_iterate() only checks the 
> array-klass, but not the element-klass:
>
> template <typename T, typename OopClosureType>
> void ObjArrayKlass::oop_oop_iterate(oop obj, OopClosureType* closure) {
>   assert (obj->is_array(), "obj must be array");
>   objArrayOop a = objArrayOop(obj);
>
>   if (Devirtualizer::do_metadata(closure)) {
>     Devirtualizer::do_klass(closure, obj->klass());
>   }
>
>   oop_oop_iterate_elements<T>(a, closure);
> }
>
> And lacking any actual elements, the _element_klass seems the only way 
> we could reach those classes. do_klass() only fetches the CLD and 
> marks through that, but that wouldn't reach the element-klass either.
>
> Do we need something like:
>
> template <typename T, typename OopClosureType>
> void ObjArrayKlass::oop_oop_iterate(oop obj, OopClosureType* closure) {
>   assert (obj->is_array(), "obj must be array");
>   objArrayOop a = objArrayOop(obj);
>
>   if (Devirtualizer::do_metadata(closure)) {
>     Devirtualizer::do_klass(closure, obj->klass());
>     Devirtualizer::do_klass(closure, a->element_klass()); <-- check 
> element-klass here?
>   }
>
>   oop_oop_iterate_elements<T>(a, closure);
> }
>
> What do you think?

They are supposed to be found through:
array->objArrayKlass->_class_loader_data->_handles

The "handles block" contains a bunch of references to objects that are 
being kept alive by the class loader. On of those oops should be the 
java mirror of the element klass.

There also seems to be a reference from the mirror to its "component 
mirror" that gets installed here:
java_lang_Class::create_mirror
...
       // Two-way link between the array klass and its component mirror:
       // (array_klass) k -> mirror -> component_mirror -> array_klass -> k
       set_component_mirror(mirror(), comp_mirror());

I think this should make it possible to also find the component mirror from:
array->objArrayKlass->_java_mirror->_component_mirror

HTH,
StefanK

>
> Thanks,
> Roman
>




More information about the hotspot-gc-dev mailing list