54 #include "gc/shared/gcVMOperations.hpp"
55 #include "gc/shared/partialArraySplitter.inline.hpp"
56 #include "gc/shared/partialArrayState.hpp"
57 #include "gc/shared/partialArrayTaskStats.hpp"
58 #include "gc/shared/referencePolicy.hpp"
59 #include "gc/shared/suspendibleThreadSet.hpp"
60 #include "gc/shared/taskqueue.inline.hpp"
61 #include "gc/shared/taskTerminator.hpp"
62 #include "gc/shared/weakProcessor.inline.hpp"
63 #include "gc/shared/workerPolicy.hpp"
64 #include "jvm.h"
65 #include "logging/log.hpp"
66 #include "memory/allocation.hpp"
67 #include "memory/iterator.hpp"
68 #include "memory/metaspaceUtils.hpp"
69 #include "memory/resourceArea.hpp"
70 #include "memory/universe.hpp"
71 #include "nmt/memTracker.hpp"
72 #include "oops/access.inline.hpp"
73 #include "oops/oop.inline.hpp"
74 #include "runtime/globals_extension.hpp"
75 #include "runtime/handles.inline.hpp"
76 #include "runtime/java.hpp"
77 #include "runtime/orderAccess.hpp"
78 #include "runtime/os.hpp"
79 #include "runtime/prefetch.inline.hpp"
80 #include "runtime/threads.hpp"
81 #include "utilities/align.hpp"
82 #include "utilities/checkedCast.hpp"
83 #include "utilities/formatBuffer.hpp"
84 #include "utilities/growableArray.hpp"
85 #include "utilities/powerOfTwo.hpp"
86
87 G1CMIsAliveClosure::G1CMIsAliveClosure() : _cm(nullptr) { }
88
89 G1CMIsAliveClosure::G1CMIsAliveClosure(G1ConcurrentMark* cm) : _cm(cm) {
90 assert(cm != nullptr, "must be");
91 }
92
93 void G1CMIsAliveClosure::initialize(G1ConcurrentMark* cm) {
2298 target_size = 0;
2299 }
2300
2301 if (_task_queue->size() > target_size) {
2302 G1TaskQueueEntry entry;
2303 bool ret = _task_queue->pop_local(entry);
2304 while (ret) {
2305 process_entry(entry, false /* stolen */);
2306 if (_task_queue->size() <= target_size || has_aborted()) {
2307 ret = false;
2308 } else {
2309 ret = _task_queue->pop_local(entry);
2310 }
2311 }
2312 }
2313 }
2314
2315 size_t G1CMTask::start_partial_array_processing(oop obj) {
2316 assert(should_be_sliced(obj), "Must be an array object %d and large %zu", obj->is_objArray(), obj->size());
2317
2318 objArrayOop obj_array = objArrayOop(obj);
2319 size_t array_length = obj_array->length();
2320
2321 size_t initial_chunk_size = _partial_array_splitter.start(_task_queue, obj_array, nullptr, array_length);
2322
2323 // Mark objArray klass metadata
2324 if (_cm_oop_closure->do_metadata()) {
2325 _cm_oop_closure->do_klass(obj_array->klass());
2326 }
2327
2328 process_array_chunk(obj_array, 0, initial_chunk_size);
2329
2330 // Include object header size
2331 return objArrayOopDesc::object_size(checked_cast<int>(initial_chunk_size));
2332 }
2333
2334 size_t G1CMTask::process_partial_array(const G1TaskQueueEntry& task, bool stolen) {
2335 PartialArrayState* state = task.to_partial_array_state();
2336 // Access state before release by claim().
2337 objArrayOop obj = objArrayOop(state->source());
2338
2339 PartialArraySplitter::Claim claim =
2340 _partial_array_splitter.claim(state, _task_queue, stolen);
2341
2342 process_array_chunk(obj, claim._start, claim._end);
2343 return heap_word_size((claim._end - claim._start) * heapOopSize);
2344 }
2345
2346 void G1CMTask::drain_global_stack(bool partially) {
2347 if (has_aborted()) {
2348 return;
2349 }
2350
2351 // We have a policy to drain the local queue before we attempt to
2352 // drain the global stack.
2353 assert(partially || _task_queue->size() == 0, "invariant");
2354
2355 // Decide what the target size is, depending whether we're going to
2356 // drain it partially (so that other tasks can steal if they run out
2357 // of things to do) or totally (at the very end).
2358 // Notice that when draining the global mark stack partially, due to the racyness
2359 // of the mark stack size update we might in fact drop below the target. But,
2360 // this is not a problem.
2361 // In case of total draining, we simply process until the global mark stack is
2362 // totally empty, disregarding the size counter.
2363 if (partially) {
|
54 #include "gc/shared/gcVMOperations.hpp"
55 #include "gc/shared/partialArraySplitter.inline.hpp"
56 #include "gc/shared/partialArrayState.hpp"
57 #include "gc/shared/partialArrayTaskStats.hpp"
58 #include "gc/shared/referencePolicy.hpp"
59 #include "gc/shared/suspendibleThreadSet.hpp"
60 #include "gc/shared/taskqueue.inline.hpp"
61 #include "gc/shared/taskTerminator.hpp"
62 #include "gc/shared/weakProcessor.inline.hpp"
63 #include "gc/shared/workerPolicy.hpp"
64 #include "jvm.h"
65 #include "logging/log.hpp"
66 #include "memory/allocation.hpp"
67 #include "memory/iterator.hpp"
68 #include "memory/metaspaceUtils.hpp"
69 #include "memory/resourceArea.hpp"
70 #include "memory/universe.hpp"
71 #include "nmt/memTracker.hpp"
72 #include "oops/access.inline.hpp"
73 #include "oops/oop.inline.hpp"
74 #include "oops/oopCast.inline.hpp"
75 #include "runtime/globals_extension.hpp"
76 #include "runtime/handles.inline.hpp"
77 #include "runtime/java.hpp"
78 #include "runtime/orderAccess.hpp"
79 #include "runtime/os.hpp"
80 #include "runtime/prefetch.inline.hpp"
81 #include "runtime/threads.hpp"
82 #include "utilities/align.hpp"
83 #include "utilities/checkedCast.hpp"
84 #include "utilities/formatBuffer.hpp"
85 #include "utilities/growableArray.hpp"
86 #include "utilities/powerOfTwo.hpp"
87
88 G1CMIsAliveClosure::G1CMIsAliveClosure() : _cm(nullptr) { }
89
90 G1CMIsAliveClosure::G1CMIsAliveClosure(G1ConcurrentMark* cm) : _cm(cm) {
91 assert(cm != nullptr, "must be");
92 }
93
94 void G1CMIsAliveClosure::initialize(G1ConcurrentMark* cm) {
2299 target_size = 0;
2300 }
2301
2302 if (_task_queue->size() > target_size) {
2303 G1TaskQueueEntry entry;
2304 bool ret = _task_queue->pop_local(entry);
2305 while (ret) {
2306 process_entry(entry, false /* stolen */);
2307 if (_task_queue->size() <= target_size || has_aborted()) {
2308 ret = false;
2309 } else {
2310 ret = _task_queue->pop_local(entry);
2311 }
2312 }
2313 }
2314 }
2315
2316 size_t G1CMTask::start_partial_array_processing(oop obj) {
2317 assert(should_be_sliced(obj), "Must be an array object %d and large %zu", obj->is_objArray(), obj->size());
2318
2319 objArrayOop obj_array = oop_cast<objArrayOop>(obj);
2320 size_t array_length = obj_array->length();
2321
2322 size_t initial_chunk_size = _partial_array_splitter.start(_task_queue, obj_array, nullptr, array_length);
2323
2324 // Mark objArray klass metadata
2325 if (_cm_oop_closure->do_metadata()) {
2326 _cm_oop_closure->do_klass(obj_array->klass());
2327
2328 if (obj_array->is_flatArray()) {
2329 FlatArrayKlass* faklass = FlatArrayKlass::cast(obj_array->klass());
2330 _cm_oop_closure->do_klass(faklass->element_klass());
2331 }
2332 }
2333
2334 process_array_chunk(obj_array, 0, initial_chunk_size);
2335
2336 // Include object header size
2337 if (obj_array->is_refArray()) {
2338 return refArrayOopDesc::object_size(checked_cast<int>(initial_chunk_size));
2339 } else {
2340 FlatArrayKlass* faKlass = FlatArrayKlass::cast(obj_array->klass());
2341 return flatArrayOopDesc::object_size(faKlass->layout_helper(), checked_cast<int>(initial_chunk_size));
2342 }
2343 }
2344
2345 size_t G1CMTask::process_partial_array(const G1TaskQueueEntry& task, bool stolen) {
2346 PartialArrayState* state = task.to_partial_array_state();
2347 // Access state before release by claim().
2348 objArrayOop obj = oop_cast<objArrayOop>(state->source());
2349
2350 PartialArraySplitter::Claim claim =
2351 _partial_array_splitter.claim(state, _task_queue, stolen);
2352
2353 process_array_chunk(obj, claim._start, claim._end);
2354
2355 if (obj->is_refArray()) {
2356 return heap_word_size((claim._end - claim._start) * heapOopSize);
2357 } else {
2358 assert(obj->is_flatArray(), "Must be!");
2359 size_t element_byte_size = FlatArrayKlass::cast(obj->klass())->element_byte_size();
2360 size_t nof_elements = claim._end - claim._start;
2361 return heap_word_size(nof_elements * element_byte_size);
2362 }
2363 }
2364
2365 void G1CMTask::drain_global_stack(bool partially) {
2366 if (has_aborted()) {
2367 return;
2368 }
2369
2370 // We have a policy to drain the local queue before we attempt to
2371 // drain the global stack.
2372 assert(partially || _task_queue->size() == 0, "invariant");
2373
2374 // Decide what the target size is, depending whether we're going to
2375 // drain it partially (so that other tasks can steal if they run out
2376 // of things to do) or totally (at the very end).
2377 // Notice that when draining the global mark stack partially, due to the racyness
2378 // of the mark stack size update we might in fact drop below the target. But,
2379 // this is not a problem.
2380 // In case of total draining, we simply process until the global mark stack is
2381 // totally empty, disregarding the size counter.
2382 if (partially) {
|