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