< prev index next >

src/hotspot/share/gc/parallel/psPromotionManager.cpp

Print this page

278 
279 template <class T> void PSPromotionManager::process_array_chunk_work(
280                                                  oop obj,
281                                                  int start, int end) {
282   assert(start <= end, "invariant");
283   T* const base      = (T*)objArrayOop(obj)->base();
284   T* p               = base + start;
285   T* const chunk_end = base + end;
286   while (p < chunk_end) {
287     if (PSScavenge::should_scavenge(p)) {
288       claim_or_forward_depth(p);
289     }
290     ++p;
291   }
292 }
293 
294 void PSPromotionManager::process_array_chunk(PartialArrayScanTask task) {
295   assert(PSChunkLargeArrays, "invariant");
296 
297   oop old = task.to_source_array();
298   assert(old->is_objArray(), "invariant");
299   assert(old->is_forwarded(), "invariant");
300 
301   TASKQUEUE_STATS_ONLY(++_array_chunks_processed);
302 
303   oop const obj = old->forwardee();
304 
305   int start;
306   int const end = arrayOop(old)->length();
307   if (end > (int) _min_array_size_for_chunking) {
308     // we'll chunk more
309     start = end - _array_chunk_size;
310     assert(start > 0, "invariant");
311     arrayOop(old)->set_length(start);
312     push_depth(ScannerTask(PartialArrayScanTask(old)));
313     TASKQUEUE_STATS_ONLY(++_array_chunk_pushes);
314   } else {
315     // this is the final chunk for this array
316     start = 0;
317     int const actual_length = arrayOop(obj)->length();
318     arrayOop(old)->set_length(actual_length);
319   }
320 
321   if (UseCompressedOops) {
322     process_array_chunk_work<narrowOop>(obj, start, end);
323   } else {
324     process_array_chunk_work<oop>(obj, start, end);
325   }
326 }
327 
328 oop PSPromotionManager::oop_promotion_failed(oop obj, markWord obj_mark) {
329   assert(_old_gen_is_full || PromotionFailureALot, "Sanity");
330 
331   // Attempt to CAS in the header.
332   // This tests if the header is still the same as when
333   // this started.  If it is the same (i.e., no forwarding
334   // pointer has been installed), then this thread owns
335   // it.
336   if (obj->forward_to_atomic(obj, obj_mark) == nullptr) {
337     // We won any races, we "own" this object.
338     assert(obj == obj->forwardee(), "Sanity");
339 
340     _promotion_failed_info.register_copy_failure(obj->size());
341 
342     ContinuationGCSupport::transform_stack_chunk(obj);
343 
344     push_contents(obj);
345 
346     // Save the markWord of promotion-failed objs in _preserved_marks for later
347     // restoration. This way we don't have to walk the young-gen to locate
348     // these promotion-failed objs.
349     _preserved_marks->push_always(obj, obj_mark);
350   }  else {
351     // We lost, someone else "owns" this object
352     guarantee(obj->is_forwarded(), "Object must be forwarded if the cas failed.");
353 
354     // No unallocation to worry about.
355     obj = obj->forwardee();
356   }

278 
279 template <class T> void PSPromotionManager::process_array_chunk_work(
280                                                  oop obj,
281                                                  int start, int end) {
282   assert(start <= end, "invariant");
283   T* const base      = (T*)objArrayOop(obj)->base();
284   T* p               = base + start;
285   T* const chunk_end = base + end;
286   while (p < chunk_end) {
287     if (PSScavenge::should_scavenge(p)) {
288       claim_or_forward_depth(p);
289     }
290     ++p;
291   }
292 }
293 
294 void PSPromotionManager::process_array_chunk(PartialArrayScanTask task) {
295   assert(PSChunkLargeArrays, "invariant");
296 
297   oop old = task.to_source_array();
298   assert(old->forward_safe_klass()->is_objArray_klass(), "invariant");
299   assert(old->is_forwarded(), "invariant");
300 
301   TASKQUEUE_STATS_ONLY(++_array_chunks_processed);
302 
303   oop const obj = old->forwardee();
304 
305   int start;
306   int const end = arrayOop(old)->length();
307   if (end > (int) _min_array_size_for_chunking) {
308     // we'll chunk more
309     start = end - _array_chunk_size;
310     assert(start > 0, "invariant");
311     arrayOop(old)->set_length(start);
312     push_depth(ScannerTask(PartialArrayScanTask(old)));
313     TASKQUEUE_STATS_ONLY(++_array_chunk_pushes);
314   } else {
315     // this is the final chunk for this array
316     start = 0;
317     int const actual_length = arrayOop(obj)->length();
318     arrayOop(old)->set_length(actual_length);
319   }
320 
321   if (UseCompressedOops) {
322     process_array_chunk_work<narrowOop>(obj, start, end);
323   } else {
324     process_array_chunk_work<oop>(obj, start, end);
325   }
326 }
327 
328 oop PSPromotionManager::oop_promotion_failed(oop obj, markWord obj_mark) {
329   assert(_old_gen_is_full || PromotionFailureALot, "Sanity");
330 
331   // Attempt to CAS in the header.
332   // This tests if the header is still the same as when
333   // this started.  If it is the same (i.e., no forwarding
334   // pointer has been installed), then this thread owns
335   // it.
336   if (obj->forward_to_self_atomic(obj_mark) == nullptr) {
337     // We won any races, we "own" this object.
338     assert(obj == obj->forwardee(), "Sanity");
339 
340     _promotion_failed_info.register_copy_failure(obj->size());
341 
342     ContinuationGCSupport::transform_stack_chunk(obj);
343 
344     push_contents(obj);
345 
346     // Save the markWord of promotion-failed objs in _preserved_marks for later
347     // restoration. This way we don't have to walk the young-gen to locate
348     // these promotion-failed objs.
349     _preserved_marks->push_always(obj, obj_mark);
350   }  else {
351     // We lost, someone else "owns" this object
352     guarantee(obj->is_forwarded(), "Object must be forwarded if the cas failed.");
353 
354     // No unallocation to worry about.
355     obj = obj->forwardee();
356   }
< prev index next >