163
164 // Finger and region values are all null or all non-null. We
165 // use _finger to check since we immediately use its value.
166 assert(_curr_region != nullptr, "invariant");
167 assert(_region_limit != nullptr, "invariant");
168 assert(_region_limit <= global_finger, "invariant");
169
170 // True if obj is less than the local finger, or is between
171 // the region limit and the global finger.
172 if (objAddr < _finger) {
173 return true;
174 } else if (objAddr < _region_limit) {
175 return false;
176 } // Else check global finger.
177 }
178 // Check global finger.
179 return objAddr < global_finger;
180 }
181
182 inline bool G1CMTask::should_be_sliced(oop obj) {
183 return obj->is_objArray() && ((objArrayOop)obj)->length() >= (int)ObjArrayMarkingStride;
184 }
185
186 inline void G1CMTask::process_array_chunk(objArrayOop obj, size_t start, size_t end) {
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 assert_fully_initialized();
194 assert(_g1h->collector_state()->is_in_concurrent_start_gc(), "must be");
195 uint const region = r->hrm_index();
196 assert(region < _g1h->max_num_regions(), "Tried to access TAMS for region %u out of bounds", region);
197 _top_at_mark_starts[region].store_relaxed(r->top());
198 }
199
200 inline void G1ConcurrentMark::set_top_at_mark_start_to_bottom(G1HeapRegion* r) {
201 assert_fully_initialized();
202 _top_at_mark_starts[r->hrm_index()].store_relaxed(r->bottom());
203 }
204
205 inline void G1ConcurrentMark::assert_top_at_mark_start_is_bottom(G1HeapRegion* r) {
206 // Can not assert anything if not initialized.
324 }
325
326 // No OrderAccess:store_load() is needed. It is implicit in the
327 // CAS done in G1CMBitMap::parMark() call in the routine above.
328 HeapWord* global_finger = _cm->finger();
329
330 // We only need to push a newly grey object on the mark
331 // stack if it is in a section of memory the mark bitmap
332 // scan has already examined. Mark bitmap scanning
333 // maintains progress "fingers" for determining that.
334 //
335 // Notice that the global finger might be moving forward
336 // concurrently. This is not a problem. In the worst case, we
337 // mark the object while it is above the global finger and, by
338 // the time we read the global finger, it has moved forward
339 // past this object. In this case, the object will probably
340 // be visited when a task is scanning the region and will also
341 // be pushed on the stack. So, some duplicate work, but no
342 // correctness problems.
343 if (is_below_finger(obj, global_finger)) {
344 if (obj->is_typeArray()) {
345 // Immediately process arrays of primitive types, rather
346 // than pushing on the mark stack. This keeps us from
347 // adding humongous objects to the mark stack that might
348 // be reclaimed before the entry is processed - see
349 // selection of candidates for eager reclaim of humongous
350 // objects. The cost of the additional type test is
351 // mitigated by avoiding a trip through the mark stack,
352 // by only doing a bookkeeping update and avoiding the
353 // actual scan of the object - a typeArray contains no
354 // references, and the metadata is built-in.
355 } else {
356 G1TaskQueueEntry entry(obj);
357 push(entry);
358 }
359 }
360 return true;
361 }
362
363 template <class T>
364 inline bool G1CMTask::deal_with_reference(T* p) {
365 increment_refs_reached();
366 oop const obj = RawAccess<MO_RELAXED>::oop_load(p);
367 if (obj == nullptr) {
368 return false;
369 }
370
371 if (!G1HeapRegion::is_in_same_region(p, obj)) {
372 inc_incoming_refs(obj);
373 }
374 return make_reference_grey(obj);
|
163
164 // Finger and region values are all null or all non-null. We
165 // use _finger to check since we immediately use its value.
166 assert(_curr_region != nullptr, "invariant");
167 assert(_region_limit != nullptr, "invariant");
168 assert(_region_limit <= global_finger, "invariant");
169
170 // True if obj is less than the local finger, or is between
171 // the region limit and the global finger.
172 if (objAddr < _finger) {
173 return true;
174 } else if (objAddr < _region_limit) {
175 return false;
176 } // Else check global finger.
177 }
178 // Check global finger.
179 return objAddr < global_finger;
180 }
181
182 inline bool G1CMTask::should_be_sliced(oop obj) {
183 return obj->is_array_with_oops() && ((objArrayOop)obj)->length() >= (int)ObjArrayMarkingStride;
184 }
185
186 inline void G1CMTask::process_array_chunk(objArrayOop obj, size_t start, size_t end) {
187 precond(obj->is_array_with_oops());
188 obj->oop_iterate_elements_range(_cm_oop_closure,
189 checked_cast<int>(start),
190 checked_cast<int>(end));
191 }
192
193 inline void G1ConcurrentMark::update_top_at_mark_start(G1HeapRegion* r) {
194 assert_fully_initialized();
195 assert(_g1h->collector_state()->is_in_concurrent_start_gc(), "must be");
196 uint const region = r->hrm_index();
197 assert(region < _g1h->max_num_regions(), "Tried to access TAMS for region %u out of bounds", region);
198 _top_at_mark_starts[region].store_relaxed(r->top());
199 }
200
201 inline void G1ConcurrentMark::set_top_at_mark_start_to_bottom(G1HeapRegion* r) {
202 assert_fully_initialized();
203 _top_at_mark_starts[r->hrm_index()].store_relaxed(r->bottom());
204 }
205
206 inline void G1ConcurrentMark::assert_top_at_mark_start_is_bottom(G1HeapRegion* r) {
207 // Can not assert anything if not initialized.
325 }
326
327 // No OrderAccess:store_load() is needed. It is implicit in the
328 // CAS done in G1CMBitMap::parMark() call in the routine above.
329 HeapWord* global_finger = _cm->finger();
330
331 // We only need to push a newly grey object on the mark
332 // stack if it is in a section of memory the mark bitmap
333 // scan has already examined. Mark bitmap scanning
334 // maintains progress "fingers" for determining that.
335 //
336 // Notice that the global finger might be moving forward
337 // concurrently. This is not a problem. In the worst case, we
338 // mark the object while it is above the global finger and, by
339 // the time we read the global finger, it has moved forward
340 // past this object. In this case, the object will probably
341 // be visited when a task is scanning the region and will also
342 // be pushed on the stack. So, some duplicate work, but no
343 // correctness problems.
344 if (is_below_finger(obj, global_finger)) {
345 if (_g1h->can_be_marked_through_immediately(obj)) {
346 // Immediately process arrays of types without oops, rather
347 // than pushing on the mark stack. This keeps us from
348 // adding humongous objects to the mark stack that might
349 // be reclaimed before the entry is processed - see
350 // selection of candidates for eager reclaim of humongous
351 // objects. The cost of the additional type test is
352 // mitigated by avoiding a trip through the mark stack,
353 // by only doing a bookkeeping update and avoiding the
354 // actual scan of the object - the object contains no
355 // references (but the metadata must be processed).
356 process_klass(obj->klass());
357 } else {
358 G1TaskQueueEntry entry(obj);
359 push(entry);
360 }
361 }
362 return true;
363 }
364
365 template <class T>
366 inline bool G1CMTask::deal_with_reference(T* p) {
367 increment_refs_reached();
368 oop const obj = RawAccess<MO_RELAXED>::oop_load(p);
369 if (obj == nullptr) {
370 return false;
371 }
372
373 if (!G1HeapRegion::is_in_same_region(p, obj)) {
374 inc_incoming_refs(obj);
375 }
376 return make_reference_grey(obj);
|