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());
|