20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #ifndef SHARE_GC_SHARED_WEAKPROCESSOR_INLINE_HPP
26 #define SHARE_GC_SHARED_WEAKPROCESSOR_INLINE_HPP
27
28 #include "classfile/stringTable.hpp"
29 #include "gc/shared/oopStorage.inline.hpp"
30 #include "gc/shared/oopStorageParState.inline.hpp"
31 #include "gc/shared/weakProcessor.hpp"
32 #include "gc/shared/weakProcessorPhases.hpp"
33 #include "gc/shared/weakProcessorPhaseTimes.hpp"
34 #include "gc/shared/workgroup.hpp"
35 #include "utilities/debug.hpp"
36
37 class BoolObjectClosure;
38 class OopClosure;
39
40 template<typename T>
41 class CountingIsAliveClosure : public BoolObjectClosure {
42 T* _inner;
43
44 size_t _num_dead;
45 size_t _num_total;
46
47 public:
48 CountingIsAliveClosure(T* cl) : _inner(cl), _num_dead(0), _num_total(0) { }
49
50 virtual bool do_object_b(oop obj) {
51 bool result = _inner->do_object_b(obj);
52 _num_dead += !result;
53 _num_total++;
54 return result;
55 }
56
57 size_t num_dead() const { return _num_dead; }
58 size_t num_total() const { return _num_total; }
59 };
60
61 template<typename IsAlive, typename KeepAlive>
62 void WeakProcessor::Task::work(uint worker_id,
63 IsAlive* is_alive,
64 KeepAlive* keep_alive) {
65 assert(worker_id < _nworkers,
66 "worker_id (%u) exceeds task's configured workers (%u)",
67 worker_id, _nworkers);
68
69 FOR_EACH_WEAK_PROCESSOR_PHASE(phase) {
70 CountingIsAliveClosure<IsAlive> cl(is_alive);
71 if (WeakProcessorPhases::is_serial(phase)) {
72 uint serial_index = WeakProcessorPhases::serial_index(phase);
73 if (_serial_phases_done.try_claim_task(serial_index)) {
74 WeakProcessorPhaseTimeTracker pt(_phase_times, phase);
75 WeakProcessorPhases::processor(phase)(&cl, keep_alive);
76 if (_phase_times != NULL) {
77 _phase_times->record_phase_items(phase, cl.num_dead(), cl.num_total());
78 }
79 }
80 } else {
81 WeakProcessorPhaseTimeTracker pt(_phase_times, phase, worker_id);
82 uint storage_index = WeakProcessorPhases::oop_storage_index(phase);
83 _storage_states[storage_index].weak_oops_do(&cl, keep_alive);
84 if (_phase_times != NULL) {
85 _phase_times->record_worker_items(worker_id, phase, cl.num_dead(), cl.num_total());
86 }
87 }
88 if (WeakProcessorPhases::is_stringtable(phase)) {
89 StringTable::inc_dead_counter(cl.num_dead());
90 }
91 }
92
93 _serial_phases_done.all_tasks_completed(_nworkers);
94 }
95
96 class WeakProcessor::GangTask : public AbstractGangTask {
97 Task _task;
98 BoolObjectClosure* _is_alive;
99 OopClosure* _keep_alive;
100 void (*_erased_do_work)(GangTask* task, uint worker_id);
101
102 template<typename IsAlive, typename KeepAlive>
103 static void erased_do_work(GangTask* task, uint worker_id) {
104 task->_task.work(worker_id,
105 static_cast<IsAlive*>(task->_is_alive),
106 static_cast<KeepAlive*>(task->_keep_alive));
107 }
108
109 public:
|
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #ifndef SHARE_GC_SHARED_WEAKPROCESSOR_INLINE_HPP
26 #define SHARE_GC_SHARED_WEAKPROCESSOR_INLINE_HPP
27
28 #include "classfile/stringTable.hpp"
29 #include "gc/shared/oopStorage.inline.hpp"
30 #include "gc/shared/oopStorageParState.inline.hpp"
31 #include "gc/shared/weakProcessor.hpp"
32 #include "gc/shared/weakProcessorPhases.hpp"
33 #include "gc/shared/weakProcessorPhaseTimes.hpp"
34 #include "gc/shared/workgroup.hpp"
35 #include "utilities/debug.hpp"
36
37 class BoolObjectClosure;
38 class OopClosure;
39
40 template<typename IsAlive>
41 class CountingIsAliveClosure : public BoolObjectClosure {
42 IsAlive* _inner;
43
44 size_t _num_dead;
45 size_t _num_total;
46
47 public:
48 CountingIsAliveClosure(IsAlive* cl) : _inner(cl), _num_dead(0), _num_total(0) { }
49
50 virtual bool do_object_b(oop obj) {
51 bool result = _inner->do_object_b(obj);
52 _num_dead += !result;
53 _num_total++;
54 return result;
55 }
56
57 size_t num_dead() const { return _num_dead; }
58 size_t num_total() const { return _num_total; }
59 };
60
61 template <typename IsAlive, typename KeepAlive>
62 class CountingSkippedIsAliveClosure : public Closure {
63 CountingIsAliveClosure<IsAlive> _counting_is_alive;
64 KeepAlive* _keep_alive;
65
66 size_t _num_skipped;
67
68 public:
69 CountingSkippedIsAliveClosure(IsAlive* is_alive, KeepAlive* keep_alive) :
70 _counting_is_alive(is_alive), _keep_alive(keep_alive), _num_skipped(0) { }
71
72 void do_oop(oop* p) {
73 oop obj = *p;
74 if (obj == NULL) {
75 _num_skipped++;
76 return;
77 }
78 if (_counting_is_alive.do_object_b(obj)) {
79 _keep_alive->do_oop(p);
80 } else {
81 *p = NULL;
82 }
83 }
84
85 size_t num_dead() const { return _counting_is_alive.num_dead(); }
86 size_t num_skipped() const { return _num_skipped; }
87 size_t num_total() const { return _counting_is_alive.num_total() + num_skipped(); }
88 };
89
90 template<typename IsAlive, typename KeepAlive>
91 void WeakProcessor::Task::work(uint worker_id,
92 IsAlive* is_alive,
93 KeepAlive* keep_alive) {
94 assert(worker_id < _nworkers,
95 "worker_id (%u) exceeds task's configured workers (%u)",
96 worker_id, _nworkers);
97
98 FOR_EACH_WEAK_PROCESSOR_PHASE(phase) {
99 if (WeakProcessorPhases::is_serial(phase)) {
100 CountingIsAliveClosure<IsAlive> cl(is_alive);
101 uint serial_index = WeakProcessorPhases::serial_index(phase);
102 if (_serial_phases_done.try_claim_task(serial_index)) {
103 WeakProcessorPhaseTimeTracker pt(_phase_times, phase);
104 WeakProcessorPhases::processor(phase)(&cl, keep_alive);
105 if (_phase_times != NULL) {
106 _phase_times->record_phase_items(phase, cl.num_dead(), cl.num_total());
107 }
108 }
109 } else {
110 CountingSkippedIsAliveClosure<IsAlive, KeepAlive> cl(is_alive, keep_alive);
111 WeakProcessorPhaseTimeTracker pt(_phase_times, phase, worker_id);
112 uint storage_index = WeakProcessorPhases::oop_storage_index(phase);
113 _storage_states[storage_index].oops_do(&cl);
114 if (_phase_times != NULL) {
115 _phase_times->record_worker_items(worker_id, phase, cl.num_dead(), cl.num_total());
116 }
117 if (WeakProcessorPhases::is_stringtable(phase)) {
118 StringTable::inc_dead_counter(cl.num_dead() + cl.num_skipped());
119 }
120 }
121 }
122
123 _serial_phases_done.all_tasks_completed(_nworkers);
124 }
125
126 class WeakProcessor::GangTask : public AbstractGangTask {
127 Task _task;
128 BoolObjectClosure* _is_alive;
129 OopClosure* _keep_alive;
130 void (*_erased_do_work)(GangTask* task, uint worker_id);
131
132 template<typename IsAlive, typename KeepAlive>
133 static void erased_do_work(GangTask* task, uint worker_id) {
134 task->_task.work(worker_id,
135 static_cast<IsAlive*>(task->_is_alive),
136 static_cast<KeepAlive*>(task->_keep_alive));
137 }
138
139 public:
|