Mercurial > hg > graal-jvmci-8
comparison src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @ 1862:b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
Reviewed-by: iveresov, tonyp
author | jcoomes |
---|---|
date | Tue, 12 Oct 2010 11:29:45 -0700 |
parents | c32059ef4dc0 |
children | 35e4e086d5f5 |
comparison
equal
deleted
inserted
replaced
1861:c32059ef4dc0 | 1862:b14ec34b1e07 |
---|---|
3843 (alloc_buffer_waste() + undo_waste()) * HeapWordSize / K, | 3843 (alloc_buffer_waste() + undo_waste()) * HeapWordSize / K, |
3844 alloc_buffer_waste() * HeapWordSize / K, | 3844 alloc_buffer_waste() * HeapWordSize / K, |
3845 undo_waste() * HeapWordSize / K); | 3845 undo_waste() * HeapWordSize / K); |
3846 } | 3846 } |
3847 | 3847 |
3848 #ifdef ASSERT | |
3849 bool G1ParScanThreadState::verify_ref(narrowOop* ref) const { | |
3850 assert(ref != NULL, "invariant"); | |
3851 assert(UseCompressedOops, "sanity"); | |
3852 assert(!has_partial_array_mask(ref), err_msg("ref=" PTR_FORMAT, ref)); | |
3853 oop p = oopDesc::load_decode_heap_oop(ref); | |
3854 assert(_g1h->is_in_g1_reserved(p), | |
3855 err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, ref, intptr_t(p))); | |
3856 return true; | |
3857 } | |
3858 | |
3859 bool G1ParScanThreadState::verify_ref(oop* ref) const { | |
3860 assert(ref != NULL, "invariant"); | |
3861 if (has_partial_array_mask(ref)) { | |
3862 // Must be in the collection set--it's already been copied. | |
3863 oop p = clear_partial_array_mask(ref); | |
3864 assert(_g1h->obj_in_cs(p), | |
3865 err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, ref, intptr_t(p))); | |
3866 } else { | |
3867 oop p = oopDesc::load_decode_heap_oop(ref); | |
3868 assert(_g1h->is_in_g1_reserved(p), | |
3869 err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, ref, intptr_t(p))); | |
3870 } | |
3871 return true; | |
3872 } | |
3873 | |
3874 bool G1ParScanThreadState::verify_task(StarTask ref) const { | |
3875 if (ref.is_narrow()) { | |
3876 return verify_ref((narrowOop*) ref); | |
3877 } else { | |
3878 return verify_ref((oop*) ref); | |
3879 } | |
3880 } | |
3881 #endif // ASSERT | |
3882 | |
3883 void G1ParScanThreadState::trim_queue() { | |
3884 StarTask ref; | |
3885 do { | |
3886 // Drain the overflow stack first, so other threads can steal. | |
3887 while (refs()->pop_overflow(ref)) { | |
3888 deal_with_reference(ref); | |
3889 } | |
3890 while (refs()->pop_local(ref)) { | |
3891 deal_with_reference(ref); | |
3892 } | |
3893 } while (!refs()->is_empty()); | |
3894 } | |
3895 | |
3848 G1ParClosureSuper::G1ParClosureSuper(G1CollectedHeap* g1, G1ParScanThreadState* par_scan_state) : | 3896 G1ParClosureSuper::G1ParClosureSuper(G1CollectedHeap* g1, G1ParScanThreadState* par_scan_state) : |
3849 _g1(g1), _g1_rem(_g1->g1_rem_set()), _cm(_g1->concurrent_mark()), | 3897 _g1(g1), _g1_rem(_g1->g1_rem_set()), _cm(_g1->concurrent_mark()), |
3850 _par_scan_state(par_scan_state) { } | 3898 _par_scan_state(par_scan_state) { } |
3851 | 3899 |
3852 template <class T> void G1ParCopyHelper::mark_forwardee(T* p) { | 3900 template <class T> void G1ParCopyHelper::mark_forwardee(T* p) { |
4045 RefToScanQueueSet* queues, | 4093 RefToScanQueueSet* queues, |
4046 ParallelTaskTerminator* terminator) | 4094 ParallelTaskTerminator* terminator) |
4047 : _g1h(g1h), _par_scan_state(par_scan_state), | 4095 : _g1h(g1h), _par_scan_state(par_scan_state), |
4048 _queues(queues), _terminator(terminator) {} | 4096 _queues(queues), _terminator(terminator) {} |
4049 | 4097 |
4050 void do_void() { | 4098 void do_void(); |
4051 G1ParScanThreadState* pss = par_scan_state(); | 4099 |
4052 while (true) { | 4100 private: |
4101 inline bool offer_termination(); | |
4102 }; | |
4103 | |
4104 bool G1ParEvacuateFollowersClosure::offer_termination() { | |
4105 G1ParScanThreadState* const pss = par_scan_state(); | |
4106 pss->start_term_time(); | |
4107 const bool res = terminator()->offer_termination(); | |
4108 pss->end_term_time(); | |
4109 return res; | |
4110 } | |
4111 | |
4112 void G1ParEvacuateFollowersClosure::do_void() { | |
4113 StarTask stolen_task; | |
4114 G1ParScanThreadState* const pss = par_scan_state(); | |
4115 pss->trim_queue(); | |
4116 | |
4117 do { | |
4118 while (queues()->steal(pss->queue_num(), pss->hash_seed(), stolen_task)) { | |
4119 assert(pss->verify_task(stolen_task), "sanity"); | |
4120 if (stolen_task.is_narrow()) { | |
4121 pss->push_on_queue((narrowOop*) stolen_task); | |
4122 } else { | |
4123 pss->push_on_queue((oop*) stolen_task); | |
4124 } | |
4053 pss->trim_queue(); | 4125 pss->trim_queue(); |
4054 | 4126 } |
4055 StarTask stolen_task; | 4127 } while (!offer_termination()); |
4056 if (queues()->steal(pss->queue_num(), pss->hash_seed(), stolen_task)) { | 4128 |
4057 // slightly paranoid tests; I'm trying to catch potential | 4129 pss->retire_alloc_buffers(); |
4058 // problems before we go into push_on_queue to know where the | 4130 } |
4059 // problem is coming from | |
4060 assert((oop*)stolen_task != NULL, "Error"); | |
4061 if (stolen_task.is_narrow()) { | |
4062 assert(UseCompressedOops, "Error"); | |
4063 narrowOop* p = (narrowOop*) stolen_task; | |
4064 assert(has_partial_array_mask(p) || | |
4065 _g1h->is_in_g1_reserved(oopDesc::load_decode_heap_oop(p)), "Error"); | |
4066 pss->push_on_queue(p); | |
4067 } else { | |
4068 oop* p = (oop*) stolen_task; | |
4069 assert(has_partial_array_mask(p) || _g1h->is_in_g1_reserved(*p), "Error"); | |
4070 pss->push_on_queue(p); | |
4071 } | |
4072 continue; | |
4073 } | |
4074 pss->start_term_time(); | |
4075 if (terminator()->offer_termination()) break; | |
4076 pss->end_term_time(); | |
4077 } | |
4078 pss->end_term_time(); | |
4079 pss->retire_alloc_buffers(); | |
4080 } | |
4081 }; | |
4082 | 4131 |
4083 class G1ParTask : public AbstractGangTask { | 4132 class G1ParTask : public AbstractGangTask { |
4084 protected: | 4133 protected: |
4085 G1CollectedHeap* _g1h; | 4134 G1CollectedHeap* _g1h; |
4086 RefToScanQueueSet *_queues; | 4135 RefToScanQueueSet *_queues; |
4175 if (ParallelGCVerbose) { | 4224 if (ParallelGCVerbose) { |
4176 MutexLocker x(stats_lock()); | 4225 MutexLocker x(stats_lock()); |
4177 pss.print_termination_stats(i); | 4226 pss.print_termination_stats(i); |
4178 } | 4227 } |
4179 | 4228 |
4180 assert(pss.refs_to_scan() == 0, "Task queue should be empty"); | 4229 assert(pss.refs()->is_empty(), "should be empty"); |
4181 assert(pss.overflowed_refs_to_scan() == 0, "Overflow queue should be empty"); | |
4182 double end_time_ms = os::elapsedTime() * 1000.0; | 4230 double end_time_ms = os::elapsedTime() * 1000.0; |
4183 _g1h->g1_policy()->record_gc_worker_end_time(i, end_time_ms); | 4231 _g1h->g1_policy()->record_gc_worker_end_time(i, end_time_ms); |
4184 } | 4232 } |
4185 }; | 4233 }; |
4186 | 4234 |