diff --git a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp index 84a0b7588ef08..238b5206032ed 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp @@ -2341,20 +2341,16 @@ void G1CMTask::drain_local_queue(bool partially) { } } -size_t G1CMTask::start_partial_array_processing(oop obj) { +size_t G1CMTask::start_partial_array_processing(objArrayOop 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); - // Mark objArray klass metadata - if (_cm_oop_closure->do_metadata()) { - _cm_oop_closure->do_klass(obj_array->klass()); - } + process_klass(obj->klass()); + + 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_array, 0, initial_chunk_size); + process_array_chunk(obj, 0, initial_chunk_size); // Include object header size return objArrayOopDesc::object_size(checked_cast(initial_chunk_size)); diff --git a/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp b/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp index 7aa9394720425..f9287f673d22c 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp @@ -844,12 +844,10 @@ class G1CMTask : public TerminatorTerminator { // mark bitmap scan, and so needs to be pushed onto the mark stack. bool is_below_finger(oop obj, HeapWord* global_finger) const; - template 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 @@ class G1CMTask : public TerminatorTerminator { template 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); diff --git a/src/hotspot/share/gc/g1/g1ConcurrentMark.inline.hpp b/src/hotspot/share/gc/g1/g1ConcurrentMark.inline.hpp index 21167d5cae9ba..094f4dca99457 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentMark.inline.hpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.inline.hpp @@ -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(task_entry, stolen); + assert(task_entry.is_partial_array_state() || _mark_bitmap->is_marked(cast_from_oop(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 -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(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(entry, false /* stolen */); } else { + G1TaskQueueEntry entry(obj); push(entry); } }