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