24 #ifndef SHARE_VM_GC_SHENANDOAH_SHENANDOAHCONCURRENTMARK_INLINE_HPP
25 #define SHARE_VM_GC_SHENANDOAH_SHENANDOAHCONCURRENTMARK_INLINE_HPP
26
27 #include "gc/shenandoah/brooksPointer.hpp"
28 #include "gc/shenandoah/shenandoahBarrierSet.inline.hpp"
29 #include "gc/shenandoah/shenandoahConcurrentMark.hpp"
30 #include "memory/iterator.inline.hpp"
31 #include "oops/oop.inline.hpp"
32 #include "runtime/prefetch.inline.hpp"
33
34 template <class T, bool COUNT_LIVENESS>
35 void ShenandoahConcurrentMark::do_task(ShenandoahObjToScanQueue* q, T* cl, jushort* live_data, ShenandoahMarkTask* task) {
36 oop obj = task->obj();
37
38 assert(obj != NULL, "expect non-null object");
39 assert(oopDesc::unsafe_equals(obj, ShenandoahBarrierSet::resolve_oop_static_not_null(obj)), "expect forwarded obj in queue");
40 assert(_heap->cancelled_concgc()
41 || oopDesc::bs()->is_safe(obj),
42 "we don't want to mark objects in from-space");
43 assert(_heap->is_in(obj), "referenced objects must be in the heap. No?");
44 assert(_heap->is_marked_next(obj), "only marked objects on task queue");
45
46 if (task->is_not_chunked()) {
47 if (COUNT_LIVENESS) count_liveness(live_data, obj);
48 if (obj->is_instance()) {
49 // Case 1: Normal oop, process as usual.
50 obj->oop_iterate(cl);
51 } else if (obj->is_objArray()) {
52 // Case 2: Object array instance and no chunk is set. Must be the first
53 // time we visit it, start the chunked processing.
54 do_chunked_array_start<T>(q, cl, obj);
55 } else {
56 // Case 3: Primitive array. Do nothing, no oops there. We use the same
57 // performance tweak TypeArrayKlass::oop_oop_iterate_impl is using:
58 // We skip iterating over the klass pointer since we know that
59 // Universe::TypeArrayKlass never moves.
60 assert (obj->is_typeArray(), "should be type array");
61 }
62 } else {
63 // Case 4: Array chunk, has sensible chunk id. Process it.
64 do_chunked_array<T>(q, cl, obj, task->chunk(), task->pow());
223 case SIMPLE:
224 // We piggy-back reference updating to the marking tasks.
225 obj = heap->update_oop_ref_not_null(p, obj);
226 break;
227 case CONCURRENT:
228 obj = heap->maybe_update_oop_ref_not_null(p, obj);
229 break;
230 default:
231 ShouldNotReachHere();
232 }
233 assert(oopDesc::unsafe_equals(obj, ShenandoahBarrierSet::resolve_oop_static(obj)), "need to-space object here");
234
235 // Note: Only when concurrently updating references can obj become NULL here.
236 // It happens when a mutator thread beats us by writing another value. In that
237 // case we don't need to do anything else.
238 if (UPDATE_REFS != CONCURRENT || !oopDesc::is_null(obj)) {
239 assert(!oopDesc::is_null(obj), "Must not be null here");
240 assert(heap->is_in(obj), "We shouldn't be calling this on objects not in the heap: " PTR_FORMAT, p2i(obj));
241 assert(oopDesc::bs()->is_safe(obj), "Only mark objects in from-space");
242
243 if (heap->mark_next(obj)) {
244 log_develop_trace(gc, marking)("Marked obj: " PTR_FORMAT, p2i((HeapWord*) obj));
245
246 bool pushed = q->push(ShenandoahMarkTask(obj));
247 assert(pushed, "overflow queue should always succeed pushing");
248 } else {
249 log_develop_trace(gc, marking)("Failed to mark obj (already marked): " PTR_FORMAT, p2i((HeapWord*) obj));
250 assert(heap->is_marked_next(obj), "Consistency: should be marked.");
251 }
252 }
253 }
254 }
255
256 #endif // SHARE_VM_GC_SHENANDOAH_SHENANDOAHCONCURRENTMARK_INLINE_HPP
|
24 #ifndef SHARE_VM_GC_SHENANDOAH_SHENANDOAHCONCURRENTMARK_INLINE_HPP
25 #define SHARE_VM_GC_SHENANDOAH_SHENANDOAHCONCURRENTMARK_INLINE_HPP
26
27 #include "gc/shenandoah/brooksPointer.hpp"
28 #include "gc/shenandoah/shenandoahBarrierSet.inline.hpp"
29 #include "gc/shenandoah/shenandoahConcurrentMark.hpp"
30 #include "memory/iterator.inline.hpp"
31 #include "oops/oop.inline.hpp"
32 #include "runtime/prefetch.inline.hpp"
33
34 template <class T, bool COUNT_LIVENESS>
35 void ShenandoahConcurrentMark::do_task(ShenandoahObjToScanQueue* q, T* cl, jushort* live_data, ShenandoahMarkTask* task) {
36 oop obj = task->obj();
37
38 assert(obj != NULL, "expect non-null object");
39 assert(oopDesc::unsafe_equals(obj, ShenandoahBarrierSet::resolve_oop_static_not_null(obj)), "expect forwarded obj in queue");
40 assert(_heap->cancelled_concgc()
41 || oopDesc::bs()->is_safe(obj),
42 "we don't want to mark objects in from-space");
43 assert(_heap->is_in(obj), "referenced objects must be in the heap. No?");
44 assert(_heap->is_marked(obj), "only marked objects on task queue");
45
46 if (task->is_not_chunked()) {
47 if (COUNT_LIVENESS) count_liveness(live_data, obj);
48 if (obj->is_instance()) {
49 // Case 1: Normal oop, process as usual.
50 obj->oop_iterate(cl);
51 } else if (obj->is_objArray()) {
52 // Case 2: Object array instance and no chunk is set. Must be the first
53 // time we visit it, start the chunked processing.
54 do_chunked_array_start<T>(q, cl, obj);
55 } else {
56 // Case 3: Primitive array. Do nothing, no oops there. We use the same
57 // performance tweak TypeArrayKlass::oop_oop_iterate_impl is using:
58 // We skip iterating over the klass pointer since we know that
59 // Universe::TypeArrayKlass never moves.
60 assert (obj->is_typeArray(), "should be type array");
61 }
62 } else {
63 // Case 4: Array chunk, has sensible chunk id. Process it.
64 do_chunked_array<T>(q, cl, obj, task->chunk(), task->pow());
223 case SIMPLE:
224 // We piggy-back reference updating to the marking tasks.
225 obj = heap->update_oop_ref_not_null(p, obj);
226 break;
227 case CONCURRENT:
228 obj = heap->maybe_update_oop_ref_not_null(p, obj);
229 break;
230 default:
231 ShouldNotReachHere();
232 }
233 assert(oopDesc::unsafe_equals(obj, ShenandoahBarrierSet::resolve_oop_static(obj)), "need to-space object here");
234
235 // Note: Only when concurrently updating references can obj become NULL here.
236 // It happens when a mutator thread beats us by writing another value. In that
237 // case we don't need to do anything else.
238 if (UPDATE_REFS != CONCURRENT || !oopDesc::is_null(obj)) {
239 assert(!oopDesc::is_null(obj), "Must not be null here");
240 assert(heap->is_in(obj), "We shouldn't be calling this on objects not in the heap: " PTR_FORMAT, p2i(obj));
241 assert(oopDesc::bs()->is_safe(obj), "Only mark objects in from-space");
242
243 if (heap->mark(obj)) {
244 log_develop_trace(gc, marking)("Marked obj: " PTR_FORMAT, p2i((HeapWord*) obj));
245
246 bool pushed = q->push(ShenandoahMarkTask(obj));
247 assert(pushed, "overflow queue should always succeed pushing");
248 } else {
249 log_develop_trace(gc, marking)("Failed to mark obj (already marked): " PTR_FORMAT, p2i((HeapWord*) obj));
250 assert(heap->is_marked(obj), "Consistency: should be marked.");
251 }
252 }
253 }
254 }
255
256 #endif // SHARE_VM_GC_SHENANDOAH_SHENANDOAHCONCURRENTMARK_INLINE_HPP
|