< prev index next >

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

Print this page

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