comparison src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @ 4836:d30fa85f9994

6484965: G1: piggy-back liveness accounting phase on marking Summary: Remove the separate counting phase of concurrent marking by tracking the amount of marked bytes and the cards spanned by marked objects in marking task/worker thread local data structures, which are updated as individual objects are marked. Reviewed-by: brutisso, tonyp
author johnc
date Thu, 12 Jan 2012 00:06:47 -0800
parents 6a78aa6ac1ff
children eff609af17d7
comparison
equal deleted inserted replaced
4835:877914d90c57 4836:d30fa85f9994
4198 } 4198 }
4199 4199
4200 G1ParGCAllocBuffer::G1ParGCAllocBuffer(size_t gclab_word_size) : 4200 G1ParGCAllocBuffer::G1ParGCAllocBuffer(size_t gclab_word_size) :
4201 ParGCAllocBuffer(gclab_word_size), _retired(false) { } 4201 ParGCAllocBuffer(gclab_word_size), _retired(false) { }
4202 4202
4203 G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, int queue_num) 4203 G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, uint queue_num)
4204 : _g1h(g1h), 4204 : _g1h(g1h),
4205 _refs(g1h->task_queue(queue_num)), 4205 _refs(g1h->task_queue(queue_num)),
4206 _dcq(&g1h->dirty_card_queue_set()), 4206 _dcq(&g1h->dirty_card_queue_set()),
4207 _ct_bs((CardTableModRefBS*)_g1h->barrier_set()), 4207 _ct_bs((CardTableModRefBS*)_g1h->barrier_set()),
4208 _g1_rem(g1h->g1_rem_set()), 4208 _g1_rem(g1h->g1_rem_set()),
4319 4319
4320 G1ParClosureSuper::G1ParClosureSuper(G1CollectedHeap* g1, 4320 G1ParClosureSuper::G1ParClosureSuper(G1CollectedHeap* g1,
4321 G1ParScanThreadState* par_scan_state) : 4321 G1ParScanThreadState* par_scan_state) :
4322 _g1(g1), _g1_rem(_g1->g1_rem_set()), _cm(_g1->concurrent_mark()), 4322 _g1(g1), _g1_rem(_g1->g1_rem_set()), _cm(_g1->concurrent_mark()),
4323 _par_scan_state(par_scan_state), 4323 _par_scan_state(par_scan_state),
4324 _worker_id(par_scan_state->queue_num()),
4324 _during_initial_mark(_g1->g1_policy()->during_initial_mark_pause()), 4325 _during_initial_mark(_g1->g1_policy()->during_initial_mark_pause()),
4325 _mark_in_progress(_g1->mark_in_progress()) { } 4326 _mark_in_progress(_g1->mark_in_progress()) { }
4326 4327
4327 void G1ParCopyHelper::mark_object(oop obj) { 4328 void G1ParCopyHelper::mark_object(oop obj) {
4328 #ifdef ASSERT 4329 #ifdef ASSERT
4330 assert(hr != NULL, "sanity"); 4331 assert(hr != NULL, "sanity");
4331 assert(!hr->in_collection_set(), "should not mark objects in the CSet"); 4332 assert(!hr->in_collection_set(), "should not mark objects in the CSet");
4332 #endif // ASSERT 4333 #endif // ASSERT
4333 4334
4334 // We know that the object is not moving so it's safe to read its size. 4335 // We know that the object is not moving so it's safe to read its size.
4335 _cm->grayRoot(obj, (size_t) obj->size()); 4336 _cm->grayRoot(obj, (size_t) obj->size(), _worker_id);
4336 } 4337 }
4337 4338
4338 void G1ParCopyHelper::mark_forwarded_object(oop from_obj, oop to_obj) { 4339 void G1ParCopyHelper::mark_forwarded_object(oop from_obj, oop to_obj) {
4339 #ifdef ASSERT 4340 #ifdef ASSERT
4340 assert(from_obj->is_forwarded(), "from obj should be forwarded"); 4341 assert(from_obj->is_forwarded(), "from obj should be forwarded");
4352 4353
4353 // The object might be in the process of being copied by another 4354 // The object might be in the process of being copied by another
4354 // worker so we cannot trust that its to-space image is 4355 // worker so we cannot trust that its to-space image is
4355 // well-formed. So we have to read its size from its from-space 4356 // well-formed. So we have to read its size from its from-space
4356 // image which we know should not be changing. 4357 // image which we know should not be changing.
4357 _cm->grayRoot(to_obj, (size_t) from_obj->size()); 4358 _cm->grayRoot(to_obj, (size_t) from_obj->size(), _worker_id);
4358 } 4359 }
4359 4360
4360 oop G1ParCopyHelper::copy_to_survivor_space(oop old) { 4361 oop G1ParCopyHelper::copy_to_survivor_space(oop old) {
4361 size_t word_sz = old->size(); 4362 size_t word_sz = old->size();
4362 HeapRegion* from_region = _g1->heap_region_containing_raw(old); 4363 HeapRegion* from_region = _g1->heap_region_containing_raw(old);
4442 ::do_oop_work(T* p) { 4443 ::do_oop_work(T* p) {
4443 oop obj = oopDesc::load_decode_heap_oop(p); 4444 oop obj = oopDesc::load_decode_heap_oop(p);
4444 assert(barrier != G1BarrierRS || obj != NULL, 4445 assert(barrier != G1BarrierRS || obj != NULL,
4445 "Precondition: G1BarrierRS implies obj is non-NULL"); 4446 "Precondition: G1BarrierRS implies obj is non-NULL");
4446 4447
4448 assert(_worker_id == _par_scan_state->queue_num(), "sanity");
4449
4447 // here the null check is implicit in the cset_fast_test() test 4450 // here the null check is implicit in the cset_fast_test() test
4448 if (_g1->in_cset_fast_test(obj)) { 4451 if (_g1->in_cset_fast_test(obj)) {
4449 oop forwardee; 4452 oop forwardee;
4450 if (obj->is_forwarded()) { 4453 if (obj->is_forwarded()) {
4451 forwardee = obj->forwardee(); 4454 forwardee = obj->forwardee();
4460 mark_forwarded_object(obj, forwardee); 4463 mark_forwarded_object(obj, forwardee);
4461 } 4464 }
4462 4465
4463 // When scanning the RS, we only care about objs in CS. 4466 // When scanning the RS, we only care about objs in CS.
4464 if (barrier == G1BarrierRS) { 4467 if (barrier == G1BarrierRS) {
4465 _par_scan_state->update_rs(_from, p, _par_scan_state->queue_num()); 4468 _par_scan_state->update_rs(_from, p, _worker_id);
4466 } 4469 }
4467 } else { 4470 } else {
4468 // The object is not in collection set. If we're a root scanning 4471 // The object is not in collection set. If we're a root scanning
4469 // closure during an initial mark pause (i.e. do_mark_object will 4472 // closure during an initial mark pause (i.e. do_mark_object will
4470 // be true) then attempt to mark the object. 4473 // be true) then attempt to mark the object.
4472 mark_object(obj); 4475 mark_object(obj);
4473 } 4476 }
4474 } 4477 }
4475 4478
4476 if (barrier == G1BarrierEvac && obj != NULL) { 4479 if (barrier == G1BarrierEvac && obj != NULL) {
4477 _par_scan_state->update_rs(_from, p, _par_scan_state->queue_num()); 4480 _par_scan_state->update_rs(_from, p, _worker_id);
4478 } 4481 }
4479 4482
4480 if (do_gen_barrier && obj != NULL) { 4483 if (do_gen_barrier && obj != NULL) {
4481 par_do_barrier(p); 4484 par_do_barrier(p);
4482 } 4485 }
5702 if (!cur->evacuation_failed()) { 5705 if (!cur->evacuation_failed()) {
5703 MemRegion used_mr = cur->used_region(); 5706 MemRegion used_mr = cur->used_region();
5704 5707
5705 // And the region is empty. 5708 // And the region is empty.
5706 assert(!used_mr.is_empty(), "Should not have empty regions in a CS."); 5709 assert(!used_mr.is_empty(), "Should not have empty regions in a CS.");
5707
5708 // If marking is in progress then clear any objects marked in
5709 // the current region. Note mark_in_progress() returns false,
5710 // even during an initial mark pause, until the set_marking_started()
5711 // call which takes place later in the pause.
5712 if (mark_in_progress()) {
5713 assert(!g1_policy()->during_initial_mark_pause(), "sanity");
5714 _cm->nextMarkBitMap()->clearRange(used_mr);
5715 }
5716
5717 free_region(cur, &pre_used, &local_free_list, false /* par */); 5710 free_region(cur, &pre_used, &local_free_list, false /* par */);
5718 } else { 5711 } else {
5719 cur->uninstall_surv_rate_group(); 5712 cur->uninstall_surv_rate_group();
5720 if (cur->is_young()) { 5713 if (cur->is_young()) {
5721 cur->set_young_index_in_cset(-1); 5714 cur->set_young_index_in_cset(-1);