162
163 // Finger and region values are all null or all non-null. We
164 // use _finger to check since we immediately use its value.
165 assert(_curr_region != nullptr, "invariant");
166 assert(_region_limit != nullptr, "invariant");
167 assert(_region_limit <= global_finger, "invariant");
168
169 // True if obj is less than the local finger, or is between
170 // the region limit and the global finger.
171 if (objAddr < _finger) {
172 return true;
173 } else if (objAddr < _region_limit) {
174 return false;
175 } // Else check global finger.
176 }
177 // Check global finger.
178 return objAddr < global_finger;
179 }
180
181 inline bool G1CMTask::should_be_sliced(oop obj) {
182 return obj->is_objArray() && ((objArrayOop)obj)->length() >= (int)ObjArrayMarkingStride;
183 }
184
185 inline void G1CMTask::process_array_chunk(objArrayOop obj, size_t start, size_t end) {
186 obj->oop_iterate_elements_range(_cm_oop_closure,
187 checked_cast<int>(start),
188 checked_cast<int>(end));
189 }
190
191 inline void G1ConcurrentMark::update_top_at_mark_start(G1HeapRegion* r) {
192 uint const region = r->hrm_index();
193 assert(region < _g1h->max_num_regions(), "Tried to access TAMS for region %u out of bounds", region);
194 _top_at_mark_starts[region].store_relaxed(r->top());
195 }
196
197 inline void G1ConcurrentMark::reset_top_at_mark_start(G1HeapRegion* r) {
198 _top_at_mark_starts[r->hrm_index()].store_relaxed(r->bottom());
199 }
200
201 inline HeapWord* G1ConcurrentMark::top_at_mark_start(const G1HeapRegion* r) const {
202 return top_at_mark_start(r->hrm_index());
203 }
204
205 inline HeapWord* G1ConcurrentMark::top_at_mark_start(uint region) const {
252 }
253
254 // No OrderAccess:store_load() is needed. It is implicit in the
255 // CAS done in G1CMBitMap::parMark() call in the routine above.
256 HeapWord* global_finger = _cm->finger();
257
258 // We only need to push a newly grey object on the mark
259 // stack if it is in a section of memory the mark bitmap
260 // scan has already examined. Mark bitmap scanning
261 // maintains progress "fingers" for determining that.
262 //
263 // Notice that the global finger might be moving forward
264 // concurrently. This is not a problem. In the worst case, we
265 // mark the object while it is above the global finger and, by
266 // the time we read the global finger, it has moved forward
267 // past this object. In this case, the object will probably
268 // be visited when a task is scanning the region and will also
269 // be pushed on the stack. So, some duplicate work, but no
270 // correctness problems.
271 if (is_below_finger(obj, global_finger)) {
272 if (obj->is_typeArray()) {
273 // Immediately process arrays of primitive types, rather
274 // than pushing on the mark stack. This keeps us from
275 // adding humongous objects to the mark stack that might
276 // be reclaimed before the entry is processed - see
277 // selection of candidates for eager reclaim of humongous
278 // objects. The cost of the additional type test is
279 // mitigated by avoiding a trip through the mark stack,
280 // by only doing a bookkeeping update and avoiding the
281 // actual scan of the object - a typeArray contains no
282 // references, and the metadata is built-in.
283 } else {
284 G1TaskQueueEntry entry(obj);
285 push(entry);
286 }
287 }
288 return true;
289 }
290
291 template <class T>
292 inline bool G1CMTask::deal_with_reference(T* p) {
293 increment_refs_reached();
294 oop const obj = RawAccess<MO_RELAXED>::oop_load(p);
295 if (obj == nullptr) {
296 return false;
297 }
298
299 if (!G1HeapRegion::is_in_same_region(p, obj)) {
300 inc_incoming_refs(obj);
301 }
302 return make_reference_grey(obj);
|
162
163 // Finger and region values are all null or all non-null. We
164 // use _finger to check since we immediately use its value.
165 assert(_curr_region != nullptr, "invariant");
166 assert(_region_limit != nullptr, "invariant");
167 assert(_region_limit <= global_finger, "invariant");
168
169 // True if obj is less than the local finger, or is between
170 // the region limit and the global finger.
171 if (objAddr < _finger) {
172 return true;
173 } else if (objAddr < _region_limit) {
174 return false;
175 } // Else check global finger.
176 }
177 // Check global finger.
178 return objAddr < global_finger;
179 }
180
181 inline bool G1CMTask::should_be_sliced(oop obj) {
182 return obj->is_array_with_oops() && ((objArrayOop)obj)->length() >= (int)ObjArrayMarkingStride;
183 }
184
185 inline void G1CMTask::process_array_chunk(objArrayOop obj, size_t start, size_t end) {
186 precond(obj->is_array_with_oops());
187 obj->oop_iterate_elements_range(_cm_oop_closure,
188 checked_cast<int>(start),
189 checked_cast<int>(end));
190 }
191
192 inline void G1ConcurrentMark::update_top_at_mark_start(G1HeapRegion* r) {
193 uint const region = r->hrm_index();
194 assert(region < _g1h->max_num_regions(), "Tried to access TAMS for region %u out of bounds", region);
195 _top_at_mark_starts[region].store_relaxed(r->top());
196 }
197
198 inline void G1ConcurrentMark::reset_top_at_mark_start(G1HeapRegion* r) {
199 _top_at_mark_starts[r->hrm_index()].store_relaxed(r->bottom());
200 }
201
202 inline HeapWord* G1ConcurrentMark::top_at_mark_start(const G1HeapRegion* r) const {
203 return top_at_mark_start(r->hrm_index());
204 }
205
206 inline HeapWord* G1ConcurrentMark::top_at_mark_start(uint region) const {
253 }
254
255 // No OrderAccess:store_load() is needed. It is implicit in the
256 // CAS done in G1CMBitMap::parMark() call in the routine above.
257 HeapWord* global_finger = _cm->finger();
258
259 // We only need to push a newly grey object on the mark
260 // stack if it is in a section of memory the mark bitmap
261 // scan has already examined. Mark bitmap scanning
262 // maintains progress "fingers" for determining that.
263 //
264 // Notice that the global finger might be moving forward
265 // concurrently. This is not a problem. In the worst case, we
266 // mark the object while it is above the global finger and, by
267 // the time we read the global finger, it has moved forward
268 // past this object. In this case, the object will probably
269 // be visited when a task is scanning the region and will also
270 // be pushed on the stack. So, some duplicate work, but no
271 // correctness problems.
272 if (is_below_finger(obj, global_finger)) {
273 if (_g1h->can_be_marked_through_immediately(obj)) {
274 // Immediately process arrays of types without oops, rather
275 // than pushing on the mark stack. This keeps us from
276 // adding humongous objects to the mark stack that might
277 // be reclaimed before the entry is processed - see
278 // selection of candidates for eager reclaim of humongous
279 // objects. The cost of the additional type test is
280 // mitigated by avoiding a trip through the mark stack,
281 // by only doing a bookkeeping update and avoiding the
282 // actual scan of the object - the object contains no
283 // references (but the metadata must be processed).
284 process_klass(obj->klass());
285 } else {
286 G1TaskQueueEntry entry(obj);
287 push(entry);
288 }
289 }
290 return true;
291 }
292
293 template <class T>
294 inline bool G1CMTask::deal_with_reference(T* p) {
295 increment_refs_reached();
296 oop const obj = RawAccess<MO_RELAXED>::oop_load(p);
297 if (obj == nullptr) {
298 return false;
299 }
300
301 if (!G1HeapRegion::is_in_same_region(p, obj)) {
302 inc_incoming_refs(obj);
303 }
304 return make_reference_grey(obj);
|