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) {
|
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 G1ScanInYoungSetter x(&_scanner, 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) {
|