48 #include "gc_implementation/shared/gcTimer.hpp" |
48 #include "gc_implementation/shared/gcTimer.hpp" |
49 #include "gc_implementation/shared/gcTrace.hpp" |
49 #include "gc_implementation/shared/gcTrace.hpp" |
50 #include "gc_implementation/shared/gcTraceTime.hpp" |
50 #include "gc_implementation/shared/gcTraceTime.hpp" |
51 #include "gc_implementation/shared/isGCActiveMark.hpp" |
51 #include "gc_implementation/shared/isGCActiveMark.hpp" |
52 #include "memory/gcLocker.inline.hpp" |
52 #include "memory/gcLocker.inline.hpp" |
53 #include "memory/genOopClosures.inline.hpp" |
|
54 #include "memory/generationSpec.hpp" |
53 #include "memory/generationSpec.hpp" |
|
54 #include "memory/iterator.hpp" |
55 #include "memory/referenceProcessor.hpp" |
55 #include "memory/referenceProcessor.hpp" |
56 #include "oops/oop.inline.hpp" |
56 #include "oops/oop.inline.hpp" |
57 #include "oops/oop.pcgc.inline.hpp" |
57 #include "oops/oop.pcgc.inline.hpp" |
58 #include "runtime/vmThread.hpp" |
58 #include "runtime/vmThread.hpp" |
59 #include "utilities/ticks.hpp" |
59 #include "utilities/ticks.hpp" |
3094 default: ShouldNotReachHere(); |
3094 default: ShouldNotReachHere(); |
3095 } |
3095 } |
3096 return NULL; // keep some compilers happy |
3096 return NULL; // keep some compilers happy |
3097 } |
3097 } |
3098 |
3098 |
3099 // TODO: VerifyRootsClosure extends OopsInGenClosure so that we can |
3099 class VerifyRootsClosure: public OopClosure { |
3100 // pass it as the perm_blk to SharedHeap::process_strong_roots. |
|
3101 // When process_strong_roots stop calling perm_blk->younger_refs_iterate |
|
3102 // we can change this closure to extend the simpler OopClosure. |
|
3103 class VerifyRootsClosure: public OopsInGenClosure { |
|
3104 private: |
3100 private: |
3105 G1CollectedHeap* _g1h; |
3101 G1CollectedHeap* _g1h; |
3106 VerifyOption _vo; |
3102 VerifyOption _vo; |
3107 bool _failures; |
3103 bool _failures; |
3108 public: |
3104 public: |
4668 _par_scan_state(par_scan_state), |
4664 _par_scan_state(par_scan_state), |
4669 _worker_id(par_scan_state->queue_num()), |
4665 _worker_id(par_scan_state->queue_num()), |
4670 _during_initial_mark(_g1->g1_policy()->during_initial_mark_pause()), |
4666 _during_initial_mark(_g1->g1_policy()->during_initial_mark_pause()), |
4671 _mark_in_progress(_g1->mark_in_progress()) { } |
4667 _mark_in_progress(_g1->mark_in_progress()) { } |
4672 |
4668 |
4673 template <bool do_gen_barrier, G1Barrier barrier, bool do_mark_object> |
4669 template <G1Barrier barrier, bool do_mark_object> |
4674 void G1ParCopyClosure<do_gen_barrier, barrier, do_mark_object>::mark_object(oop obj) { |
4670 void G1ParCopyClosure<barrier, do_mark_object>::mark_object(oop obj) { |
4675 #ifdef ASSERT |
4671 #ifdef ASSERT |
4676 HeapRegion* hr = _g1->heap_region_containing(obj); |
4672 HeapRegion* hr = _g1->heap_region_containing(obj); |
4677 assert(hr != NULL, "sanity"); |
4673 assert(hr != NULL, "sanity"); |
4678 assert(!hr->in_collection_set(), "should not mark objects in the CSet"); |
4674 assert(!hr->in_collection_set(), "should not mark objects in the CSet"); |
4679 #endif // ASSERT |
4675 #endif // ASSERT |
4680 |
4676 |
4681 // We know that the object is not moving so it's safe to read its size. |
4677 // We know that the object is not moving so it's safe to read its size. |
4682 _cm->grayRoot(obj, (size_t) obj->size(), _worker_id); |
4678 _cm->grayRoot(obj, (size_t) obj->size(), _worker_id); |
4683 } |
4679 } |
4684 |
4680 |
4685 template <bool do_gen_barrier, G1Barrier barrier, bool do_mark_object> |
4681 template <G1Barrier barrier, bool do_mark_object> |
4686 void G1ParCopyClosure<do_gen_barrier, barrier, do_mark_object> |
4682 void G1ParCopyClosure<barrier, do_mark_object> |
4687 ::mark_forwarded_object(oop from_obj, oop to_obj) { |
4683 ::mark_forwarded_object(oop from_obj, oop to_obj) { |
4688 #ifdef ASSERT |
4684 #ifdef ASSERT |
4689 assert(from_obj->is_forwarded(), "from obj should be forwarded"); |
4685 assert(from_obj->is_forwarded(), "from obj should be forwarded"); |
4690 assert(from_obj->forwardee() == to_obj, "to obj should be the forwardee"); |
4686 assert(from_obj->forwardee() == to_obj, "to obj should be the forwardee"); |
4691 assert(from_obj != to_obj, "should not be self-forwarded"); |
4687 assert(from_obj != to_obj, "should not be self-forwarded"); |
4704 // well-formed. So we have to read its size from its from-space |
4700 // well-formed. So we have to read its size from its from-space |
4705 // image which we know should not be changing. |
4701 // image which we know should not be changing. |
4706 _cm->grayRoot(to_obj, (size_t) from_obj->size(), _worker_id); |
4702 _cm->grayRoot(to_obj, (size_t) from_obj->size(), _worker_id); |
4707 } |
4703 } |
4708 |
4704 |
4709 template <bool do_gen_barrier, G1Barrier barrier, bool do_mark_object> |
4705 template <G1Barrier barrier, bool do_mark_object> |
4710 oop G1ParCopyClosure<do_gen_barrier, barrier, do_mark_object> |
4706 oop G1ParCopyClosure<barrier, do_mark_object> |
4711 ::copy_to_survivor_space(oop old) { |
4707 ::copy_to_survivor_space(oop old) { |
4712 size_t word_sz = old->size(); |
4708 size_t word_sz = old->size(); |
4713 HeapRegion* from_region = _g1->heap_region_containing_raw(old); |
4709 HeapRegion* from_region = _g1->heap_region_containing_raw(old); |
4714 // +1 to make the -1 indexes valid... |
4710 // +1 to make the -1 indexes valid... |
4715 int young_index = from_region->young_index_in_cset()+1; |
4711 int young_index = from_region->young_index_in_cset()+1; |
4801 if (_g1->heap_region_containing_raw(new_obj)->is_young()) { |
4797 if (_g1->heap_region_containing_raw(new_obj)->is_young()) { |
4802 _scanned_klass->record_modified_oops(); |
4798 _scanned_klass->record_modified_oops(); |
4803 } |
4799 } |
4804 } |
4800 } |
4805 |
4801 |
4806 template <bool do_gen_barrier, G1Barrier barrier, bool do_mark_object> |
4802 template <G1Barrier barrier, bool do_mark_object> |
4807 template <class T> |
4803 template <class T> |
4808 void G1ParCopyClosure<do_gen_barrier, barrier, do_mark_object> |
4804 void G1ParCopyClosure<barrier, do_mark_object> |
4809 ::do_oop_work(T* p) { |
4805 ::do_oop_work(T* p) { |
4810 oop obj = oopDesc::load_decode_heap_oop(p); |
4806 oop obj = oopDesc::load_decode_heap_oop(p); |
4811 assert(barrier != G1BarrierRS || obj != NULL, |
|
4812 "Precondition: G1BarrierRS implies obj is non-NULL"); |
|
4813 |
4807 |
4814 assert(_worker_id == _par_scan_state->queue_num(), "sanity"); |
4808 assert(_worker_id == _par_scan_state->queue_num(), "sanity"); |
4815 |
4809 |
4816 // here the null check is implicit in the cset_fast_test() test |
4810 // here the null check is implicit in the cset_fast_test() test |
4817 if (_g1->in_cset_fast_test(obj)) { |
4811 if (_g1->in_cset_fast_test(obj)) { |
4827 // If the object is self-forwarded we don't need to explicitly |
4821 // If the object is self-forwarded we don't need to explicitly |
4828 // mark it, the evacuation failure protocol will do so. |
4822 // mark it, the evacuation failure protocol will do so. |
4829 mark_forwarded_object(obj, forwardee); |
4823 mark_forwarded_object(obj, forwardee); |
4830 } |
4824 } |
4831 |
4825 |
4832 // When scanning the RS, we only care about objs in CS. |
4826 if (barrier == G1BarrierKlass) { |
4833 if (barrier == G1BarrierRS) { |
|
4834 _par_scan_state->update_rs(_from, p, _worker_id); |
|
4835 } else if (barrier == G1BarrierKlass) { |
|
4836 do_klass_barrier(p, forwardee); |
4827 do_klass_barrier(p, forwardee); |
4837 } |
4828 } |
4838 } else { |
4829 } else { |
4839 // The object is not in collection set. If we're a root scanning |
4830 // The object is not in collection set. If we're a root scanning |
4840 // closure during an initial mark pause (i.e. do_mark_object will |
4831 // closure during an initial mark pause (i.e. do_mark_object will |
4845 } |
4836 } |
4846 |
4837 |
4847 if (barrier == G1BarrierEvac && obj != NULL) { |
4838 if (barrier == G1BarrierEvac && obj != NULL) { |
4848 _par_scan_state->update_rs(_from, p, _worker_id); |
4839 _par_scan_state->update_rs(_from, p, _worker_id); |
4849 } |
4840 } |
4850 |
4841 } |
4851 if (do_gen_barrier && obj != NULL) { |
4842 |
4852 par_do_barrier(p); |
4843 template void G1ParCopyClosure<G1BarrierEvac, false>::do_oop_work(oop* p); |
4853 } |
4844 template void G1ParCopyClosure<G1BarrierEvac, false>::do_oop_work(narrowOop* p); |
4854 } |
|
4855 |
|
4856 template void G1ParCopyClosure<false, G1BarrierEvac, false>::do_oop_work(oop* p); |
|
4857 template void G1ParCopyClosure<false, G1BarrierEvac, false>::do_oop_work(narrowOop* p); |
|
4858 |
4845 |
4859 template <class T> void G1ParScanPartialArrayClosure::do_oop_nv(T* p) { |
4846 template <class T> void G1ParScanPartialArrayClosure::do_oop_nv(T* p) { |
4860 assert(has_partial_array_mask(p), "invariant"); |
4847 assert(has_partial_array_mask(p), "invariant"); |
4861 oop from_obj = clear_partial_array_mask(p); |
4848 oop from_obj = clear_partial_array_mask(p); |
4862 |
4849 |