53 #include "gc/shared/gcVMOperations.hpp"
54 #include "gc/shared/partialArraySplitter.inline.hpp"
55 #include "gc/shared/partialArrayState.hpp"
56 #include "gc/shared/partialArrayTaskStats.hpp"
57 #include "gc/shared/referencePolicy.hpp"
58 #include "gc/shared/suspendibleThreadSet.hpp"
59 #include "gc/shared/taskqueue.inline.hpp"
60 #include "gc/shared/taskTerminator.hpp"
61 #include "gc/shared/weakProcessor.inline.hpp"
62 #include "gc/shared/workerPolicy.hpp"
63 #include "jvm.h"
64 #include "logging/log.hpp"
65 #include "memory/allocation.hpp"
66 #include "memory/iterator.hpp"
67 #include "memory/metaspaceUtils.hpp"
68 #include "memory/resourceArea.hpp"
69 #include "memory/universe.hpp"
70 #include "nmt/memTracker.hpp"
71 #include "oops/access.inline.hpp"
72 #include "oops/oop.inline.hpp"
73 #include "runtime/globals_extension.hpp"
74 #include "runtime/handles.inline.hpp"
75 #include "runtime/java.hpp"
76 #include "runtime/orderAccess.hpp"
77 #include "runtime/os.hpp"
78 #include "runtime/prefetch.inline.hpp"
79 #include "runtime/threads.hpp"
80 #include "utilities/align.hpp"
81 #include "utilities/checkedCast.hpp"
82 #include "utilities/formatBuffer.hpp"
83 #include "utilities/growableArray.hpp"
84 #include "utilities/powerOfTwo.hpp"
85
86 G1CMIsAliveClosure::G1CMIsAliveClosure() : _cm(nullptr) { }
87
88 G1CMIsAliveClosure::G1CMIsAliveClosure(G1ConcurrentMark* cm) : _cm(cm) {
89 assert(cm != nullptr, "must be");
90 }
91
92 void G1CMIsAliveClosure::initialize(G1ConcurrentMark* cm) {
2427 target_size = 0;
2428 }
2429
2430 if (_task_queue->size() > target_size) {
2431 G1TaskQueueEntry entry;
2432 bool ret = _task_queue->pop_local(entry);
2433 while (ret) {
2434 process_entry(entry, false /* stolen */);
2435 if (_task_queue->size() <= target_size || has_aborted()) {
2436 ret = false;
2437 } else {
2438 ret = _task_queue->pop_local(entry);
2439 }
2440 }
2441 }
2442 }
2443
2444 size_t G1CMTask::start_partial_array_processing(objArrayOop obj) {
2445 assert(obj->length() >= (int)ObjArrayMarkingStride, "Must be a large array object %d", obj->length());
2446
2447 // Mark objArray klass metadata
2448 process_klass(obj->klass());
2449
2450 size_t array_length = obj->length();
2451 size_t initial_chunk_size = _partial_array_splitter.start(_task_queue, obj, nullptr, array_length, ObjArrayMarkingStride);
2452
2453 process_array_chunk(obj, 0, initial_chunk_size);
2454
2455 // Include object header size
2456 return objArrayOopDesc::object_size(checked_cast<int>(initial_chunk_size));
2457 }
2458
2459 size_t G1CMTask::process_partial_array(const G1TaskQueueEntry& task, bool stolen) {
2460 PartialArrayState* state = task.to_partial_array_state();
2461 // Access state before release by claim().
2462 objArrayOop obj = objArrayOop(state->source());
2463
2464 PartialArraySplitter::Claim claim =
2465 _partial_array_splitter.claim(state, _task_queue, stolen);
2466
2467 process_array_chunk(obj, claim._start, claim._end);
2468 return heap_word_size((claim._end - claim._start) * heapOopSize);
2469 }
2470
2471 void G1CMTask::drain_global_stack(bool partially) {
2472 if (has_aborted()) {
2473 return;
2474 }
2475
2476 // We have a policy to drain the local queue before we attempt to
2477 // drain the global stack.
2478 assert(partially || _task_queue->size() == 0, "invariant");
2479
2480 // Decide what the target size is, depending whether we're going to
2481 // drain it partially (so that other tasks can steal if they run out
2482 // of things to do) or totally (at the very end).
2483 // Notice that when draining the global mark stack partially, due to the racyness
2484 // of the mark stack size update we might in fact drop below the target. But,
2485 // this is not a problem.
2486 // In case of total draining, we simply process until the global mark stack is
2487 // totally empty, disregarding the size counter.
2488 if (partially) {
|
53 #include "gc/shared/gcVMOperations.hpp"
54 #include "gc/shared/partialArraySplitter.inline.hpp"
55 #include "gc/shared/partialArrayState.hpp"
56 #include "gc/shared/partialArrayTaskStats.hpp"
57 #include "gc/shared/referencePolicy.hpp"
58 #include "gc/shared/suspendibleThreadSet.hpp"
59 #include "gc/shared/taskqueue.inline.hpp"
60 #include "gc/shared/taskTerminator.hpp"
61 #include "gc/shared/weakProcessor.inline.hpp"
62 #include "gc/shared/workerPolicy.hpp"
63 #include "jvm.h"
64 #include "logging/log.hpp"
65 #include "memory/allocation.hpp"
66 #include "memory/iterator.hpp"
67 #include "memory/metaspaceUtils.hpp"
68 #include "memory/resourceArea.hpp"
69 #include "memory/universe.hpp"
70 #include "nmt/memTracker.hpp"
71 #include "oops/access.inline.hpp"
72 #include "oops/oop.inline.hpp"
73 #include "oops/oopCast.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) {
2428 target_size = 0;
2429 }
2430
2431 if (_task_queue->size() > target_size) {
2432 G1TaskQueueEntry entry;
2433 bool ret = _task_queue->pop_local(entry);
2434 while (ret) {
2435 process_entry(entry, false /* stolen */);
2436 if (_task_queue->size() <= target_size || has_aborted()) {
2437 ret = false;
2438 } else {
2439 ret = _task_queue->pop_local(entry);
2440 }
2441 }
2442 }
2443 }
2444
2445 size_t G1CMTask::start_partial_array_processing(objArrayOop obj) {
2446 assert(obj->length() >= (int)ObjArrayMarkingStride, "Must be a large array object %d", obj->length());
2447
2448 // Mark klass metadata
2449 process_klass(obj->klass());
2450
2451 size_t array_length = obj->length();
2452 size_t initial_chunk_size = _partial_array_splitter.start(_task_queue, obj, nullptr, array_length, ObjArrayMarkingStride);
2453
2454 process_array_chunk(obj, 0, initial_chunk_size);
2455
2456 // Include object header size
2457 if (obj->is_refArray()) {
2458 return refArrayOopDesc::object_size(checked_cast<int>(initial_chunk_size));
2459 } else {
2460 FlatArrayKlass* fak = FlatArrayKlass::cast(obj->klass());
2461 return flatArrayOopDesc::object_size(fak->layout_helper(), checked_cast<int>(initial_chunk_size));
2462 }
2463 }
2464
2465 size_t G1CMTask::process_partial_array(const G1TaskQueueEntry& task, bool stolen) {
2466 PartialArrayState* state = task.to_partial_array_state();
2467 // Access state before release by claim().
2468 objArrayOop obj = oop_cast<objArrayOop>(state->source());
2469
2470 PartialArraySplitter::Claim claim =
2471 _partial_array_splitter.claim(state, _task_queue, stolen);
2472
2473 process_array_chunk(obj, claim._start, claim._end);
2474
2475 if (obj->is_refArray()) {
2476 return heap_word_size((claim._end - claim._start) * heapOopSize);
2477 } else {
2478 assert(obj->is_flatArray(), "Must be!");
2479 size_t element_byte_size = FlatArrayKlass::cast(obj->klass())->element_byte_size();
2480 size_t nof_elements = claim._end - claim._start;
2481 return heap_word_size(nof_elements * element_byte_size);
2482 }
2483 }
2484
2485 void G1CMTask::drain_global_stack(bool partially) {
2486 if (has_aborted()) {
2487 return;
2488 }
2489
2490 // We have a policy to drain the local queue before we attempt to
2491 // drain the global stack.
2492 assert(partially || _task_queue->size() == 0, "invariant");
2493
2494 // Decide what the target size is, depending whether we're going to
2495 // drain it partially (so that other tasks can steal if they run out
2496 // of things to do) or totally (at the very end).
2497 // Notice that when draining the global mark stack partially, due to the racyness
2498 // of the mark stack size update we might in fact drop below the target. But,
2499 // this is not a problem.
2500 // In case of total draining, we simply process until the global mark stack is
2501 // totally empty, disregarding the size counter.
2502 if (partially) {
|