1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp Wed Apr 27 01:25:04 2016 +0800 1.3 @@ -0,0 +1,426 @@ 1.4 +/* 1.5 + * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#ifndef SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_CMSOOPCLOSURES_HPP 1.29 +#define SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_CMSOOPCLOSURES_HPP 1.30 + 1.31 +#include "memory/genOopClosures.hpp" 1.32 + 1.33 +///////////////////////////////////////////////////////////////// 1.34 +// Closures used by ConcurrentMarkSweepGeneration's collector 1.35 +///////////////////////////////////////////////////////////////// 1.36 +class ConcurrentMarkSweepGeneration; 1.37 +class CMSBitMap; 1.38 +class CMSMarkStack; 1.39 +class CMSCollector; 1.40 +class MarkFromRootsClosure; 1.41 +class Par_MarkFromRootsClosure; 1.42 + 1.43 +// Decode the oop and call do_oop on it. 1.44 +#define DO_OOP_WORK_DEFN \ 1.45 + void do_oop(oop obj); \ 1.46 + template <class T> inline void do_oop_work(T* p) { \ 1.47 + T heap_oop = oopDesc::load_heap_oop(p); \ 1.48 + if (!oopDesc::is_null(heap_oop)) { \ 1.49 + oop obj = oopDesc::decode_heap_oop_not_null(heap_oop); \ 1.50 + do_oop(obj); \ 1.51 + } \ 1.52 + } 1.53 + 1.54 +// Applies the given oop closure to all oops in all klasses visited. 1.55 +class CMKlassClosure : public KlassClosure { 1.56 + friend class CMSOopClosure; 1.57 + friend class CMSOopsInGenClosure; 1.58 + 1.59 + OopClosure* _oop_closure; 1.60 + 1.61 + // Used when _oop_closure couldn't be set in an initialization list. 1.62 + void initialize(OopClosure* oop_closure) { 1.63 + assert(_oop_closure == NULL, "Should only be called once"); 1.64 + _oop_closure = oop_closure; 1.65 + } 1.66 + public: 1.67 + CMKlassClosure(OopClosure* oop_closure = NULL) : _oop_closure(oop_closure) { } 1.68 + 1.69 + void do_klass(Klass* k); 1.70 +}; 1.71 + 1.72 +// The base class for all CMS marking closures. 1.73 +// It's used to proxy through the metadata to the oops defined in them. 1.74 +class CMSOopClosure: public ExtendedOopClosure { 1.75 + CMKlassClosure _klass_closure; 1.76 + public: 1.77 + CMSOopClosure() : ExtendedOopClosure() { 1.78 + _klass_closure.initialize(this); 1.79 + } 1.80 + CMSOopClosure(ReferenceProcessor* rp) : ExtendedOopClosure(rp) { 1.81 + _klass_closure.initialize(this); 1.82 + } 1.83 + 1.84 + virtual bool do_metadata() { return do_metadata_nv(); } 1.85 + inline bool do_metadata_nv() { return true; } 1.86 + 1.87 + virtual void do_klass(Klass* k); 1.88 + void do_klass_nv(Klass* k); 1.89 + 1.90 + virtual void do_class_loader_data(ClassLoaderData* cld); 1.91 +}; 1.92 + 1.93 +// TODO: This duplication of the CMSOopClosure class is only needed because 1.94 +// some CMS OopClosures derive from OopsInGenClosure. It would be good 1.95 +// to get rid of them completely. 1.96 +class CMSOopsInGenClosure: public OopsInGenClosure { 1.97 + CMKlassClosure _klass_closure; 1.98 + public: 1.99 + CMSOopsInGenClosure() { 1.100 + _klass_closure.initialize(this); 1.101 + } 1.102 + 1.103 + virtual bool do_metadata() { return do_metadata_nv(); } 1.104 + inline bool do_metadata_nv() { return true; } 1.105 + 1.106 + virtual void do_klass(Klass* k); 1.107 + void do_klass_nv(Klass* k); 1.108 + 1.109 + virtual void do_class_loader_data(ClassLoaderData* cld); 1.110 +}; 1.111 + 1.112 +class MarkRefsIntoClosure: public CMSOopsInGenClosure { 1.113 + private: 1.114 + const MemRegion _span; 1.115 + CMSBitMap* _bitMap; 1.116 + protected: 1.117 + DO_OOP_WORK_DEFN 1.118 + public: 1.119 + MarkRefsIntoClosure(MemRegion span, CMSBitMap* bitMap); 1.120 + virtual void do_oop(oop* p); 1.121 + virtual void do_oop(narrowOop* p); 1.122 + 1.123 + Prefetch::style prefetch_style() { 1.124 + return Prefetch::do_read; 1.125 + } 1.126 +}; 1.127 + 1.128 +class Par_MarkRefsIntoClosure: public CMSOopsInGenClosure { 1.129 + private: 1.130 + const MemRegion _span; 1.131 + CMSBitMap* _bitMap; 1.132 + protected: 1.133 + DO_OOP_WORK_DEFN 1.134 + public: 1.135 + Par_MarkRefsIntoClosure(MemRegion span, CMSBitMap* bitMap); 1.136 + virtual void do_oop(oop* p); 1.137 + virtual void do_oop(narrowOop* p); 1.138 + 1.139 + Prefetch::style prefetch_style() { 1.140 + return Prefetch::do_read; 1.141 + } 1.142 +}; 1.143 + 1.144 +// A variant of the above used in certain kinds of CMS 1.145 +// marking verification. 1.146 +class MarkRefsIntoVerifyClosure: public CMSOopsInGenClosure { 1.147 + private: 1.148 + const MemRegion _span; 1.149 + CMSBitMap* _verification_bm; 1.150 + CMSBitMap* _cms_bm; 1.151 + protected: 1.152 + DO_OOP_WORK_DEFN 1.153 + public: 1.154 + MarkRefsIntoVerifyClosure(MemRegion span, CMSBitMap* verification_bm, 1.155 + CMSBitMap* cms_bm); 1.156 + virtual void do_oop(oop* p); 1.157 + virtual void do_oop(narrowOop* p); 1.158 + 1.159 + Prefetch::style prefetch_style() { 1.160 + return Prefetch::do_read; 1.161 + } 1.162 +}; 1.163 + 1.164 +// The non-parallel version (the parallel version appears further below). 1.165 +class PushAndMarkClosure: public CMSOopClosure { 1.166 + private: 1.167 + CMSCollector* _collector; 1.168 + MemRegion _span; 1.169 + CMSBitMap* _bit_map; 1.170 + CMSBitMap* _mod_union_table; 1.171 + CMSMarkStack* _mark_stack; 1.172 + bool _concurrent_precleaning; 1.173 + protected: 1.174 + DO_OOP_WORK_DEFN 1.175 + public: 1.176 + PushAndMarkClosure(CMSCollector* collector, 1.177 + MemRegion span, 1.178 + ReferenceProcessor* rp, 1.179 + CMSBitMap* bit_map, 1.180 + CMSBitMap* mod_union_table, 1.181 + CMSMarkStack* mark_stack, 1.182 + bool concurrent_precleaning); 1.183 + virtual void do_oop(oop* p); 1.184 + virtual void do_oop(narrowOop* p); 1.185 + inline void do_oop_nv(oop* p) { PushAndMarkClosure::do_oop_work(p); } 1.186 + inline void do_oop_nv(narrowOop* p) { PushAndMarkClosure::do_oop_work(p); } 1.187 + 1.188 + Prefetch::style prefetch_style() { 1.189 + return Prefetch::do_read; 1.190 + } 1.191 +}; 1.192 + 1.193 +// In the parallel case, the bit map and the 1.194 +// reference processor are currently all shared. Access to 1.195 +// these shared mutable structures must use appropriate 1.196 +// synchronization (for instance, via CAS). The marking stack 1.197 +// used in the non-parallel case above is here replaced with 1.198 +// an OopTaskQueue structure to allow efficient work stealing. 1.199 +class Par_PushAndMarkClosure: public CMSOopClosure { 1.200 + private: 1.201 + CMSCollector* _collector; 1.202 + MemRegion _span; 1.203 + CMSBitMap* _bit_map; 1.204 + OopTaskQueue* _work_queue; 1.205 + protected: 1.206 + DO_OOP_WORK_DEFN 1.207 + public: 1.208 + Par_PushAndMarkClosure(CMSCollector* collector, 1.209 + MemRegion span, 1.210 + ReferenceProcessor* rp, 1.211 + CMSBitMap* bit_map, 1.212 + OopTaskQueue* work_queue); 1.213 + virtual void do_oop(oop* p); 1.214 + virtual void do_oop(narrowOop* p); 1.215 + inline void do_oop_nv(oop* p) { Par_PushAndMarkClosure::do_oop_work(p); } 1.216 + inline void do_oop_nv(narrowOop* p) { Par_PushAndMarkClosure::do_oop_work(p); } 1.217 + 1.218 + Prefetch::style prefetch_style() { 1.219 + return Prefetch::do_read; 1.220 + } 1.221 +}; 1.222 + 1.223 +// The non-parallel version (the parallel version appears further below). 1.224 +class MarkRefsIntoAndScanClosure: public CMSOopsInGenClosure { 1.225 + private: 1.226 + MemRegion _span; 1.227 + CMSBitMap* _bit_map; 1.228 + CMSMarkStack* _mark_stack; 1.229 + PushAndMarkClosure _pushAndMarkClosure; 1.230 + CMSCollector* _collector; 1.231 + Mutex* _freelistLock; 1.232 + bool _yield; 1.233 + // Whether closure is being used for concurrent precleaning 1.234 + bool _concurrent_precleaning; 1.235 + protected: 1.236 + DO_OOP_WORK_DEFN 1.237 + public: 1.238 + MarkRefsIntoAndScanClosure(MemRegion span, 1.239 + ReferenceProcessor* rp, 1.240 + CMSBitMap* bit_map, 1.241 + CMSBitMap* mod_union_table, 1.242 + CMSMarkStack* mark_stack, 1.243 + CMSCollector* collector, 1.244 + bool should_yield, 1.245 + bool concurrent_precleaning); 1.246 + virtual void do_oop(oop* p); 1.247 + virtual void do_oop(narrowOop* p); 1.248 + inline void do_oop_nv(oop* p) { MarkRefsIntoAndScanClosure::do_oop_work(p); } 1.249 + inline void do_oop_nv(narrowOop* p) { MarkRefsIntoAndScanClosure::do_oop_work(p); } 1.250 + 1.251 + Prefetch::style prefetch_style() { 1.252 + return Prefetch::do_read; 1.253 + } 1.254 + void set_freelistLock(Mutex* m) { 1.255 + _freelistLock = m; 1.256 + } 1.257 + 1.258 + private: 1.259 + inline void do_yield_check(); 1.260 + void do_yield_work(); 1.261 + bool take_from_overflow_list(); 1.262 +}; 1.263 + 1.264 +// Tn this, the parallel avatar of MarkRefsIntoAndScanClosure, the revisit 1.265 +// stack and the bitMap are shared, so access needs to be suitably 1.266 +// sycnhronized. An OopTaskQueue structure, supporting efficient 1.267 +// workstealing, replaces a CMSMarkStack for storing grey objects. 1.268 +class Par_MarkRefsIntoAndScanClosure: public CMSOopsInGenClosure { 1.269 + private: 1.270 + MemRegion _span; 1.271 + CMSBitMap* _bit_map; 1.272 + OopTaskQueue* _work_queue; 1.273 + const uint _low_water_mark; 1.274 + Par_PushAndMarkClosure _par_pushAndMarkClosure; 1.275 + protected: 1.276 + DO_OOP_WORK_DEFN 1.277 + public: 1.278 + Par_MarkRefsIntoAndScanClosure(CMSCollector* collector, 1.279 + MemRegion span, 1.280 + ReferenceProcessor* rp, 1.281 + CMSBitMap* bit_map, 1.282 + OopTaskQueue* work_queue); 1.283 + virtual void do_oop(oop* p); 1.284 + virtual void do_oop(narrowOop* p); 1.285 + inline void do_oop_nv(oop* p) { Par_MarkRefsIntoAndScanClosure::do_oop_work(p); } 1.286 + inline void do_oop_nv(narrowOop* p) { Par_MarkRefsIntoAndScanClosure::do_oop_work(p); } 1.287 + 1.288 + Prefetch::style prefetch_style() { 1.289 + return Prefetch::do_read; 1.290 + } 1.291 + void trim_queue(uint size); 1.292 +}; 1.293 + 1.294 +// This closure is used during the concurrent marking phase 1.295 +// following the first checkpoint. Its use is buried in 1.296 +// the closure MarkFromRootsClosure. 1.297 +class PushOrMarkClosure: public CMSOopClosure { 1.298 + private: 1.299 + CMSCollector* _collector; 1.300 + MemRegion _span; 1.301 + CMSBitMap* _bitMap; 1.302 + CMSMarkStack* _markStack; 1.303 + HeapWord* const _finger; 1.304 + MarkFromRootsClosure* const 1.305 + _parent; 1.306 + protected: 1.307 + DO_OOP_WORK_DEFN 1.308 + public: 1.309 + PushOrMarkClosure(CMSCollector* cms_collector, 1.310 + MemRegion span, 1.311 + CMSBitMap* bitMap, 1.312 + CMSMarkStack* markStack, 1.313 + HeapWord* finger, 1.314 + MarkFromRootsClosure* parent); 1.315 + virtual void do_oop(oop* p); 1.316 + virtual void do_oop(narrowOop* p); 1.317 + inline void do_oop_nv(oop* p) { PushOrMarkClosure::do_oop_work(p); } 1.318 + inline void do_oop_nv(narrowOop* p) { PushOrMarkClosure::do_oop_work(p); } 1.319 + 1.320 + // Deal with a stack overflow condition 1.321 + void handle_stack_overflow(HeapWord* lost); 1.322 + private: 1.323 + inline void do_yield_check(); 1.324 +}; 1.325 + 1.326 +// A parallel (MT) version of the above. 1.327 +// This closure is used during the concurrent marking phase 1.328 +// following the first checkpoint. Its use is buried in 1.329 +// the closure Par_MarkFromRootsClosure. 1.330 +class Par_PushOrMarkClosure: public CMSOopClosure { 1.331 + private: 1.332 + CMSCollector* _collector; 1.333 + MemRegion _whole_span; 1.334 + MemRegion _span; // local chunk 1.335 + CMSBitMap* _bit_map; 1.336 + OopTaskQueue* _work_queue; 1.337 + CMSMarkStack* _overflow_stack; 1.338 + HeapWord* const _finger; 1.339 + HeapWord** const _global_finger_addr; 1.340 + Par_MarkFromRootsClosure* const 1.341 + _parent; 1.342 + protected: 1.343 + DO_OOP_WORK_DEFN 1.344 + public: 1.345 + Par_PushOrMarkClosure(CMSCollector* cms_collector, 1.346 + MemRegion span, 1.347 + CMSBitMap* bit_map, 1.348 + OopTaskQueue* work_queue, 1.349 + CMSMarkStack* mark_stack, 1.350 + HeapWord* finger, 1.351 + HeapWord** global_finger_addr, 1.352 + Par_MarkFromRootsClosure* parent); 1.353 + virtual void do_oop(oop* p); 1.354 + virtual void do_oop(narrowOop* p); 1.355 + inline void do_oop_nv(oop* p) { Par_PushOrMarkClosure::do_oop_work(p); } 1.356 + inline void do_oop_nv(narrowOop* p) { Par_PushOrMarkClosure::do_oop_work(p); } 1.357 + 1.358 + // Deal with a stack overflow condition 1.359 + void handle_stack_overflow(HeapWord* lost); 1.360 + private: 1.361 + inline void do_yield_check(); 1.362 +}; 1.363 + 1.364 +// For objects in CMS generation, this closure marks 1.365 +// given objects (transitively) as being reachable/live. 1.366 +// This is currently used during the (weak) reference object 1.367 +// processing phase of the CMS final checkpoint step, as 1.368 +// well as during the concurrent precleaning of the discovered 1.369 +// reference lists. 1.370 +class CMSKeepAliveClosure: public CMSOopClosure { 1.371 + private: 1.372 + CMSCollector* _collector; 1.373 + const MemRegion _span; 1.374 + CMSMarkStack* _mark_stack; 1.375 + CMSBitMap* _bit_map; 1.376 + bool _concurrent_precleaning; 1.377 + protected: 1.378 + DO_OOP_WORK_DEFN 1.379 + public: 1.380 + CMSKeepAliveClosure(CMSCollector* collector, MemRegion span, 1.381 + CMSBitMap* bit_map, CMSMarkStack* mark_stack, 1.382 + bool cpc); 1.383 + bool concurrent_precleaning() const { return _concurrent_precleaning; } 1.384 + virtual void do_oop(oop* p); 1.385 + virtual void do_oop(narrowOop* p); 1.386 + inline void do_oop_nv(oop* p) { CMSKeepAliveClosure::do_oop_work(p); } 1.387 + inline void do_oop_nv(narrowOop* p) { CMSKeepAliveClosure::do_oop_work(p); } 1.388 +}; 1.389 + 1.390 +class CMSInnerParMarkAndPushClosure: public CMSOopClosure { 1.391 + private: 1.392 + CMSCollector* _collector; 1.393 + MemRegion _span; 1.394 + OopTaskQueue* _work_queue; 1.395 + CMSBitMap* _bit_map; 1.396 + protected: 1.397 + DO_OOP_WORK_DEFN 1.398 + public: 1.399 + CMSInnerParMarkAndPushClosure(CMSCollector* collector, 1.400 + MemRegion span, CMSBitMap* bit_map, 1.401 + OopTaskQueue* work_queue); 1.402 + virtual void do_oop(oop* p); 1.403 + virtual void do_oop(narrowOop* p); 1.404 + inline void do_oop_nv(oop* p) { CMSInnerParMarkAndPushClosure::do_oop_work(p); } 1.405 + inline void do_oop_nv(narrowOop* p) { CMSInnerParMarkAndPushClosure::do_oop_work(p); } 1.406 +}; 1.407 + 1.408 +// A parallel (MT) version of the above, used when 1.409 +// reference processing is parallel; the only difference 1.410 +// is in the do_oop method. 1.411 +class CMSParKeepAliveClosure: public CMSOopClosure { 1.412 + private: 1.413 + MemRegion _span; 1.414 + OopTaskQueue* _work_queue; 1.415 + CMSBitMap* _bit_map; 1.416 + CMSInnerParMarkAndPushClosure 1.417 + _mark_and_push; 1.418 + const uint _low_water_mark; 1.419 + void trim_queue(uint max); 1.420 + protected: 1.421 + DO_OOP_WORK_DEFN 1.422 + public: 1.423 + CMSParKeepAliveClosure(CMSCollector* collector, MemRegion span, 1.424 + CMSBitMap* bit_map, OopTaskQueue* work_queue); 1.425 + virtual void do_oop(oop* p); 1.426 + virtual void do_oop(narrowOop* p); 1.427 +}; 1.428 + 1.429 +#endif // SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_CMSOOPCLOSURES_HPP