4772 _scanner.set_region(_g1->heap_region_containing_raw(obj));
4773 obj->oop_iterate_backwards(&_scanner);
4774 }
4775 } else {
4776 _par_scan_state->undo_allocation(alloc_purpose, obj_ptr, word_sz);
4777 obj = forward_ptr;
4778 }
4779 return obj;
4780 }
4781
4782 template <class T>
4783 void G1ParCopyHelper::do_klass_barrier(T* p, oop new_obj) {
4784 if (_g1->heap_region_containing_raw(new_obj)->is_young()) {
4785 _scanned_klass->record_modified_oops();
4786 }
4787 }
4788
4789 template <G1Barrier barrier, bool do_mark_object>
4790 template <class T>
4791 void G1ParCopyClosure<barrier, do_mark_object>::do_oop_work(T* p) {
4792 oop obj = oopDesc::load_decode_heap_oop(p);
4793
4794 assert(_worker_id == _par_scan_state->queue_num(), "sanity");
4795
4796 // here the null check is implicit in the cset_fast_test() test
4797 if (_g1->in_cset_fast_test(obj)) {
4798 oop forwardee;
4799 if (obj->is_forwarded()) {
4800 forwardee = obj->forwardee();
4801 } else {
4802 forwardee = copy_to_survivor_space(obj);
4803 }
4804 assert(forwardee != NULL, "forwardee should not be NULL");
4805 oopDesc::encode_store_heap_oop(p, forwardee);
4806 if (do_mark_object && forwardee != obj) {
4807 // If the object is self-forwarded we don't need to explicitly
4808 // mark it, the evacuation failure protocol will do so.
4809 mark_forwarded_object(obj, forwardee);
4810 }
4811
4812 if (barrier == G1BarrierKlass) {
4813 do_klass_barrier(p, forwardee);
4814 }
4815 } else {
4816 // The object is not in collection set. If we're a root scanning
4817 // closure during an initial mark pause (i.e. do_mark_object will
4818 // be true) then attempt to mark the object.
4819 if (do_mark_object && _g1->is_in_g1_reserved(obj)) {
4820 mark_object(obj);
4821 }
4822 }
4823
4824 if (barrier == G1BarrierEvac && obj != NULL) {
4825 _par_scan_state->update_rs(_from, p, _worker_id);
4826 }
4827 }
4828
4829 template void G1ParCopyClosure<G1BarrierEvac, false>::do_oop_work(oop* p);
4830 template void G1ParCopyClosure<G1BarrierEvac, false>::do_oop_work(narrowOop* p);
4831
4832 template <class T> void G1ParScanPartialArrayClosure::do_oop_nv(T* p) {
4833 assert(has_partial_array_mask(p), "invariant");
4834 oop from_obj = clear_partial_array_mask(p);
4835
4836 assert(Universe::heap()->is_in_reserved(from_obj), "must be in heap.");
4837 assert(from_obj->is_objArray(), "must be obj array");
4838 objArrayOop from_obj_array = objArrayOop(from_obj);
4839 // The from-space object contains the real length.
4840 int length = from_obj_array->length();
4841
4842 assert(from_obj->is_forwarded(), "must be forwarded");
4843 oop to_obj = from_obj->forwardee();
4844 assert(from_obj != to_obj, "should not be chunking self-forwarded objects");
|
4772 _scanner.set_region(_g1->heap_region_containing_raw(obj));
4773 obj->oop_iterate_backwards(&_scanner);
4774 }
4775 } else {
4776 _par_scan_state->undo_allocation(alloc_purpose, obj_ptr, word_sz);
4777 obj = forward_ptr;
4778 }
4779 return obj;
4780 }
4781
4782 template <class T>
4783 void G1ParCopyHelper::do_klass_barrier(T* p, oop new_obj) {
4784 if (_g1->heap_region_containing_raw(new_obj)->is_young()) {
4785 _scanned_klass->record_modified_oops();
4786 }
4787 }
4788
4789 template <G1Barrier barrier, bool do_mark_object>
4790 template <class T>
4791 void G1ParCopyClosure<barrier, do_mark_object>::do_oop_work(T* p) {
4792 T heap_oop = oopDesc::load_heap_oop(p);
4793
4794 // Filter out all NULL references up front avoiding checking this again
4795 // over and over.
4796 if (oopDesc::is_null(heap_oop)) {
4797 return;
4798 }
4799
4800 oop obj = oopDesc::load_decode_heap_oop_not_null(p);
4801
4802 assert(_worker_id == _par_scan_state->queue_num(), "sanity");
4803
4804 if (_g1->in_cset_fast_test(obj)) {
4805 oop forwardee;
4806 if (obj->is_forwarded()) {
4807 forwardee = obj->forwardee();
4808 } else {
4809 forwardee = copy_to_survivor_space(obj);
4810 }
4811 assert(forwardee != NULL, "forwardee should not be NULL");
4812 oopDesc::encode_store_heap_oop(p, forwardee);
4813 if (do_mark_object && forwardee != obj) {
4814 // If the object is self-forwarded we don't need to explicitly
4815 // mark it, the evacuation failure protocol will do so.
4816 mark_forwarded_object(obj, forwardee);
4817 }
4818
4819 if (barrier == G1BarrierKlass) {
4820 do_klass_barrier(p, forwardee);
4821 }
4822 } else {
4823 // The object is not in collection set. If we're a root scanning
4824 // closure during an initial mark pause (i.e. do_mark_object will
4825 // be true) then attempt to mark the object.
4826 if (do_mark_object) {
4827 mark_object(obj);
4828 }
4829 }
4830
4831 if (barrier == G1BarrierEvac) {
4832 _par_scan_state->update_rs(_from, p, _worker_id);
4833 }
4834 }
4835
4836 template void G1ParCopyClosure<G1BarrierEvac, false>::do_oop_work(oop* p);
4837 template void G1ParCopyClosure<G1BarrierEvac, false>::do_oop_work(narrowOop* p);
4838
4839 template <class T> void G1ParScanPartialArrayClosure::do_oop_nv(T* p) {
4840 assert(has_partial_array_mask(p), "invariant");
4841 oop from_obj = clear_partial_array_mask(p);
4842
4843 assert(Universe::heap()->is_in_reserved(from_obj), "must be in heap.");
4844 assert(from_obj->is_objArray(), "must be obj array");
4845 objArrayOop from_obj_array = objArrayOop(from_obj);
4846 // The from-space object contains the real length.
4847 int length = 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");
|