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) {
2430 target_size = 0;
2431 }
2432
2433 if (_task_queue->size() > target_size) {
2434 G1TaskQueueEntry entry;
2435 bool ret = _task_queue->pop_local(entry);
2436 while (ret) {
2437 process_entry(entry, false /* stolen */);
2438 if (_task_queue->size() <= target_size || has_aborted()) {
2439 ret = false;
2440 } else {
2441 ret = _task_queue->pop_local(entry);
2442 }
2443 }
2444 }
2445 }
2446
2447 size_t G1CMTask::start_partial_array_processing(objArrayOop obj) {
2448 assert(obj->length() >= (int)ObjArrayMarkingStride, "Must be a large array object %d", obj->length());
2449
2450 // Mark objArray klass metadata
2451 process_klass(obj->klass());
2452
2453 size_t array_length = obj->length();
2454 size_t initial_chunk_size = _partial_array_splitter.start(_task_queue, obj, nullptr, array_length, ObjArrayMarkingStride);
2455
2456 process_array_chunk(obj, 0, initial_chunk_size);
2457
2458 // Include object header size
2459 return objArrayOopDesc::object_size(checked_cast<int>(initial_chunk_size));
2460 }
2461
2462 size_t G1CMTask::process_partial_array(const G1TaskQueueEntry& task, bool stolen) {
2463 PartialArrayState* state = task.to_partial_array_state();
2464 // Access state before release by claim().
2465 objArrayOop obj = objArrayOop(state->source());
2466
2467 PartialArraySplitter::Claim claim =
2468 _partial_array_splitter.claim(state, _task_queue, stolen);
2469
2470 process_array_chunk(obj, claim._start, claim._end);
2471 return heap_word_size((claim._end - claim._start) * heapOopSize);
2472 }
2473
2474 void G1CMTask::drain_global_stack(bool partially) {
2475 if (has_aborted()) {
2476 return;
2477 }
2478
2479 // We have a policy to drain the local queue before we attempt to
2480 // drain the global stack.
2481 assert(partially || _task_queue->size() == 0, "invariant");
2482
2483 // Decide what the target size is, depending whether we're going to
2484 // drain it partially (so that other tasks can steal if they run out
2485 // of things to do) or totally (at the very end).
2486 // Notice that when draining the global mark stack partially, due to the racyness
2487 // of the mark stack size update we might in fact drop below the target. But,
2488 // this is not a problem.
2489 // In case of total draining, we simply process until the global mark stack is
2490 // totally empty, disregarding the size counter.
2491 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) {
2431 target_size = 0;
2432 }
2433
2434 if (_task_queue->size() > target_size) {
2435 G1TaskQueueEntry entry;
2436 bool ret = _task_queue->pop_local(entry);
2437 while (ret) {
2438 process_entry(entry, false /* stolen */);
2439 if (_task_queue->size() <= target_size || has_aborted()) {
2440 ret = false;
2441 } else {
2442 ret = _task_queue->pop_local(entry);
2443 }
2444 }
2445 }
2446 }
2447
2448 size_t G1CMTask::start_partial_array_processing(objArrayOop obj) {
2449 assert(obj->length() >= (int)ObjArrayMarkingStride, "Must be a large array object %d", obj->length());
2450
2451 // Mark klass metadata
2452 process_klass(obj->klass());
2453
2454 size_t array_length = obj->length();
2455 size_t initial_chunk_size = _partial_array_splitter.start(_task_queue, obj, nullptr, array_length, ObjArrayMarkingStride);
2456
2457 process_array_chunk(obj, 0, initial_chunk_size);
2458
2459 // Include object header size
2460 if (obj->is_refArray()) {
2461 return refArrayOopDesc::object_size(checked_cast<int>(initial_chunk_size));
2462 } else {
2463 FlatArrayKlass* fak = FlatArrayKlass::cast(obj->klass());
2464 return flatArrayOopDesc::object_size(fak->layout_helper(), checked_cast<int>(initial_chunk_size));
2465 }
2466 }
2467
2468 size_t G1CMTask::process_partial_array(const G1TaskQueueEntry& task, bool stolen) {
2469 PartialArrayState* state = task.to_partial_array_state();
2470 // Access state before release by claim().
2471 objArrayOop obj = oop_cast<objArrayOop>(state->source());
2472
2473 PartialArraySplitter::Claim claim =
2474 _partial_array_splitter.claim(state, _task_queue, stolen);
2475
2476 process_array_chunk(obj, claim._start, claim._end);
2477
2478 if (obj->is_refArray()) {
2479 return heap_word_size((claim._end - claim._start) * heapOopSize);
2480 } else {
2481 assert(obj->is_flatArray(), "Must be!");
2482 size_t element_byte_size = FlatArrayKlass::cast(obj->klass())->element_byte_size();
2483 size_t nof_elements = claim._end - claim._start;
2484 return heap_word_size(nof_elements * element_byte_size);
2485 }
2486 }
2487
2488 void G1CMTask::drain_global_stack(bool partially) {
2489 if (has_aborted()) {
2490 return;
2491 }
2492
2493 // We have a policy to drain the local queue before we attempt to
2494 // drain the global stack.
2495 assert(partially || _task_queue->size() == 0, "invariant");
2496
2497 // Decide what the target size is, depending whether we're going to
2498 // drain it partially (so that other tasks can steal if they run out
2499 // of things to do) or totally (at the very end).
2500 // Notice that when draining the global mark stack partially, due to the racyness
2501 // of the mark stack size update we might in fact drop below the target. But,
2502 // this is not a problem.
2503 // In case of total draining, we simply process until the global mark stack is
2504 // totally empty, disregarding the size counter.
2505 if (partially) {
|