12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #ifndef SHARE_VM_GC_G1_G1PARSCANTHREADSTATE_INLINE_HPP
26 #define SHARE_VM_GC_G1_G1PARSCANTHREADSTATE_INLINE_HPP
27
28 #include "gc/g1/g1ParScanThreadState.hpp"
29 #include "gc/g1/g1RemSet.hpp"
30 #include "oops/access.inline.hpp"
31 #include "oops/oop.inline.hpp"
32
33 template <class T> void G1ParScanThreadState::do_oop_evac(T* p) {
34 // Reference should not be NULL here as such are never pushed to the task queue.
35 oop obj = RawAccess<OOP_NOT_NULL>::oop_load(p);
36
37 // Although we never intentionally push references outside of the collection
38 // set, due to (benign) races in the claim mechanism during RSet scanning more
39 // than one thread might claim the same card. So the same card may be
40 // processed multiple times, and so we might get references into old gen here.
41 // So we need to redo this check.
42 const InCSetState in_cset_state = _g1h->in_cset_state(obj);
43 if (in_cset_state.is_in_cset()) {
44 markOop m = obj->mark_raw();
45 if (m->is_marked()) {
46 obj = (oop) m->decode_pointer();
47 } else {
48 obj = copy_to_survivor_space(in_cset_state, obj, m);
49 }
50 RawAccess<OOP_NOT_NULL>::oop_store(p, obj);
51 } else if (in_cset_state.is_humongous()) {
132 inline void G1ParScanThreadState::dispatch_reference(StarTask ref) {
133 assert(verify_task(ref), "sanity");
134 if (ref.is_narrow()) {
135 deal_with_reference((narrowOop*)ref);
136 } else {
137 deal_with_reference((oop*)ref);
138 }
139 }
140
141 void G1ParScanThreadState::steal_and_trim_queue(RefToScanQueueSet *task_queues) {
142 StarTask stolen_task;
143 while (task_queues->steal(_worker_id, &_hash_seed, stolen_task)) {
144 assert(verify_task(stolen_task), "sanity");
145 dispatch_reference(stolen_task);
146
147 // We've just processed a reference and we might have made
148 // available new entries on the queues. So we have to make sure
149 // we drain the queues as necessary.
150 trim_queue();
151 }
152 }
153
154 #endif // SHARE_VM_GC_G1_G1PARSCANTHREADSTATE_INLINE_HPP
|
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #ifndef SHARE_VM_GC_G1_G1PARSCANTHREADSTATE_INLINE_HPP
26 #define SHARE_VM_GC_G1_G1PARSCANTHREADSTATE_INLINE_HPP
27
28 #include "gc/g1/g1ParScanThreadState.hpp"
29 #include "gc/g1/g1RemSet.hpp"
30 #include "oops/access.inline.hpp"
31 #include "oops/oop.inline.hpp"
32 #include "utilities/ticks.inline.hpp"
33
34 template <class T> void G1ParScanThreadState::do_oop_evac(T* p) {
35 // Reference should not be NULL here as such are never pushed to the task queue.
36 oop obj = RawAccess<OOP_NOT_NULL>::oop_load(p);
37
38 // Although we never intentionally push references outside of the collection
39 // set, due to (benign) races in the claim mechanism during RSet scanning more
40 // than one thread might claim the same card. So the same card may be
41 // processed multiple times, and so we might get references into old gen here.
42 // So we need to redo this check.
43 const InCSetState in_cset_state = _g1h->in_cset_state(obj);
44 if (in_cset_state.is_in_cset()) {
45 markOop m = obj->mark_raw();
46 if (m->is_marked()) {
47 obj = (oop) m->decode_pointer();
48 } else {
49 obj = copy_to_survivor_space(in_cset_state, obj, m);
50 }
51 RawAccess<OOP_NOT_NULL>::oop_store(p, obj);
52 } else if (in_cset_state.is_humongous()) {
133 inline void G1ParScanThreadState::dispatch_reference(StarTask ref) {
134 assert(verify_task(ref), "sanity");
135 if (ref.is_narrow()) {
136 deal_with_reference((narrowOop*)ref);
137 } else {
138 deal_with_reference((oop*)ref);
139 }
140 }
141
142 void G1ParScanThreadState::steal_and_trim_queue(RefToScanQueueSet *task_queues) {
143 StarTask stolen_task;
144 while (task_queues->steal(_worker_id, &_hash_seed, stolen_task)) {
145 assert(verify_task(stolen_task), "sanity");
146 dispatch_reference(stolen_task);
147
148 // We've just processed a reference and we might have made
149 // available new entries on the queues. So we have to make sure
150 // we drain the queues as necessary.
151 trim_queue();
152 }
153 }
154
155 inline bool G1ParScanThreadState::needs_partial_trimming() const {
156 return !_refs->overflow_empty() || _refs->size() > _stack_drain_upper_threshold;
157 }
158
159 inline bool G1ParScanThreadState::is_partially_trimmed() const {
160 return _refs->overflow_empty() && _refs->size() <= _stack_drain_lower_threshold;
161 }
162
163 inline void G1ParScanThreadState::trim_queue_to_threshold(uint threshold) {
164 StarTask ref;
165 // Drain the overflow stack first, so other threads can potentially steal.
166 while (_refs->pop_overflow(ref)) {
167 if (!_refs->try_push_to_taskqueue(ref)) {
168 dispatch_reference(ref);
169 }
170 }
171
172 while (_refs->pop_local(ref, threshold)) {
173 dispatch_reference(ref);
174 }
175 }
176
177 inline void G1ParScanThreadState::trim_queue_partially() {
178 if (!needs_partial_trimming()) {
179 return;
180 }
181
182 const Ticks start = Ticks::now();
183 do {
184 trim_queue_to_threshold(_stack_drain_lower_threshold);
185 } while (!is_partially_trimmed());
186 _trim_ticks += Ticks::now() - start;
187 }
188
189 inline Tickspan G1ParScanThreadState::trim_ticks() {
190 return _trim_ticks;
191 }
192
193 inline void G1ParScanThreadState::reset_trim_ticks() {
194 _trim_ticks = Tickspan();
195 }
196
197 #endif // SHARE_VM_GC_G1_G1PARSCANTHREADSTATE_INLINE_HPP
|