< prev index next >

src/hotspot/share/gc/g1/g1ConcurrentMark.inline.hpp

Print this page

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);
< prev index next >