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

Roman Kennke rkennke at redhat.com
Mon Feb 8 22:03:54 UTC 2021


>> 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

Ok, thanks! That explains it.

Cheers,
Roman




More information about the hotspot-gc-dev mailing list