8381561: G1: Cleanup patch in preparation for eager reclamation of flat arrays

Reviewed-by: tschatzl, ayang, iwalulya
This commit is contained in:
Stefan Karlsson 2026-04-07 11:30:23 +00:00
parent c267c84ff6
commit 69c4a211ee
3 changed files with 31 additions and 38 deletions

View File

@ -2341,20 +2341,16 @@ void G1CMTask::drain_local_queue(bool partially) {
}
}
size_t G1CMTask::start_partial_array_processing(oop obj) {
assert(should_be_sliced(obj), "Must be an array object %d and large %zu", obj->is_objArray(), obj->size());
objArrayOop obj_array = objArrayOop(obj);
size_t array_length = obj_array->length();
size_t initial_chunk_size = _partial_array_splitter.start(_task_queue, obj_array, nullptr, array_length);
size_t G1CMTask::start_partial_array_processing(objArrayOop obj) {
assert(obj->length() >= (int)ObjArrayMarkingStride, "Must be a large array object %d", obj->length());
// Mark objArray klass metadata
if (_cm_oop_closure->do_metadata()) {
_cm_oop_closure->do_klass(obj_array->klass());
}
process_klass(obj->klass());
process_array_chunk(obj_array, 0, initial_chunk_size);
size_t array_length = obj->length();
size_t initial_chunk_size = _partial_array_splitter.start(_task_queue, obj, nullptr, array_length);
process_array_chunk(obj, 0, initial_chunk_size);
// Include object header size
return objArrayOopDesc::object_size(checked_cast<int>(initial_chunk_size));

View File

@ -844,12 +844,10 @@ private:
// mark bitmap scan, and so needs to be pushed onto the mark stack.
bool is_below_finger(oop obj, HeapWord* global_finger) const;
template<bool scan> void process_grey_task_entry(G1TaskQueueEntry task_entry, bool stolen);
static bool should_be_sliced(oop obj);
// Start processing the given objArrayOop by first pushing its continuations and
// then scanning the first chunk including the header.
size_t start_partial_array_processing(oop obj);
size_t start_partial_array_processing(objArrayOop obj);
// Process the given continuation. Returns the number of words scanned.
size_t process_partial_array(const G1TaskQueueEntry& task, bool stolen);
// Apply the closure to the given range of elements in the objArray.
@ -918,6 +916,9 @@ public:
template <class T>
inline bool deal_with_reference(T* p);
// Scan the klass and visit its children.
inline void process_klass(Klass* klass);
// Scans an object and visits its children.
inline void process_entry(G1TaskQueueEntry task_entry, bool stolen);

View File

@ -106,9 +106,27 @@ inline void G1CMMarkStack::iterate(Fn fn) const {
}
#endif
inline void G1CMTask::process_klass(Klass* klass) {
_cm_oop_closure->do_klass(klass);
}
// It scans an object and visits its children.
inline void G1CMTask::process_entry(G1TaskQueueEntry task_entry, bool stolen) {
process_grey_task_entry<true>(task_entry, stolen);
assert(task_entry.is_partial_array_state() || _mark_bitmap->is_marked(cast_from_oop<HeapWord*>(task_entry.to_oop())),
"Any stolen object should be a slice or marked");
if (task_entry.is_partial_array_state()) {
_words_scanned += process_partial_array(task_entry, stolen);
} else {
oop obj = task_entry.to_oop();
if (should_be_sliced(obj)) {
_words_scanned += start_partial_array_processing(objArrayOop(obj));
} else {
_words_scanned += obj->oop_iterate_size(_cm_oop_closure);
}
}
check_limits();
}
inline void G1CMTask::push(G1TaskQueueEntry task_entry) {
@ -160,27 +178,6 @@ inline bool G1CMTask::is_below_finger(oop obj, HeapWord* global_finger) const {
return objAddr < global_finger;
}
template<bool scan>
inline void G1CMTask::process_grey_task_entry(G1TaskQueueEntry task_entry, bool stolen) {
assert(scan || (!task_entry.is_partial_array_state() && task_entry.to_oop()->is_typeArray()), "Skipping scan of grey non-typeArray");
assert(task_entry.is_partial_array_state() || _mark_bitmap->is_marked(cast_from_oop<HeapWord*>(task_entry.to_oop())),
"Any stolen object should be a slice or marked");
if (scan) {
if (task_entry.is_partial_array_state()) {
_words_scanned += process_partial_array(task_entry, stolen);
} else {
oop obj = task_entry.to_oop();
if (should_be_sliced(obj)) {
_words_scanned += start_partial_array_processing(obj);
} else {
_words_scanned += obj->oop_iterate_size(_cm_oop_closure);
}
}
}
check_limits();
}
inline bool G1CMTask::should_be_sliced(oop obj) {
return obj->is_objArray() && ((objArrayOop)obj)->length() >= (int)ObjArrayMarkingStride;
}
@ -272,7 +269,6 @@ inline bool G1CMTask::make_reference_grey(oop obj) {
// be pushed on the stack. So, some duplicate work, but no
// correctness problems.
if (is_below_finger(obj, global_finger)) {
G1TaskQueueEntry entry(obj);
if (obj->is_typeArray()) {
// Immediately process arrays of primitive types, rather
// than pushing on the mark stack. This keeps us from
@ -284,8 +280,8 @@ inline bool G1CMTask::make_reference_grey(oop obj) {
// by only doing a bookkeeping update and avoiding the
// actual scan of the object - a typeArray contains no
// references, and the metadata is built-in.
process_grey_task_entry<false>(entry, false /* stolen */);
} else {
G1TaskQueueEntry entry(obj);
push(entry);
}
}