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