Mercurial > hg > graal-jvmci-8
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); |