< 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->cas_forward_to(obj, obj_mark)) {
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     // Save the markWord of promotion-failed objs in _preserved_marks for later
364     // restoration. This way we don't have to walk the young-gen to locate
365     // these promotion-failed objs.
366     _preserved_marks->push_always(obj, obj_mark);
367   }  else {
368     // We lost, someone else "owns" this object
369     guarantee(obj->is_forwarded(), "Object must be forwarded if the cas failed.");
370 
371     // No unallocation to worry about.
372     obj = obj->forwardee();
373   }
374 
375   log_develop_trace(gc, scavenge)("{promotion-failure %s " PTR_FORMAT " (%d)}", obj->klass()->internal_name(), p2i(obj), obj->size());

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(UseCompactObjectHeaders || 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_self_atomic(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     // Save the markWord of promotion-failed objs in _preserved_marks for later
364     // restoration. This way we don't have to walk the young-gen to locate
365     // these promotion-failed objs.
366     _preserved_marks->push_always(obj, obj_mark);
367   }  else {
368     // We lost, someone else "owns" this object
369     guarantee(obj->is_forwarded(), "Object must be forwarded if the cas failed.");
370 
371     // No unallocation to worry about.
372     obj = obj->forwardee();
373   }
374 
375   log_develop_trace(gc, scavenge)("{promotion-failure %s " PTR_FORMAT " (%d)}", obj->klass()->internal_name(), p2i(obj), obj->size());
< prev index next >