comparison src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @ 14487:97300b6165f8

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 Mon, 24 Feb 2014 09:41:04 +0100
parents 4f227ecd7beb
children d8041d695d19
comparison
equal deleted inserted replaced
14486:4f227ecd7beb 14487:97300b6165f8
4532 } 4532 }
4533 4533
4534 G1ParGCAllocBuffer::G1ParGCAllocBuffer(size_t gclab_word_size) : 4534 G1ParGCAllocBuffer::G1ParGCAllocBuffer(size_t gclab_word_size) :
4535 ParGCAllocBuffer(gclab_word_size), _retired(false) { } 4535 ParGCAllocBuffer(gclab_word_size), _retired(false) { }
4536 4536
4537 G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, uint queue_num) 4537 G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, uint queue_num, ReferenceProcessor* rp)
4538 : _g1h(g1h), 4538 : _g1h(g1h),
4539 _refs(g1h->task_queue(queue_num)), 4539 _refs(g1h->task_queue(queue_num)),
4540 _dcq(&g1h->dirty_card_queue_set()), 4540 _dcq(&g1h->dirty_card_queue_set()),
4541 _ct_bs(g1h->g1_barrier_set()), 4541 _ct_bs(g1h->g1_barrier_set()),
4542 _g1_rem(g1h->g1_rem_set()), 4542 _g1_rem(g1h->g1_rem_set()),
4543 _hash_seed(17), _queue_num(queue_num), 4543 _hash_seed(17), _queue_num(queue_num),
4544 _term_attempts(0), 4544 _term_attempts(0),
4545 _surviving_alloc_buffer(g1h->desired_plab_sz(GCAllocForSurvived)), 4545 _surviving_alloc_buffer(g1h->desired_plab_sz(GCAllocForSurvived)),
4546 _tenured_alloc_buffer(g1h->desired_plab_sz(GCAllocForTenured)), 4546 _tenured_alloc_buffer(g1h->desired_plab_sz(GCAllocForTenured)),
4547 _age_table(false), 4547 _age_table(false), _scanner(g1h, this, rp),
4548 _strong_roots_time(0), _term_time(0), 4548 _strong_roots_time(0), _term_time(0),
4549 _alloc_buffer_waste(0), _undo_waste(0) { 4549 _alloc_buffer_waste(0), _undo_waste(0) {
4550 // we allocate G1YoungSurvRateNumRegions plus one entries, since 4550 // we allocate G1YoungSurvRateNumRegions plus one entries, since
4551 // we "sacrifice" entry 0 to keep track of surviving bytes for 4551 // we "sacrifice" entry 0 to keep track of surviving bytes for
4552 // non-young regions (where the age is -1) 4552 // non-young regions (where the age is -1)
4687 // well-formed. So we have to read its size from its from-space 4687 // well-formed. So we have to read its size from its from-space
4688 // image which we know should not be changing. 4688 // image which we know should not be changing.
4689 _cm->grayRoot(to_obj, (size_t) from_obj->size(), _worker_id); 4689 _cm->grayRoot(to_obj, (size_t) from_obj->size(), _worker_id);
4690 } 4690 }
4691 4691
4692 template <G1Barrier barrier, bool do_mark_object> 4692 oop G1ParScanThreadState::copy_to_survivor_space(oop const old) {
4693 oop G1ParCopyClosure<barrier, do_mark_object>
4694 ::copy_to_survivor_space(oop old) {
4695 size_t word_sz = old->size(); 4693 size_t word_sz = old->size();
4696 HeapRegion* from_region = _g1->heap_region_containing_raw(old); 4694 HeapRegion* from_region = _g1h->heap_region_containing_raw(old);
4697 // +1 to make the -1 indexes valid... 4695 // +1 to make the -1 indexes valid...
4698 int young_index = from_region->young_index_in_cset()+1; 4696 int young_index = from_region->young_index_in_cset()+1;
4699 assert( (from_region->is_young() && young_index > 0) || 4697 assert( (from_region->is_young() && young_index > 0) ||
4700 (!from_region->is_young() && young_index == 0), "invariant" ); 4698 (!from_region->is_young() && young_index == 0), "invariant" );
4701 G1CollectorPolicy* g1p = _g1->g1_policy(); 4699 G1CollectorPolicy* g1p = _g1h->g1_policy();
4702 markOop m = old->mark(); 4700 markOop m = old->mark();
4703 int age = m->has_displaced_mark_helper() ? m->displaced_mark_helper()->age() 4701 int age = m->has_displaced_mark_helper() ? m->displaced_mark_helper()->age()
4704 : m->age(); 4702 : m->age();
4705 GCAllocPurpose alloc_purpose = g1p->evacuation_destination(from_region, age, 4703 GCAllocPurpose alloc_purpose = g1p->evacuation_destination(from_region, age,
4706 word_sz); 4704 word_sz);
4707 HeapWord* obj_ptr = _par_scan_state->allocate(alloc_purpose, word_sz); 4705 HeapWord* obj_ptr = allocate(alloc_purpose, word_sz);
4708 #ifndef PRODUCT 4706 #ifndef PRODUCT
4709 // Should this evacuation fail? 4707 // Should this evacuation fail?
4710 if (_g1->evacuation_should_fail()) { 4708 if (_g1h->evacuation_should_fail()) {
4711 if (obj_ptr != NULL) { 4709 if (obj_ptr != NULL) {
4712 _par_scan_state->undo_allocation(alloc_purpose, obj_ptr, word_sz); 4710 undo_allocation(alloc_purpose, obj_ptr, word_sz);
4713 obj_ptr = NULL; 4711 obj_ptr = NULL;
4714 } 4712 }
4715 } 4713 }
4716 #endif // !PRODUCT 4714 #endif // !PRODUCT
4717 4715
4718 if (obj_ptr == NULL) { 4716 if (obj_ptr == NULL) {
4719 // This will either forward-to-self, or detect that someone else has 4717 // This will either forward-to-self, or detect that someone else has
4720 // installed a forwarding pointer. 4718 // installed a forwarding pointer.
4721 return _g1->handle_evacuation_failure_par(_par_scan_state, old); 4719 return _g1h->handle_evacuation_failure_par(this, old);
4722 } 4720 }
4723 4721
4724 oop obj = oop(obj_ptr); 4722 oop obj = oop(obj_ptr);
4725 4723
4726 // We're going to allocate linearly, so might as well prefetch ahead. 4724 // We're going to allocate linearly, so might as well prefetch ahead.
4749 obj->incr_age(); 4747 obj->incr_age();
4750 } else { 4748 } else {
4751 m = m->incr_age(); 4749 m = m->incr_age();
4752 obj->set_mark(m); 4750 obj->set_mark(m);
4753 } 4751 }
4754 _par_scan_state->age_table()->add(obj, word_sz); 4752 age_table()->add(obj, word_sz);
4755 } else { 4753 } else {
4756 obj->set_mark(m); 4754 obj->set_mark(m);
4757 } 4755 }
4758 4756
4759 size_t* surv_young_words = _par_scan_state->surviving_young_words(); 4757 size_t* surv_young_words = surviving_young_words();
4760 surv_young_words[young_index] += word_sz; 4758 surv_young_words[young_index] += word_sz;
4761 4759
4762 if (obj->is_objArray() && arrayOop(obj)->length() >= ParGCArrayScanChunk) { 4760 if (obj->is_objArray() && arrayOop(obj)->length() >= ParGCArrayScanChunk) {
4763 // We keep track of the next start index in the length field of 4761 // We keep track of the next start index in the length field of
4764 // the to-space object. The actual length can be found in the 4762 // the to-space object. The actual length can be found in the
4765 // length field of the from-space object. 4763 // length field of the from-space object.
4766 arrayOop(obj)->set_length(0); 4764 arrayOop(obj)->set_length(0);
4767 oop* old_p = set_partial_array_mask(old); 4765 oop* old_p = set_partial_array_mask(old);
4768 _par_scan_state->push_on_queue(old_p); 4766 push_on_queue(old_p);
4769 } else { 4767 } else {
4770 // No point in using the slower heap_region_containing() method, 4768 // No point in using the slower heap_region_containing() method,
4771 // given that we know obj is in the heap. 4769 // given that we know obj is in the heap.
4772 _scanner.set_region(_g1->heap_region_containing_raw(obj)); 4770 _scanner.set_region(_g1h->heap_region_containing_raw(obj));
4773 obj->oop_iterate_backwards(&_scanner); 4771 obj->oop_iterate_backwards(&_scanner);
4774 } 4772 }
4775 } else { 4773 } else {
4776 _par_scan_state->undo_allocation(alloc_purpose, obj_ptr, word_sz); 4774 undo_allocation(alloc_purpose, obj_ptr, word_sz);
4777 obj = forward_ptr; 4775 obj = forward_ptr;
4778 } 4776 }
4779 return obj; 4777 return obj;
4780 } 4778 }
4781 4779
4802 if (_g1->in_cset_fast_test(obj)) { 4800 if (_g1->in_cset_fast_test(obj)) {
4803 oop forwardee; 4801 oop forwardee;
4804 if (obj->is_forwarded()) { 4802 if (obj->is_forwarded()) {
4805 forwardee = obj->forwardee(); 4803 forwardee = obj->forwardee();
4806 } else { 4804 } else {
4807 forwardee = copy_to_survivor_space(obj); 4805 forwardee = _par_scan_state->copy_to_survivor_space(obj);
4808 } 4806 }
4809 assert(forwardee != NULL, "forwardee should not be NULL"); 4807 assert(forwardee != NULL, "forwardee should not be NULL");
4810 oopDesc::encode_store_heap_oop(p, forwardee); 4808 oopDesc::encode_store_heap_oop(p, forwardee);
4811 if (do_mark_object && forwardee != obj) { 4809 if (do_mark_object && forwardee != obj) {
4812 // If the object is self-forwarded we don't need to explicitly 4810 // If the object is self-forwarded we don't need to explicitly
5021 ResourceMark rm; 5019 ResourceMark rm;
5022 HandleMark hm; 5020 HandleMark hm;
5023 5021
5024 ReferenceProcessor* rp = _g1h->ref_processor_stw(); 5022 ReferenceProcessor* rp = _g1h->ref_processor_stw();
5025 5023
5026 G1ParScanThreadState pss(_g1h, worker_id); 5024 G1ParScanThreadState pss(_g1h, worker_id, rp);
5027 G1ParScanHeapEvacClosure scan_evac_cl(_g1h, &pss, rp); 5025 G1ParScanHeapEvacClosure scan_evac_cl(_g1h, &pss, rp);
5028 G1ParScanHeapEvacFailureClosure evac_failure_cl(_g1h, &pss, rp); 5026 G1ParScanHeapEvacFailureClosure evac_failure_cl(_g1h, &pss, rp);
5029 G1ParScanPartialArrayClosure partial_scan_cl(_g1h, &pss, rp); 5027 G1ParScanPartialArrayClosure partial_scan_cl(_g1h, &pss, rp);
5030 5028
5031 pss.set_evac_closure(&scan_evac_cl); 5029 pss.set_evac_closure(&scan_evac_cl);
5452 ResourceMark rm; 5450 ResourceMark rm;
5453 HandleMark hm; 5451 HandleMark hm;
5454 5452
5455 G1STWIsAliveClosure is_alive(_g1h); 5453 G1STWIsAliveClosure is_alive(_g1h);
5456 5454
5457 G1ParScanThreadState pss(_g1h, worker_id); 5455 G1ParScanThreadState pss(_g1h, worker_id, NULL);
5458 5456
5459 G1ParScanHeapEvacClosure scan_evac_cl(_g1h, &pss, NULL); 5457 G1ParScanHeapEvacClosure scan_evac_cl(_g1h, &pss, NULL);
5460 G1ParScanHeapEvacFailureClosure evac_failure_cl(_g1h, &pss, NULL); 5458 G1ParScanHeapEvacFailureClosure evac_failure_cl(_g1h, &pss, NULL);
5461 G1ParScanPartialArrayClosure partial_scan_cl(_g1h, &pss, NULL); 5459 G1ParScanPartialArrayClosure partial_scan_cl(_g1h, &pss, NULL);
5462 5460
5564 5562
5565 void work(uint worker_id) { 5563 void work(uint worker_id) {
5566 ResourceMark rm; 5564 ResourceMark rm;
5567 HandleMark hm; 5565 HandleMark hm;
5568 5566
5569 G1ParScanThreadState pss(_g1h, worker_id); 5567 G1ParScanThreadState pss(_g1h, worker_id, NULL);
5570 G1ParScanHeapEvacClosure scan_evac_cl(_g1h, &pss, NULL); 5568 G1ParScanHeapEvacClosure scan_evac_cl(_g1h, &pss, NULL);
5571 G1ParScanHeapEvacFailureClosure evac_failure_cl(_g1h, &pss, NULL); 5569 G1ParScanHeapEvacFailureClosure evac_failure_cl(_g1h, &pss, NULL);
5572 G1ParScanPartialArrayClosure partial_scan_cl(_g1h, &pss, NULL); 5570 G1ParScanPartialArrayClosure partial_scan_cl(_g1h, &pss, NULL);
5573 5571
5574 pss.set_evac_closure(&scan_evac_cl); 5572 pss.set_evac_closure(&scan_evac_cl);
5690 // of JNI refs is serial and performed serially by the current thread 5688 // of JNI refs is serial and performed serially by the current thread
5691 // rather than by a worker. The following PSS will be used for processing 5689 // rather than by a worker. The following PSS will be used for processing
5692 // JNI refs. 5690 // JNI refs.
5693 5691
5694 // Use only a single queue for this PSS. 5692 // Use only a single queue for this PSS.
5695 G1ParScanThreadState pss(this, 0); 5693 G1ParScanThreadState pss(this, 0, NULL);
5696 5694
5697 // We do not embed a reference processor in the copying/scanning 5695 // We do not embed a reference processor in the copying/scanning
5698 // closures while we're actually processing the discovered 5696 // closures while we're actually processing the discovered
5699 // reference objects. 5697 // reference objects.
5700 G1ParScanHeapEvacClosure scan_evac_cl(this, &pss, NULL); 5698 G1ParScanHeapEvacClosure scan_evac_cl(this, &pss, NULL);