comparison src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @ 17689:5d492d192cbf

8035329: Move G1ParCopyClosure::copy_to_survivor_space into G1ParScanThreadState Summary: Move G1ParCopyClosure::copy_to_survivor_space to decrease code size. Reviewed-by: stefank, jmasa
author tschatzl
date Wed, 26 Feb 2014 15:32:47 +0100
parents 2c2ae9e5f65d
children cfd4aac53239
comparison
equal deleted inserted replaced
17688:2c2ae9e5f65d 17689:5d492d192cbf
4537 } 4537 }
4538 4538
4539 G1ParGCAllocBuffer::G1ParGCAllocBuffer(size_t gclab_word_size) : 4539 G1ParGCAllocBuffer::G1ParGCAllocBuffer(size_t gclab_word_size) :
4540 ParGCAllocBuffer(gclab_word_size), _retired(false) { } 4540 ParGCAllocBuffer(gclab_word_size), _retired(false) { }
4541 4541
4542 G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, uint queue_num) 4542 G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, uint queue_num, ReferenceProcessor* rp)
4543 : _g1h(g1h), 4543 : _g1h(g1h),
4544 _refs(g1h->task_queue(queue_num)), 4544 _refs(g1h->task_queue(queue_num)),
4545 _dcq(&g1h->dirty_card_queue_set()), 4545 _dcq(&g1h->dirty_card_queue_set()),
4546 _ct_bs(g1h->g1_barrier_set()), 4546 _ct_bs(g1h->g1_barrier_set()),
4547 _g1_rem(g1h->g1_rem_set()), 4547 _g1_rem(g1h->g1_rem_set()),
4548 _hash_seed(17), _queue_num(queue_num), 4548 _hash_seed(17), _queue_num(queue_num),
4549 _term_attempts(0), 4549 _term_attempts(0),
4550 _surviving_alloc_buffer(g1h->desired_plab_sz(GCAllocForSurvived)), 4550 _surviving_alloc_buffer(g1h->desired_plab_sz(GCAllocForSurvived)),
4551 _tenured_alloc_buffer(g1h->desired_plab_sz(GCAllocForTenured)), 4551 _tenured_alloc_buffer(g1h->desired_plab_sz(GCAllocForTenured)),
4552 _age_table(false), 4552 _age_table(false), _scanner(g1h, this, rp),
4553 _strong_roots_time(0), _term_time(0), 4553 _strong_roots_time(0), _term_time(0),
4554 _alloc_buffer_waste(0), _undo_waste(0) { 4554 _alloc_buffer_waste(0), _undo_waste(0) {
4555 // we allocate G1YoungSurvRateNumRegions plus one entries, since 4555 // we allocate G1YoungSurvRateNumRegions plus one entries, since
4556 // we "sacrifice" entry 0 to keep track of surviving bytes for 4556 // we "sacrifice" entry 0 to keep track of surviving bytes for
4557 // non-young regions (where the age is -1) 4557 // non-young regions (where the age is -1)
4692 // well-formed. So we have to read its size from its from-space 4692 // well-formed. So we have to read its size from its from-space
4693 // image which we know should not be changing. 4693 // image which we know should not be changing.
4694 _cm->grayRoot(to_obj, (size_t) from_obj->size(), _worker_id); 4694 _cm->grayRoot(to_obj, (size_t) from_obj->size(), _worker_id);
4695 } 4695 }
4696 4696
4697 template <G1Barrier barrier, bool do_mark_object> 4697 oop G1ParScanThreadState::copy_to_survivor_space(oop const old) {
4698 oop G1ParCopyClosure<barrier, do_mark_object>
4699 ::copy_to_survivor_space(oop old) {
4700 size_t word_sz = old->size(); 4698 size_t word_sz = old->size();
4701 HeapRegion* from_region = _g1->heap_region_containing_raw(old); 4699 HeapRegion* from_region = _g1h->heap_region_containing_raw(old);
4702 // +1 to make the -1 indexes valid... 4700 // +1 to make the -1 indexes valid...
4703 int young_index = from_region->young_index_in_cset()+1; 4701 int young_index = from_region->young_index_in_cset()+1;
4704 assert( (from_region->is_young() && young_index > 0) || 4702 assert( (from_region->is_young() && young_index > 0) ||
4705 (!from_region->is_young() && young_index == 0), "invariant" ); 4703 (!from_region->is_young() && young_index == 0), "invariant" );
4706 G1CollectorPolicy* g1p = _g1->g1_policy(); 4704 G1CollectorPolicy* g1p = _g1h->g1_policy();
4707 markOop m = old->mark(); 4705 markOop m = old->mark();
4708 int age = m->has_displaced_mark_helper() ? m->displaced_mark_helper()->age() 4706 int age = m->has_displaced_mark_helper() ? m->displaced_mark_helper()->age()
4709 : m->age(); 4707 : m->age();
4710 GCAllocPurpose alloc_purpose = g1p->evacuation_destination(from_region, age, 4708 GCAllocPurpose alloc_purpose = g1p->evacuation_destination(from_region, age,
4711 word_sz); 4709 word_sz);
4712 HeapWord* obj_ptr = _par_scan_state->allocate(alloc_purpose, word_sz); 4710 HeapWord* obj_ptr = allocate(alloc_purpose, word_sz);
4713 #ifndef PRODUCT 4711 #ifndef PRODUCT
4714 // Should this evacuation fail? 4712 // Should this evacuation fail?
4715 if (_g1->evacuation_should_fail()) { 4713 if (_g1h->evacuation_should_fail()) {
4716 if (obj_ptr != NULL) { 4714 if (obj_ptr != NULL) {
4717 _par_scan_state->undo_allocation(alloc_purpose, obj_ptr, word_sz); 4715 undo_allocation(alloc_purpose, obj_ptr, word_sz);
4718 obj_ptr = NULL; 4716 obj_ptr = NULL;
4719 } 4717 }
4720 } 4718 }
4721 #endif // !PRODUCT 4719 #endif // !PRODUCT
4722 4720
4723 if (obj_ptr == NULL) { 4721 if (obj_ptr == NULL) {
4724 // This will either forward-to-self, or detect that someone else has 4722 // This will either forward-to-self, or detect that someone else has
4725 // installed a forwarding pointer. 4723 // installed a forwarding pointer.
4726 return _g1->handle_evacuation_failure_par(_par_scan_state, old); 4724 return _g1h->handle_evacuation_failure_par(this, old);
4727 } 4725 }
4728 4726
4729 oop obj = oop(obj_ptr); 4727 oop obj = oop(obj_ptr);
4730 4728
4731 // We're going to allocate linearly, so might as well prefetch ahead. 4729 // We're going to allocate linearly, so might as well prefetch ahead.
4754 obj->incr_age(); 4752 obj->incr_age();
4755 } else { 4753 } else {
4756 m = m->incr_age(); 4754 m = m->incr_age();
4757 obj->set_mark(m); 4755 obj->set_mark(m);
4758 } 4756 }
4759 _par_scan_state->age_table()->add(obj, word_sz); 4757 age_table()->add(obj, word_sz);
4760 } else { 4758 } else {
4761 obj->set_mark(m); 4759 obj->set_mark(m);
4762 } 4760 }
4763 4761
4764 size_t* surv_young_words = _par_scan_state->surviving_young_words(); 4762 size_t* surv_young_words = surviving_young_words();
4765 surv_young_words[young_index] += word_sz; 4763 surv_young_words[young_index] += word_sz;
4766 4764
4767 if (obj->is_objArray() && arrayOop(obj)->length() >= ParGCArrayScanChunk) { 4765 if (obj->is_objArray() && arrayOop(obj)->length() >= ParGCArrayScanChunk) {
4768 // We keep track of the next start index in the length field of 4766 // We keep track of the next start index in the length field of
4769 // the to-space object. The actual length can be found in the 4767 // the to-space object. The actual length can be found in the
4770 // length field of the from-space object. 4768 // length field of the from-space object.
4771 arrayOop(obj)->set_length(0); 4769 arrayOop(obj)->set_length(0);
4772 oop* old_p = set_partial_array_mask(old); 4770 oop* old_p = set_partial_array_mask(old);
4773 _par_scan_state->push_on_queue(old_p); 4771 push_on_queue(old_p);
4774 } else { 4772 } else {
4775 // No point in using the slower heap_region_containing() method, 4773 // No point in using the slower heap_region_containing() method,
4776 // given that we know obj is in the heap. 4774 // given that we know obj is in the heap.
4777 _scanner.set_region(_g1->heap_region_containing_raw(obj)); 4775 _scanner.set_region(_g1h->heap_region_containing_raw(obj));
4778 obj->oop_iterate_backwards(&_scanner); 4776 obj->oop_iterate_backwards(&_scanner);
4779 } 4777 }
4780 } else { 4778 } else {
4781 _par_scan_state->undo_allocation(alloc_purpose, obj_ptr, word_sz); 4779 undo_allocation(alloc_purpose, obj_ptr, word_sz);
4782 obj = forward_ptr; 4780 obj = forward_ptr;
4783 } 4781 }
4784 return obj; 4782 return obj;
4785 } 4783 }
4786 4784
4807 if (_g1->in_cset_fast_test(obj)) { 4805 if (_g1->in_cset_fast_test(obj)) {
4808 oop forwardee; 4806 oop forwardee;
4809 if (obj->is_forwarded()) { 4807 if (obj->is_forwarded()) {
4810 forwardee = obj->forwardee(); 4808 forwardee = obj->forwardee();
4811 } else { 4809 } else {
4812 forwardee = copy_to_survivor_space(obj); 4810 forwardee = _par_scan_state->copy_to_survivor_space(obj);
4813 } 4811 }
4814 assert(forwardee != NULL, "forwardee should not be NULL"); 4812 assert(forwardee != NULL, "forwardee should not be NULL");
4815 oopDesc::encode_store_heap_oop(p, forwardee); 4813 oopDesc::encode_store_heap_oop(p, forwardee);
4816 if (do_mark_object && forwardee != obj) { 4814 if (do_mark_object && forwardee != obj) {
4817 // If the object is self-forwarded we don't need to explicitly 4815 // If the object is self-forwarded we don't need to explicitly
5026 ResourceMark rm; 5024 ResourceMark rm;
5027 HandleMark hm; 5025 HandleMark hm;
5028 5026
5029 ReferenceProcessor* rp = _g1h->ref_processor_stw(); 5027 ReferenceProcessor* rp = _g1h->ref_processor_stw();
5030 5028
5031 G1ParScanThreadState pss(_g1h, worker_id); 5029 G1ParScanThreadState pss(_g1h, worker_id, rp);
5032 G1ParScanHeapEvacClosure scan_evac_cl(_g1h, &pss, rp); 5030 G1ParScanHeapEvacClosure scan_evac_cl(_g1h, &pss, rp);
5033 G1ParScanHeapEvacFailureClosure evac_failure_cl(_g1h, &pss, rp); 5031 G1ParScanHeapEvacFailureClosure evac_failure_cl(_g1h, &pss, rp);
5034 G1ParScanPartialArrayClosure partial_scan_cl(_g1h, &pss, rp); 5032 G1ParScanPartialArrayClosure partial_scan_cl(_g1h, &pss, rp);
5035 5033
5036 pss.set_evac_closure(&scan_evac_cl); 5034 pss.set_evac_closure(&scan_evac_cl);
5469 ResourceMark rm; 5467 ResourceMark rm;
5470 HandleMark hm; 5468 HandleMark hm;
5471 5469
5472 G1STWIsAliveClosure is_alive(_g1h); 5470 G1STWIsAliveClosure is_alive(_g1h);
5473 5471
5474 G1ParScanThreadState pss(_g1h, worker_id); 5472 G1ParScanThreadState pss(_g1h, worker_id, NULL);
5475 5473
5476 G1ParScanHeapEvacClosure scan_evac_cl(_g1h, &pss, NULL); 5474 G1ParScanHeapEvacClosure scan_evac_cl(_g1h, &pss, NULL);
5477 G1ParScanHeapEvacFailureClosure evac_failure_cl(_g1h, &pss, NULL); 5475 G1ParScanHeapEvacFailureClosure evac_failure_cl(_g1h, &pss, NULL);
5478 G1ParScanPartialArrayClosure partial_scan_cl(_g1h, &pss, NULL); 5476 G1ParScanPartialArrayClosure partial_scan_cl(_g1h, &pss, NULL);
5479 5477
5581 5579
5582 void work(uint worker_id) { 5580 void work(uint worker_id) {
5583 ResourceMark rm; 5581 ResourceMark rm;
5584 HandleMark hm; 5582 HandleMark hm;
5585 5583
5586 G1ParScanThreadState pss(_g1h, worker_id); 5584 G1ParScanThreadState pss(_g1h, worker_id, NULL);
5587 G1ParScanHeapEvacClosure scan_evac_cl(_g1h, &pss, NULL); 5585 G1ParScanHeapEvacClosure scan_evac_cl(_g1h, &pss, NULL);
5588 G1ParScanHeapEvacFailureClosure evac_failure_cl(_g1h, &pss, NULL); 5586 G1ParScanHeapEvacFailureClosure evac_failure_cl(_g1h, &pss, NULL);
5589 G1ParScanPartialArrayClosure partial_scan_cl(_g1h, &pss, NULL); 5587 G1ParScanPartialArrayClosure partial_scan_cl(_g1h, &pss, NULL);
5590 5588
5591 pss.set_evac_closure(&scan_evac_cl); 5589 pss.set_evac_closure(&scan_evac_cl);
5707 // of JNI refs is serial and performed serially by the current thread 5705 // of JNI refs is serial and performed serially by the current thread
5708 // rather than by a worker. The following PSS will be used for processing 5706 // rather than by a worker. The following PSS will be used for processing
5709 // JNI refs. 5707 // JNI refs.
5710 5708
5711 // Use only a single queue for this PSS. 5709 // Use only a single queue for this PSS.
5712 G1ParScanThreadState pss(this, 0); 5710 G1ParScanThreadState pss(this, 0, NULL);
5713 5711
5714 // We do not embed a reference processor in the copying/scanning 5712 // We do not embed a reference processor in the copying/scanning
5715 // closures while we're actually processing the discovered 5713 // closures while we're actually processing the discovered
5716 // reference objects. 5714 // reference objects.
5717 G1ParScanHeapEvacClosure scan_evac_cl(this, &pss, NULL); 5715 G1ParScanHeapEvacClosure scan_evac_cl(this, &pss, NULL);