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 }
|