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