4749 if (m->has_displaced_mark_helper()) { 4750 // in this case, we have to install the mark word first, 4751 // otherwise obj looks to be forwarded (the old mark word, 4752 // which contains the forward pointer, was copied) 4753 obj->set_mark(m); 4754 obj->incr_age(); 4755 } else { 4756 m = m->incr_age(); 4757 obj->set_mark(m); 4758 } 4759 _par_scan_state->age_table()->add(obj, word_sz); 4760 } else { 4761 obj->set_mark(m); 4762 } 4763 4764 size_t* surv_young_words = _par_scan_state->surviving_young_words(); 4765 surv_young_words[young_index] += word_sz; 4766 4767 if (obj->is_objArray() && arrayOop(obj)->length() >= ParGCArrayScanChunk) { 4768 // 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 4770 // length field of the from-space object. 4771 arrayOop(obj)->set_length(0); 4772 oop* old_p = set_partial_array_mask(old); 4773 _par_scan_state->push_on_queue(old_p); 4774 } else { 4775 // No point in using the slower heap_region_containing() method, 4776 // given that we know obj is in the heap. 4777 _scanner.set_region(_g1->heap_region_containing_raw(obj)); 4778 obj->oop_iterate_backwards(&_scanner); 4779 } 4780 } else { 4781 _par_scan_state->undo_allocation(alloc_purpose, obj_ptr, word_sz); 4782 obj = forward_ptr; 4783 } 4784 return obj; 4785 } 4786 4787 template <class T> 4788 void G1ParCopyHelper::do_klass_barrier(T* p, oop new_obj) { 4789 if (_g1->heap_region_containing_raw(new_obj)->is_young()) { 4790 _scanned_klass->record_modified_oops(); 4791 } 4825 if (do_mark_object && _g1->is_in_g1_reserved(obj)) { 4826 mark_object(obj); 4827 } 4828 } 4829 4830 if (barrier == G1BarrierEvac && obj != NULL) { 4831 _par_scan_state->update_rs(_from, p, _worker_id); 4832 } 4833 } 4834 4835 template void G1ParCopyClosure<G1BarrierEvac, false>::do_oop_work(oop* p); 4836 template void G1ParCopyClosure<G1BarrierEvac, false>::do_oop_work(narrowOop* p); 4837 4838 template <class T> void G1ParScanPartialArrayClosure::do_oop_nv(T* p) { 4839 assert(has_partial_array_mask(p), "invariant"); 4840 oop from_obj = clear_partial_array_mask(p); 4841 4842 assert(Universe::heap()->is_in_reserved(from_obj), "must be in heap."); 4843 assert(from_obj->is_objArray(), "must be obj array"); 4844 objArrayOop from_obj_array = objArrayOop(from_obj); 4845 // The from-space object contains the real length. 4846 int length = from_obj_array->length(); 4847 4848 assert(from_obj->is_forwarded(), "must be forwarded"); 4849 oop to_obj = from_obj->forwardee(); 4850 assert(from_obj != to_obj, "should not be chunking self-forwarded objects"); 4851 objArrayOop to_obj_array = objArrayOop(to_obj); 4852 // We keep track of the next start index in the length field of the 4853 // to-space object. 4854 int next_index = to_obj_array->length(); 4855 assert(0 <= next_index && next_index < length, 4856 err_msg("invariant, next index: %d, length: %d", next_index, length)); 4857 4858 int start = next_index; 4859 int end = length; 4860 int remainder = end - start; 4861 // We'll try not to push a range that's smaller than ParGCArrayScanChunk. 4862 if (remainder > 2 * ParGCArrayScanChunk) { 4863 end = start + ParGCArrayScanChunk; 4864 to_obj_array->set_length(end); 4865 // Push the remainder before we process the range in case another 4866 // worker has run out of things to do and can steal it. 4867 oop* from_obj_p = set_partial_array_mask(from_obj); 4868 _par_scan_state->push_on_queue(from_obj_p); 4869 } else { 4870 assert(length == end, "sanity"); 4871 // We'll process the final range for this object. Restore the length 4872 // so that the heap remains parsable in case of evacuation failure. 4873 to_obj_array->set_length(end); 4874 } 4875 _scanner.set_region(_g1->heap_region_containing_raw(to_obj)); 4876 // Process indexes [start,end). It will also process the header 4877 // along with the first chunk (i.e., the chunk with start == 0). 4878 // Note that at this point the length field of to_obj_array is not 4879 // correct given that we are using it to keep track of the next 4880 // start index. oop_iterate_range() (thankfully!) ignores the length 4881 // field and only relies on the start / end parameters. It does 4882 // however return the size of the object which will be incorrect. So 4883 // we have to ignore it even if we wanted to use it. 4884 to_obj_array->oop_iterate_range(&_scanner, start, end); 4885 } 4886 4887 class G1ParEvacuateFollowersClosure : public VoidClosure { 4888 protected: 4889 G1CollectedHeap* _g1h; 4890 G1ParScanThreadState* _par_scan_state; 4891 RefToScanQueueSet* _queues; 4892 ParallelTaskTerminator* _terminator; 4893 | 4749 if (m->has_displaced_mark_helper()) { 4750 // in this case, we have to install the mark word first, 4751 // otherwise obj looks to be forwarded (the old mark word, 4752 // which contains the forward pointer, was copied) 4753 obj->set_mark(m); 4754 obj->incr_age(); 4755 } else { 4756 m = m->incr_age(); 4757 obj->set_mark(m); 4758 } 4759 _par_scan_state->age_table()->add(obj, word_sz); 4760 } else { 4761 obj->set_mark(m); 4762 } 4763 4764 size_t* surv_young_words = _par_scan_state->surviving_young_words(); 4765 surv_young_words[young_index] += word_sz; 4766 4767 if (obj->is_objArray() && arrayOop(obj)->length() >= ParGCArrayScanChunk) { 4768 // We keep track of the next start index in the length field of 4769 // the from-space object. The actual length can be found in the 4770 // length field of the to-space object. 4771 arrayOop(old)->set_length(0); 4772 oop* old_p = set_partial_array_mask(old); 4773 _par_scan_state->push_on_queue(old_p); 4774 } else { 4775 // No point in using the slower heap_region_containing() method, 4776 // given that we know obj is in the heap. 4777 _scanner.set_region(_g1->heap_region_containing_raw(obj)); 4778 obj->oop_iterate_backwards(&_scanner); 4779 } 4780 } else { 4781 _par_scan_state->undo_allocation(alloc_purpose, obj_ptr, word_sz); 4782 obj = forward_ptr; 4783 } 4784 return obj; 4785 } 4786 4787 template <class T> 4788 void G1ParCopyHelper::do_klass_barrier(T* p, oop new_obj) { 4789 if (_g1->heap_region_containing_raw(new_obj)->is_young()) { 4790 _scanned_klass->record_modified_oops(); 4791 } 4825 if (do_mark_object && _g1->is_in_g1_reserved(obj)) { 4826 mark_object(obj); 4827 } 4828 } 4829 4830 if (barrier == G1BarrierEvac && obj != NULL) { 4831 _par_scan_state->update_rs(_from, p, _worker_id); 4832 } 4833 } 4834 4835 template void G1ParCopyClosure<G1BarrierEvac, false>::do_oop_work(oop* p); 4836 template void G1ParCopyClosure<G1BarrierEvac, false>::do_oop_work(narrowOop* p); 4837 4838 template <class T> void G1ParScanPartialArrayClosure::do_oop_nv(T* p) { 4839 assert(has_partial_array_mask(p), "invariant"); 4840 oop from_obj = clear_partial_array_mask(p); 4841 4842 assert(Universe::heap()->is_in_reserved(from_obj), "must be in heap."); 4843 assert(from_obj->is_objArray(), "must be obj array"); 4844 objArrayOop from_obj_array = objArrayOop(from_obj); 4845 // We keep track of the next start index in the length field of the 4846 // from-space object. 4847 int next_index = from_obj_array->length(); 4848 4849 assert(from_obj->is_forwarded(), "must be forwarded"); 4850 oop to_obj = from_obj->forwardee(); 4851 assert(from_obj != to_obj, "should not be chunking self-forwarded objects"); 4852 objArrayOop to_obj_array = objArrayOop(to_obj); 4853 // The to-space object contains the real length. 4854 int length = to_obj_array->length(); 4855 assert(0 <= next_index && next_index < length, 4856 err_msg("invariant, next index: %d, length: %d", next_index, length)); 4857 4858 int start = next_index; 4859 int end = length; 4860 int remainder = end - start; 4861 // We'll try not to push a range that's smaller than ParGCArrayScanChunk. 4862 if (remainder > 2 * ParGCArrayScanChunk) { 4863 end = start + ParGCArrayScanChunk; 4864 from_obj_array->set_length(end); 4865 // Push the remainder before we process the range in case another 4866 // worker has run out of things to do and can steal it. 4867 oop* from_obj_p = set_partial_array_mask(from_obj); 4868 _par_scan_state->push_on_queue(from_obj_p); 4869 } else { 4870 assert(length == end, "sanity"); 4871 // We'll process the final range for this object. Restore the length 4872 // so that the heap remains parsable in case of evacuation failure. 4873 from_obj_array->set_length(end); 4874 } 4875 _scanner.set_region(_g1->heap_region_containing_raw(to_obj)); 4876 // Process indexes [start,end). It will also process the header 4877 // along with the first chunk (i.e., the chunk with start == 0). 4878 // Note that at this point the length field of to_obj_array is not 4879 // correct given that we are using it to keep track of the next 4880 // start index. oop_iterate_range() (thankfully!) ignores the length 4881 // field and only relies on the start / end parameters. It does 4882 // however return the size of the object which will be incorrect. So 4883 // we have to ignore it even if we wanted to use it. 4884 to_obj_array->oop_iterate_range(&_scanner, start, end); 4885 } 4886 4887 class G1ParEvacuateFollowersClosure : public VoidClosure { 4888 protected: 4889 G1CollectedHeap* _g1h; 4890 G1ParScanThreadState* _par_scan_state; 4891 RefToScanQueueSet* _queues; 4892 ParallelTaskTerminator* _terminator; 4893 |