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

Roman Kennke rkennke at redhat.com
Mon Feb 8 19:37:09 UTC 2021


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?

Thanks,
Roman




More information about the hotspot-gc-dev mailing list