< prev index next >

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

Print this page

297 
298 template <class T> void PSPromotionManager::process_array_chunk_work(
299                                                  oop obj,
300                                                  int start, int end) {
301   assert(start <= end, "invariant");
302   T* const base      = (T*)objArrayOop(obj)->base();
303   T* p               = base + start;
304   T* const chunk_end = base + end;
305   while (p < chunk_end) {
306     if (PSScavenge::should_scavenge(p)) {
307       claim_or_forward_depth(p);
308     }
309     ++p;
310   }
311 }
312 
313 void PSPromotionManager::process_array_chunk(PartialArrayScanTask task) {
314   assert(PSChunkLargeArrays, "invariant");
315 
316   oop old = task.to_source_array();
317   assert(old->is_objArray(), "invariant");
318   assert(old->is_forwarded(), "invariant");
319 
320   TASKQUEUE_STATS_ONLY(++_array_chunks_processed);
321 
322   oop const obj = old->forwardee();
323 
324   int start;
325   int const end = arrayOop(old)->length();
326   if (end > (int) _min_array_size_for_chunking) {
327     // we'll chunk more
328     start = end - _array_chunk_size;
329     assert(start > 0, "invariant");
330     arrayOop(old)->set_length(start);
331     push_depth(ScannerTask(PartialArrayScanTask(old)));
332     TASKQUEUE_STATS_ONLY(++_array_chunk_pushes);
333   } else {
334     // this is the final chunk for this array
335     start = 0;
336     int const actual_length = arrayOop(obj)->length();
337     arrayOop(old)->set_length(actual_length);
338   }
339 
340   if (UseCompressedOops) {
341     process_array_chunk_work<narrowOop>(obj, start, end);
342   } else {
343     process_array_chunk_work<oop>(obj, start, end);
344   }
345 }
346 
347 oop PSPromotionManager::oop_promotion_failed(oop obj, markWord obj_mark) {
348   assert(_old_gen_is_full || PromotionFailureALot, "Sanity");
349 
350   // Attempt to CAS in the header.
351   // This tests if the header is still the same as when
352   // this started.  If it is the same (i.e., no forwarding
353   // pointer has been installed), then this thread owns
354   // it.
355   if (obj->forward_to_atomic(obj, obj_mark) == NULL) {
356     // We won any races, we "own" this object.
357     assert(obj == obj->forwardee(), "Sanity");
358 
359     _promotion_failed_info.register_copy_failure(obj->size());
360 
361     push_contents(obj);
362 
363     _preserved_marks->push_if_necessary(obj, obj_mark);
364   }  else {
365     // We lost, someone else "owns" this object
366     guarantee(obj->is_forwarded(), "Object must be forwarded if the cas failed.");
367 
368     // No unallocation to worry about.
369     obj = obj->forwardee();
370   }
371 
372   return obj;
373 }

297 
298 template <class T> void PSPromotionManager::process_array_chunk_work(
299                                                  oop obj,
300                                                  int start, int end) {
301   assert(start <= end, "invariant");
302   T* const base      = (T*)objArrayOop(obj)->base();
303   T* p               = base + start;
304   T* const chunk_end = base + end;
305   while (p < chunk_end) {
306     if (PSScavenge::should_scavenge(p)) {
307       claim_or_forward_depth(p);
308     }
309     ++p;
310   }
311 }
312 
313 void PSPromotionManager::process_array_chunk(PartialArrayScanTask task) {
314   assert(PSChunkLargeArrays, "invariant");
315 
316   oop old = task.to_source_array();

317   assert(old->is_forwarded(), "invariant");
318 
319   TASKQUEUE_STATS_ONLY(++_array_chunks_processed);
320 
321   oop const obj = old->forwardee();
322 
323   int start;
324   int const end = arrayOop(old)->length();
325   if (end > (int) _min_array_size_for_chunking) {
326     // we'll chunk more
327     start = end - _array_chunk_size;
328     assert(start > 0, "invariant");
329     arrayOop(old)->set_length(start);
330     push_depth(ScannerTask(PartialArrayScanTask(old)));
331     TASKQUEUE_STATS_ONLY(++_array_chunk_pushes);
332   } else {
333     // this is the final chunk for this array
334     start = 0;
335     int const actual_length = arrayOop(obj)->length();
336     arrayOop(old)->set_length(actual_length);
337   }
338 
339   if (UseCompressedOops) {
340     process_array_chunk_work<narrowOop>(obj, start, end);
341   } else {
342     process_array_chunk_work<oop>(obj, start, end);
343   }
344 }
345 
346 oop PSPromotionManager::oop_promotion_failed(oop obj, markWord obj_mark) {
347   assert(_old_gen_is_full || PromotionFailureALot, "Sanity");
348 
349   // Attempt to CAS in the header.
350   // This tests if the header is still the same as when
351   // this started.  If it is the same (i.e., no forwarding
352   // pointer has been installed), then this thread owns
353   // it.
354   if (obj->forward_to_self_atomic(obj_mark) == NULL) {
355     // We won any races, we "own" this object.
356     assert(obj == obj->forwardee(), "Sanity");
357 
358     _promotion_failed_info.register_copy_failure(obj->size());
359 
360     push_contents(obj);
361 
362     _preserved_marks->push_if_necessary(obj, obj_mark);
363   }  else {
364     // We lost, someone else "owns" this object
365     guarantee(obj->is_forwarded(), "Object must be forwarded if the cas failed.");
366 
367     // No unallocation to worry about.
368     obj = obj->forwardee();
369   }
370 
371   return obj;
372 }
< prev index next >