RFR: 8374780: G1: Do not iterate klass metadata when splitting objArrays for every slice
Stefan Karlsson
stefank at openjdk.org
Fri Jan 9 09:54:34 UTC 2026
On Thu, 8 Jan 2026 13:54:59 GMT, Thomas Schatzl <tschatzl at openjdk.org> wrote:
> Hi all,
>
> please review this change that makes concurrent mark not try to iterate over `objArray` metadata for every slice, to make behavior uniform with other garbage collection types/garbage collectors.
>
> Testing: tier1-5
>
> Thanks,
> Thomas
I agree that we should do a change like this.
I've given some feedback that I think the code would be easier to read if you operated on array indices instead of `MemRegion`. We do that in other GCs.
Then I have given some length comments about the oop iterate functions. I find their names misleading and inconsistent. I would like to take a stab at slightly tweaking them, if you don't mind. That can be done in parallel with this change, and doesn't block the PR.
src/hotspot/share/gc/g1/g1ConcurrentMark.inline.hpp line 192:
> 190: int start = checked_cast<int>(pointer_delta(MAX2(mr.start(), obj->base()), obj->base(), heapOopSize));
> 191: int end = checked_cast<int>(pointer_delta(mr.end(), obj->base(), heapOopSize));
> 192: obj->oop_iterate_range(_cm_oop_closure, start, end);
I think this becomes a bit obscure when the lines perform multiple tasks, and having one line per operation makes it easier to make sure that the code is correct.
If we look at the operations we also see an inconsistency between `start` and `end` calculation:
For `start` it calculates the lower boundary and then it converts to an index.
For `end` it *skips* calculating a upper boundary and then it converts to an index.
You need to read the callers to figure out if skipping calculating the upper boundary for `end` is correct.
I would strongly suggest that this code is rewritten so that `scan_objArray` takes a `start` and `end` as array indices, instead of using a `MemRegion`. And that the same is done for `process_array_slice`. I think then some of these casts and `pointer_deltas` will go away and the code will be easier to read and reason about.
src/hotspot/share/oops/objArrayKlass.hpp line 138:
> 136: inline void oop_oop_iterate_bounded(oop obj, OopClosureType* closure, MemRegion mr);
> 137:
> 138: // Iterate over oop elements within [start, end) without metadata.
I know that you didn't change this, but this inconsistency in the API between `oop_oop_iterate_bounded` and `oop_oop_iterate_range` is unsettling. I think they both should be visiting the klass metadata if the obj falls within mr.
FWIW, the `InstanceKlass` implementation is also slightly different in that it checks if `mr` spans the start of `obj`:
ALWAYSINLINE void InstanceKlass::oop_oop_iterate_bounded(oop obj, OopClosureType* closure, MemRegion mr) {
if (Devirtualizer::do_metadata(closure)) {
if (mr.contains(obj)) {
Devirtualizer::do_klass(closure, this);
}
}
I wonder if we should (maybe later) do an experiment where we check that we don't pass down a metadata-visiting closure when we iterate over a range. Similar to:
ALWAYSINLINE void InstanceKlass::oop_oop_iterate_reverse(oop obj, OopClosureType* closure) {
assert(!Devirtualizer::do_metadata(closure),
"Code to handle metadata is not implemented");
And then remove the metadata visiting from `oop_oop_iterate_bounded` as well.
src/hotspot/share/oops/objArrayOop.hpp line 86:
> 84:
> 85: public:
> 86: // Special iterator for index ranges.
This comment goes together with the one above in the objArrayKlass file. While looking at the various oop_oop_iterate functions in `ObjArrayKlass` I think it would be better if this was called `oop_iterate_elements`. Given the inconsistency described above, we might also have to do something about the `ObjArrayKlass::oop_oop_iterate_range` name. Let me take a closer look at these names separately from your patch.
-------------
Marked as reviewed by stefank (Reviewer).
PR Review: https://git.openjdk.org/jdk/pull/29116#pullrequestreview-3643080539
PR Review Comment: https://git.openjdk.org/jdk/pull/29116#discussion_r2675491836
PR Review Comment: https://git.openjdk.org/jdk/pull/29116#discussion_r2675445556
PR Review Comment: https://git.openjdk.org/jdk/pull/29116#discussion_r2675527141
More information about the hotspot-dev
mailing list