1.1 --- a/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp Fri Aug 14 13:44:15 2009 -0700 1.2 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp Mon Aug 24 10:36:31 2009 -0700 1.3 @@ -92,17 +92,50 @@ 1.4 } 1.5 }; 1.6 1.7 +// KlassRememberingOopClosure is used when marking of the permanent generation 1.8 +// is being done. It adds fields to support revisiting of klasses 1.9 +// for class unloading. _should_remember_klasses should be set to 1.10 +// indicate if klasses should be remembered. Currently that is whenever 1.11 +// CMS class unloading is turned on. The _revisit_stack is used 1.12 +// to save the klasses for later processing. 1.13 +class KlassRememberingOopClosure : public OopClosure { 1.14 + protected: 1.15 + CMSCollector* _collector; 1.16 + CMSMarkStack* _revisit_stack; 1.17 + bool const _should_remember_klasses; 1.18 + public: 1.19 + void check_remember_klasses() const PRODUCT_RETURN; 1.20 + virtual const bool should_remember_klasses() const { 1.21 + check_remember_klasses(); 1.22 + return _should_remember_klasses; 1.23 + } 1.24 + virtual void remember_klass(Klass* k); 1.25 + 1.26 + KlassRememberingOopClosure(CMSCollector* collector, 1.27 + ReferenceProcessor* rp, 1.28 + CMSMarkStack* revisit_stack); 1.29 +}; 1.30 + 1.31 +// Similar to KlassRememberingOopClosure for use when multiple 1.32 +// GC threads will execute the closure. 1.33 + 1.34 +class Par_KlassRememberingOopClosure : public KlassRememberingOopClosure { 1.35 + public: 1.36 + Par_KlassRememberingOopClosure(CMSCollector* collector, 1.37 + ReferenceProcessor* rp, 1.38 + CMSMarkStack* revisit_stack): 1.39 + KlassRememberingOopClosure(collector, rp, revisit_stack) {} 1.40 + virtual void remember_klass(Klass* k); 1.41 +}; 1.42 + 1.43 // The non-parallel version (the parallel version appears further below). 1.44 -class PushAndMarkClosure: public OopClosure { 1.45 +class PushAndMarkClosure: public KlassRememberingOopClosure { 1.46 private: 1.47 - CMSCollector* _collector; 1.48 MemRegion _span; 1.49 CMSBitMap* _bit_map; 1.50 CMSBitMap* _mod_union_table; 1.51 CMSMarkStack* _mark_stack; 1.52 - CMSMarkStack* _revisit_stack; 1.53 bool _concurrent_precleaning; 1.54 - bool const _should_remember_klasses; 1.55 protected: 1.56 DO_OOP_WORK_DEFN 1.57 public: 1.58 @@ -122,10 +155,6 @@ 1.59 Prefetch::style prefetch_style() { 1.60 return Prefetch::do_read; 1.61 } 1.62 - virtual const bool should_remember_klasses() const { 1.63 - return _should_remember_klasses; 1.64 - } 1.65 - virtual void remember_klass(Klass* k); 1.66 }; 1.67 1.68 // In the parallel case, the revisit stack, the bit map and the 1.69 @@ -134,14 +163,11 @@ 1.70 // synchronization (for instance, via CAS). The marking stack 1.71 // used in the non-parallel case above is here replaced with 1.72 // an OopTaskQueue structure to allow efficient work stealing. 1.73 -class Par_PushAndMarkClosure: public OopClosure { 1.74 +class Par_PushAndMarkClosure: public Par_KlassRememberingOopClosure { 1.75 private: 1.76 - CMSCollector* _collector; 1.77 MemRegion _span; 1.78 CMSBitMap* _bit_map; 1.79 OopTaskQueue* _work_queue; 1.80 - CMSMarkStack* _revisit_stack; 1.81 - bool const _should_remember_klasses; 1.82 protected: 1.83 DO_OOP_WORK_DEFN 1.84 public: 1.85 @@ -159,10 +185,6 @@ 1.86 Prefetch::style prefetch_style() { 1.87 return Prefetch::do_read; 1.88 } 1.89 - virtual const bool should_remember_klasses() const { 1.90 - return _should_remember_klasses; 1.91 - } 1.92 - virtual void remember_klass(Klass* k); 1.93 }; 1.94 1.95 // The non-parallel version (the parallel version appears further below). 1.96 @@ -201,6 +223,12 @@ 1.97 void set_freelistLock(Mutex* m) { 1.98 _freelistLock = m; 1.99 } 1.100 + virtual const bool should_remember_klasses() const { 1.101 + return _pushAndMarkClosure.should_remember_klasses(); 1.102 + } 1.103 + virtual void remember_klass(Klass* k) { 1.104 + _pushAndMarkClosure.remember_klass(k); 1.105 + } 1.106 1.107 private: 1.108 inline void do_yield_check(); 1.109 @@ -234,6 +262,16 @@ 1.110 inline void do_oop_nv(narrowOop* p) { Par_MarkRefsIntoAndScanClosure::do_oop_work(p); } 1.111 bool do_header() { return true; } 1.112 virtual const bool do_nmethods() const { return true; } 1.113 + // When ScanMarkedObjectsAgainClosure is used, 1.114 + // it passes [Par_]MarkRefsIntoAndScanClosure to oop_oop_iterate(), 1.115 + // and this delegation is used. 1.116 + virtual const bool should_remember_klasses() const { 1.117 + return _par_pushAndMarkClosure.should_remember_klasses(); 1.118 + } 1.119 + // See comment on should_remember_klasses() above. 1.120 + virtual void remember_klass(Klass* k) { 1.121 + _par_pushAndMarkClosure.remember_klass(k); 1.122 + } 1.123 Prefetch::style prefetch_style() { 1.124 return Prefetch::do_read; 1.125 } 1.126 @@ -243,17 +281,14 @@ 1.127 // This closure is used during the concurrent marking phase 1.128 // following the first checkpoint. Its use is buried in 1.129 // the closure MarkFromRootsClosure. 1.130 -class PushOrMarkClosure: public OopClosure { 1.131 +class PushOrMarkClosure: public KlassRememberingOopClosure { 1.132 private: 1.133 - CMSCollector* _collector; 1.134 MemRegion _span; 1.135 CMSBitMap* _bitMap; 1.136 CMSMarkStack* _markStack; 1.137 - CMSMarkStack* _revisitStack; 1.138 HeapWord* const _finger; 1.139 MarkFromRootsClosure* const 1.140 _parent; 1.141 - bool const _should_remember_klasses; 1.142 protected: 1.143 DO_OOP_WORK_DEFN 1.144 public: 1.145 @@ -268,10 +303,6 @@ 1.146 virtual void do_oop(narrowOop* p); 1.147 inline void do_oop_nv(oop* p) { PushOrMarkClosure::do_oop_work(p); } 1.148 inline void do_oop_nv(narrowOop* p) { PushOrMarkClosure::do_oop_work(p); } 1.149 - virtual const bool should_remember_klasses() const { 1.150 - return _should_remember_klasses; 1.151 - } 1.152 - virtual void remember_klass(Klass* k); 1.153 // Deal with a stack overflow condition 1.154 void handle_stack_overflow(HeapWord* lost); 1.155 private: 1.156 @@ -282,20 +313,17 @@ 1.157 // This closure is used during the concurrent marking phase 1.158 // following the first checkpoint. Its use is buried in 1.159 // the closure Par_MarkFromRootsClosure. 1.160 -class Par_PushOrMarkClosure: public OopClosure { 1.161 +class Par_PushOrMarkClosure: public Par_KlassRememberingOopClosure { 1.162 private: 1.163 - CMSCollector* _collector; 1.164 MemRegion _whole_span; 1.165 MemRegion _span; // local chunk 1.166 CMSBitMap* _bit_map; 1.167 OopTaskQueue* _work_queue; 1.168 CMSMarkStack* _overflow_stack; 1.169 - CMSMarkStack* _revisit_stack; 1.170 HeapWord* const _finger; 1.171 HeapWord** const _global_finger_addr; 1.172 Par_MarkFromRootsClosure* const 1.173 _parent; 1.174 - bool const _should_remember_klasses; 1.175 protected: 1.176 DO_OOP_WORK_DEFN 1.177 public: 1.178 @@ -312,10 +340,6 @@ 1.179 virtual void do_oop(narrowOop* p); 1.180 inline void do_oop_nv(oop* p) { Par_PushOrMarkClosure::do_oop_work(p); } 1.181 inline void do_oop_nv(narrowOop* p) { Par_PushOrMarkClosure::do_oop_work(p); } 1.182 - virtual const bool should_remember_klasses() const { 1.183 - return _should_remember_klasses; 1.184 - } 1.185 - virtual void remember_klass(Klass* k); 1.186 // Deal with a stack overflow condition 1.187 void handle_stack_overflow(HeapWord* lost); 1.188 private: 1.189 @@ -328,9 +352,8 @@ 1.190 // processing phase of the CMS final checkpoint step, as 1.191 // well as during the concurrent precleaning of the discovered 1.192 // reference lists. 1.193 -class CMSKeepAliveClosure: public OopClosure { 1.194 +class CMSKeepAliveClosure: public KlassRememberingOopClosure { 1.195 private: 1.196 - CMSCollector* _collector; 1.197 const MemRegion _span; 1.198 CMSMarkStack* _mark_stack; 1.199 CMSBitMap* _bit_map; 1.200 @@ -340,14 +363,7 @@ 1.201 public: 1.202 CMSKeepAliveClosure(CMSCollector* collector, MemRegion span, 1.203 CMSBitMap* bit_map, CMSMarkStack* mark_stack, 1.204 - bool cpc): 1.205 - _collector(collector), 1.206 - _span(span), 1.207 - _bit_map(bit_map), 1.208 - _mark_stack(mark_stack), 1.209 - _concurrent_precleaning(cpc) { 1.210 - assert(!_span.is_empty(), "Empty span could spell trouble"); 1.211 - } 1.212 + CMSMarkStack* revisit_stack, bool cpc); 1.213 bool concurrent_precleaning() const { return _concurrent_precleaning; } 1.214 virtual void do_oop(oop* p); 1.215 virtual void do_oop(narrowOop* p); 1.216 @@ -355,9 +371,8 @@ 1.217 inline void do_oop_nv(narrowOop* p) { CMSKeepAliveClosure::do_oop_work(p); } 1.218 }; 1.219 1.220 -class CMSInnerParMarkAndPushClosure: public OopClosure { 1.221 +class CMSInnerParMarkAndPushClosure: public Par_KlassRememberingOopClosure { 1.222 private: 1.223 - CMSCollector* _collector; 1.224 MemRegion _span; 1.225 OopTaskQueue* _work_queue; 1.226 CMSBitMap* _bit_map; 1.227 @@ -366,11 +381,8 @@ 1.228 public: 1.229 CMSInnerParMarkAndPushClosure(CMSCollector* collector, 1.230 MemRegion span, CMSBitMap* bit_map, 1.231 - OopTaskQueue* work_queue): 1.232 - _collector(collector), 1.233 - _span(span), 1.234 - _bit_map(bit_map), 1.235 - _work_queue(work_queue) { } 1.236 + CMSMarkStack* revisit_stack, 1.237 + OopTaskQueue* work_queue); 1.238 virtual void do_oop(oop* p); 1.239 virtual void do_oop(narrowOop* p); 1.240 inline void do_oop_nv(oop* p) { CMSInnerParMarkAndPushClosure::do_oop_work(p); } 1.241 @@ -380,9 +392,8 @@ 1.242 // A parallel (MT) version of the above, used when 1.243 // reference processing is parallel; the only difference 1.244 // is in the do_oop method. 1.245 -class CMSParKeepAliveClosure: public OopClosure { 1.246 +class CMSParKeepAliveClosure: public Par_KlassRememberingOopClosure { 1.247 private: 1.248 - CMSCollector* _collector; 1.249 MemRegion _span; 1.250 OopTaskQueue* _work_queue; 1.251 CMSBitMap* _bit_map; 1.252 @@ -394,7 +405,8 @@ 1.253 DO_OOP_WORK_DEFN 1.254 public: 1.255 CMSParKeepAliveClosure(CMSCollector* collector, MemRegion span, 1.256 - CMSBitMap* bit_map, OopTaskQueue* work_queue); 1.257 + CMSBitMap* bit_map, CMSMarkStack* revisit_stack, 1.258 + OopTaskQueue* work_queue); 1.259 virtual void do_oop(oop* p); 1.260 virtual void do_oop(narrowOop* p); 1.261 inline void do_oop_nv(oop* p) { CMSParKeepAliveClosure::do_oop_work(p); }