44 // References pushed onto the work stack should never point to a humongous region
45 // as they are not added to the collection set due to above precondition.
46 assert(!in_cset_state.is_humongous(),
47 "Obj " PTR_FORMAT " should not refer to humongous region %u from " PTR_FORMAT,
48 p2i(obj), _g1h->addr_to_region((HeapWord*)obj), p2i(p));
49
50 if (!in_cset_state.is_in_cset()) {
51 // In this case somebody else already did all the work.
52 return;
53 }
54
55 markOop m = obj->mark_raw();
56 if (m->is_marked()) {
57 obj = (oop) m->decode_pointer();
58 } else {
59 obj = copy_to_survivor_space(in_cset_state, obj, m);
60 }
61 RawAccess<IS_NOT_NULL>::oop_store(p, obj);
62
63 assert(obj != NULL, "Must be");
64 if (!HeapRegion::is_in_same_region(p, obj)) {
65 HeapRegion* from = _g1h->heap_region_containing(p);
66 update_rs(from, p, obj);
67 }
68 }
69
70 template <class T> inline void G1ParScanThreadState::push_on_queue(T* ref) {
71 assert(verify_ref(ref), "sanity");
72 _refs->push(ref);
73 }
74
75 inline void G1ParScanThreadState::do_oop_partial_array(oop* p) {
76 assert(has_partial_array_mask(p), "invariant");
77 oop from_obj = clear_partial_array_mask(p);
78
79 assert(_g1h->is_in_reserved(from_obj), "must be in heap.");
80 assert(from_obj->is_objArray(), "must be obj array");
81 objArrayOop from_obj_array = objArrayOop(from_obj);
82 // The from-space object contains the real length.
83 int length = from_obj_array->length();
84
85 assert(from_obj->is_forwarded(), "must be forwarded");
86 oop to_obj = from_obj->forwardee();
92 assert(0 <= next_index && next_index < length,
93 "invariant, next index: %d, length: %d", next_index, length);
94
95 int start = next_index;
96 int end = length;
97 int remainder = end - start;
98 // We'll try not to push a range that's smaller than ParGCArrayScanChunk.
99 if (remainder > 2 * ParGCArrayScanChunk) {
100 end = start + ParGCArrayScanChunk;
101 to_obj_array->set_length(end);
102 // Push the remainder before we process the range in case another
103 // worker has run out of things to do and can steal it.
104 oop* from_obj_p = set_partial_array_mask(from_obj);
105 push_on_queue(from_obj_p);
106 } else {
107 assert(length == end, "sanity");
108 // We'll process the final range for this object. Restore the length
109 // so that the heap remains parsable in case of evacuation failure.
110 to_obj_array->set_length(end);
111 }
112 _scanner.set_region(_g1h->heap_region_containing(to_obj));
113 // Process indexes [start,end). It will also process the header
114 // along with the first chunk (i.e., the chunk with start == 0).
115 // Note that at this point the length field of to_obj_array is not
116 // correct given that we are using it to keep track of the next
117 // start index. oop_iterate_range() (thankfully!) ignores the length
118 // field and only relies on the start / end parameters. It does
119 // however return the size of the object which will be incorrect. So
120 // we have to ignore it even if we wanted to use it.
121 to_obj_array->oop_iterate_range(&_scanner, start, end);
122 }
123
124 inline void G1ParScanThreadState::deal_with_reference(oop* ref_to_scan) {
125 if (!has_partial_array_mask(ref_to_scan)) {
126 do_oop_evac(ref_to_scan);
127 } else {
128 do_oop_partial_array(ref_to_scan);
129 }
130 }
131
132 inline void G1ParScanThreadState::deal_with_reference(narrowOop* ref_to_scan) {
|
44 // References pushed onto the work stack should never point to a humongous region
45 // as they are not added to the collection set due to above precondition.
46 assert(!in_cset_state.is_humongous(),
47 "Obj " PTR_FORMAT " should not refer to humongous region %u from " PTR_FORMAT,
48 p2i(obj), _g1h->addr_to_region((HeapWord*)obj), p2i(p));
49
50 if (!in_cset_state.is_in_cset()) {
51 // In this case somebody else already did all the work.
52 return;
53 }
54
55 markOop m = obj->mark_raw();
56 if (m->is_marked()) {
57 obj = (oop) m->decode_pointer();
58 } else {
59 obj = copy_to_survivor_space(in_cset_state, obj, m);
60 }
61 RawAccess<IS_NOT_NULL>::oop_store(p, obj);
62
63 assert(obj != NULL, "Must be");
64 if (HeapRegion::is_in_same_region(p, obj)) {
65 return;
66 }
67 HeapRegion* from = _g1h->heap_region_containing(p);
68 if (!from->is_young()) {
69 enqueue_card_if_tracked(p, obj);
70 }
71 }
72
73 template <class T> inline void G1ParScanThreadState::push_on_queue(T* ref) {
74 assert(verify_ref(ref), "sanity");
75 _refs->push(ref);
76 }
77
78 inline void G1ParScanThreadState::do_oop_partial_array(oop* p) {
79 assert(has_partial_array_mask(p), "invariant");
80 oop from_obj = clear_partial_array_mask(p);
81
82 assert(_g1h->is_in_reserved(from_obj), "must be in heap.");
83 assert(from_obj->is_objArray(), "must be obj array");
84 objArrayOop from_obj_array = objArrayOop(from_obj);
85 // The from-space object contains the real length.
86 int length = from_obj_array->length();
87
88 assert(from_obj->is_forwarded(), "must be forwarded");
89 oop to_obj = from_obj->forwardee();
95 assert(0 <= next_index && next_index < length,
96 "invariant, next index: %d, length: %d", next_index, length);
97
98 int start = next_index;
99 int end = length;
100 int remainder = end - start;
101 // We'll try not to push a range that's smaller than ParGCArrayScanChunk.
102 if (remainder > 2 * ParGCArrayScanChunk) {
103 end = start + ParGCArrayScanChunk;
104 to_obj_array->set_length(end);
105 // Push the remainder before we process the range in case another
106 // worker has run out of things to do and can steal it.
107 oop* from_obj_p = set_partial_array_mask(from_obj);
108 push_on_queue(from_obj_p);
109 } else {
110 assert(length == end, "sanity");
111 // We'll process the final range for this object. Restore the length
112 // so that the heap remains parsable in case of evacuation failure.
113 to_obj_array->set_length(end);
114 }
115
116 HeapRegion* hr = _g1h->heap_region_containing(to_obj);
117 _scanner.set_scanning_in_young(hr->is_young());
118 // Process indexes [start,end). It will also process the header
119 // along with the first chunk (i.e., the chunk with start == 0).
120 // Note that at this point the length field of to_obj_array is not
121 // correct given that we are using it to keep track of the next
122 // start index. oop_iterate_range() (thankfully!) ignores the length
123 // field and only relies on the start / end parameters. It does
124 // however return the size of the object which will be incorrect. So
125 // we have to ignore it even if we wanted to use it.
126 to_obj_array->oop_iterate_range(&_scanner, start, end);
127 }
128
129 inline void G1ParScanThreadState::deal_with_reference(oop* ref_to_scan) {
130 if (!has_partial_array_mask(ref_to_scan)) {
131 do_oop_evac(ref_to_scan);
132 } else {
133 do_oop_partial_array(ref_to_scan);
134 }
135 }
136
137 inline void G1ParScanThreadState::deal_with_reference(narrowOop* ref_to_scan) {
|