< prev index next >

src/hotspot/share/gc/g1/g1ParScanThreadState.cpp

Print this page
rev 52316 : imported patch 8212911-unify-reference-handling-during-gc
rev 52317 : imported patch 8212911-stefanj-review
rev 52319 : imported patch 8213142-use-raii-to-set-scanning-from-young


 294       assert(is_from_young == _g1h->heap_region_containing(old)->is_young(),
 295              "sanity");
 296       assert(is_to_young == _g1h->heap_region_containing(obj)->is_young(),
 297              "sanity");
 298       G1StringDedup::enqueue_from_evacuation(is_from_young,
 299                                              is_to_young,
 300                                              _worker_id,
 301                                              obj);
 302     }
 303 
 304     _surviving_young_words[young_index] += word_sz;
 305 
 306     if (obj->is_objArray() && arrayOop(obj)->length() >= ParGCArrayScanChunk) {
 307       // We keep track of the next start index in the length field of
 308       // the to-space object. The actual length can be found in the
 309       // length field of the from-space object.
 310       arrayOop(obj)->set_length(0);
 311       oop* old_p = set_partial_array_mask(old);
 312       do_oop_partial_array(old_p);
 313     } else {
 314       _scanner.set_scanning_in_young(dest_state.is_young());
 315       obj->oop_iterate_backwards(&_scanner);
 316     }
 317     return obj;
 318   } else {
 319     _plab_allocator->undo_allocation(dest_state, obj_ptr, word_sz);
 320     return forward_ptr;
 321   }
 322 }
 323 
 324 G1ParScanThreadState* G1ParScanThreadStateSet::state_for_worker(uint worker_id) {
 325   assert(worker_id < _n_workers, "out of bounds access");
 326   if (_states[worker_id] == NULL) {
 327     _states[worker_id] = new G1ParScanThreadState(_g1h, worker_id, _young_cset_length);
 328   }
 329   return _states[worker_id];
 330 }
 331 
 332 const size_t* G1ParScanThreadStateSet::surviving_young_words() const {
 333   assert(_flushed, "thread local state from the per thread states should have been flushed");
 334   return _surviving_young_words_total;


 349     _states[worker_index] = NULL;
 350   }
 351   _flushed = true;
 352 }
 353 
 354 oop G1ParScanThreadState::handle_evacuation_failure_par(oop old, markOop m) {
 355   assert(_g1h->is_in_cset(old), "Object " PTR_FORMAT " should be in the CSet", p2i(old));
 356 
 357   oop forward_ptr = old->forward_to_atomic(old, m, memory_order_relaxed);
 358   if (forward_ptr == NULL) {
 359     // Forward-to-self succeeded. We are the "owner" of the object.
 360     HeapRegion* r = _g1h->heap_region_containing(old);
 361 
 362     if (!r->evacuation_failed()) {
 363       r->set_evacuation_failed(true);
 364      _g1h->hr_printer()->evac_failure(r);
 365     }
 366 
 367     _g1h->preserve_mark_during_evac_failure(_worker_id, old, m);
 368 
 369     _scanner.set_scanning_in_young(r->is_young());
 370     old->oop_iterate_backwards(&_scanner);
 371 
 372     return old;
 373   } else {
 374     // Forward-to-self failed. Either someone else managed to allocate
 375     // space for this object (old != forward_ptr) or they beat us in
 376     // self-forwarding it (old == forward_ptr).
 377     assert(old == forward_ptr || !_g1h->is_in_cset(forward_ptr),
 378            "Object " PTR_FORMAT " forwarded to: " PTR_FORMAT " "
 379            "should not be in the CSet",
 380            p2i(old), p2i(forward_ptr));
 381     return forward_ptr;
 382   }
 383 }
 384 G1ParScanThreadStateSet::G1ParScanThreadStateSet(G1CollectedHeap* g1h, uint n_workers, size_t young_cset_length) :
 385     _g1h(g1h),
 386     _states(NEW_C_HEAP_ARRAY(G1ParScanThreadState*, n_workers, mtGC)),
 387     _surviving_young_words_total(NEW_C_HEAP_ARRAY(size_t, young_cset_length, mtGC)),
 388     _young_cset_length(young_cset_length),
 389     _n_workers(n_workers),


 294       assert(is_from_young == _g1h->heap_region_containing(old)->is_young(),
 295              "sanity");
 296       assert(is_to_young == _g1h->heap_region_containing(obj)->is_young(),
 297              "sanity");
 298       G1StringDedup::enqueue_from_evacuation(is_from_young,
 299                                              is_to_young,
 300                                              _worker_id,
 301                                              obj);
 302     }
 303 
 304     _surviving_young_words[young_index] += word_sz;
 305 
 306     if (obj->is_objArray() && arrayOop(obj)->length() >= ParGCArrayScanChunk) {
 307       // We keep track of the next start index in the length field of
 308       // the to-space object. The actual length can be found in the
 309       // length field of the from-space object.
 310       arrayOop(obj)->set_length(0);
 311       oop* old_p = set_partial_array_mask(old);
 312       do_oop_partial_array(old_p);
 313     } else {
 314       G1ScanInYoungSetter x(&_scanner, dest_state.is_young());
 315       obj->oop_iterate_backwards(&_scanner);
 316     }
 317     return obj;
 318   } else {
 319     _plab_allocator->undo_allocation(dest_state, obj_ptr, word_sz);
 320     return forward_ptr;
 321   }
 322 }
 323 
 324 G1ParScanThreadState* G1ParScanThreadStateSet::state_for_worker(uint worker_id) {
 325   assert(worker_id < _n_workers, "out of bounds access");
 326   if (_states[worker_id] == NULL) {
 327     _states[worker_id] = new G1ParScanThreadState(_g1h, worker_id, _young_cset_length);
 328   }
 329   return _states[worker_id];
 330 }
 331 
 332 const size_t* G1ParScanThreadStateSet::surviving_young_words() const {
 333   assert(_flushed, "thread local state from the per thread states should have been flushed");
 334   return _surviving_young_words_total;


 349     _states[worker_index] = NULL;
 350   }
 351   _flushed = true;
 352 }
 353 
 354 oop G1ParScanThreadState::handle_evacuation_failure_par(oop old, markOop m) {
 355   assert(_g1h->is_in_cset(old), "Object " PTR_FORMAT " should be in the CSet", p2i(old));
 356 
 357   oop forward_ptr = old->forward_to_atomic(old, m, memory_order_relaxed);
 358   if (forward_ptr == NULL) {
 359     // Forward-to-self succeeded. We are the "owner" of the object.
 360     HeapRegion* r = _g1h->heap_region_containing(old);
 361 
 362     if (!r->evacuation_failed()) {
 363       r->set_evacuation_failed(true);
 364      _g1h->hr_printer()->evac_failure(r);
 365     }
 366 
 367     _g1h->preserve_mark_during_evac_failure(_worker_id, old, m);
 368 
 369     G1ScanInYoungSetter x(&_scanner, r->is_young());
 370     old->oop_iterate_backwards(&_scanner);
 371 
 372     return old;
 373   } else {
 374     // Forward-to-self failed. Either someone else managed to allocate
 375     // space for this object (old != forward_ptr) or they beat us in
 376     // self-forwarding it (old == forward_ptr).
 377     assert(old == forward_ptr || !_g1h->is_in_cset(forward_ptr),
 378            "Object " PTR_FORMAT " forwarded to: " PTR_FORMAT " "
 379            "should not be in the CSet",
 380            p2i(old), p2i(forward_ptr));
 381     return forward_ptr;
 382   }
 383 }
 384 G1ParScanThreadStateSet::G1ParScanThreadStateSet(G1CollectedHeap* g1h, uint n_workers, size_t young_cset_length) :
 385     _g1h(g1h),
 386     _states(NEW_C_HEAP_ARRAY(G1ParScanThreadState*, n_workers, mtGC)),
 387     _surviving_young_words_total(NEW_C_HEAP_ARRAY(size_t, young_cset_length, mtGC)),
 388     _young_cset_length(young_cset_length),
 389     _n_workers(n_workers),
< prev index next >