Mercurial > hg > truffle
diff src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp @ 0:a61af66fc99e jdk7-b24
Initial load
author | duke |
---|---|
date | Sat, 01 Dec 2007 00:00:00 +0000 |
parents | |
children | ba764ed4b6f2 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp Sat Dec 01 00:00:00 2007 +0000 @@ -0,0 +1,334 @@ +/* + * Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +///////////////////////////////////////////////////////////////// +// Closures used by ConcurrentMarkSweepGeneration's collector +///////////////////////////////////////////////////////////////// +class ConcurrentMarkSweepGeneration; +class CMSBitMap; +class CMSMarkStack; +class CMSCollector; +template<class E> class GenericTaskQueue; +typedef GenericTaskQueue<oop> OopTaskQueue; +template<class E> class GenericTaskQueueSet; +typedef GenericTaskQueueSet<oop> OopTaskQueueSet; +class MarkFromRootsClosure; +class Par_MarkFromRootsClosure; + +class MarkRefsIntoClosure: public OopsInGenClosure { + const MemRegion _span; + CMSBitMap* _bitMap; + const bool _should_do_nmethods; + public: + MarkRefsIntoClosure(MemRegion span, CMSBitMap* bitMap, + bool should_do_nmethods); + void do_oop(oop* p); + void do_oop_nv(oop* p) { MarkRefsIntoClosure::do_oop(p); } + bool do_header() { return true; } + virtual const bool do_nmethods() const { + return _should_do_nmethods; + } + Prefetch::style prefetch_style() { + return Prefetch::do_read; + } +}; + +// A variant of the above used in certain kinds of CMS +// marking verification. +class MarkRefsIntoVerifyClosure: public OopsInGenClosure { + const MemRegion _span; + CMSBitMap* _verification_bm; + CMSBitMap* _cms_bm; + const bool _should_do_nmethods; + public: + MarkRefsIntoVerifyClosure(MemRegion span, CMSBitMap* verification_bm, + CMSBitMap* cms_bm, bool should_do_nmethods); + void do_oop(oop* p); + void do_oop_nv(oop* p) { MarkRefsIntoVerifyClosure::do_oop(p); } + bool do_header() { return true; } + virtual const bool do_nmethods() const { + return _should_do_nmethods; + } + Prefetch::style prefetch_style() { + return Prefetch::do_read; + } +}; + + +// The non-parallel version (the parallel version appears further below). +class PushAndMarkClosure: public OopClosure { + CMSCollector* _collector; + MemRegion _span; + CMSBitMap* _bit_map; + CMSBitMap* _mod_union_table; + CMSMarkStack* _mark_stack; + CMSMarkStack* _revisit_stack; + bool _concurrent_precleaning; + bool const _should_remember_klasses; + public: + PushAndMarkClosure(CMSCollector* collector, + MemRegion span, + ReferenceProcessor* rp, + CMSBitMap* bit_map, + CMSBitMap* mod_union_table, + CMSMarkStack* mark_stack, + CMSMarkStack* revisit_stack, + bool concurrent_precleaning); + + void do_oop(oop* p); + void do_oop_nv(oop* p) { PushAndMarkClosure::do_oop(p); } + bool do_header() { return true; } + Prefetch::style prefetch_style() { + return Prefetch::do_read; + } + const bool should_remember_klasses() const { + return _should_remember_klasses; + } + void remember_klass(Klass* k); +}; + +// In the parallel case, the revisit stack, the bit map and the +// reference processor are currently all shared. Access to +// these shared mutable structures must use appropriate +// synchronization (for instance, via CAS). The marking stack +// used in the non-parallel case above is here replaced with +// an OopTaskQueue structure to allow efficient work stealing. +class Par_PushAndMarkClosure: public OopClosure { + CMSCollector* _collector; + MemRegion _span; + CMSBitMap* _bit_map; + OopTaskQueue* _work_queue; + CMSMarkStack* _revisit_stack; + bool const _should_remember_klasses; + public: + Par_PushAndMarkClosure(CMSCollector* collector, + MemRegion span, + ReferenceProcessor* rp, + CMSBitMap* bit_map, + OopTaskQueue* work_queue, + CMSMarkStack* revisit_stack); + + void do_oop(oop* p); + void do_oop_nv(oop* p) { Par_PushAndMarkClosure::do_oop(p); } + bool do_header() { return true; } + Prefetch::style prefetch_style() { + return Prefetch::do_read; + } + const bool should_remember_klasses() const { + return _should_remember_klasses; + } + void remember_klass(Klass* k); +}; + + +// The non-parallel version (the parallel version appears further below). +class MarkRefsIntoAndScanClosure: public OopsInGenClosure { + MemRegion _span; + CMSBitMap* _bit_map; + CMSMarkStack* _mark_stack; + PushAndMarkClosure _pushAndMarkClosure; + CMSCollector* _collector; + bool _yield; + // Whether closure is being used for concurrent precleaning + bool _concurrent_precleaning; + Mutex* _freelistLock; + public: + MarkRefsIntoAndScanClosure(MemRegion span, + ReferenceProcessor* rp, + CMSBitMap* bit_map, + CMSBitMap* mod_union_table, + CMSMarkStack* mark_stack, + CMSMarkStack* revisit_stack, + CMSCollector* collector, + bool should_yield, + bool concurrent_precleaning); + void do_oop(oop* p); + void do_oop_nv(oop* p) { MarkRefsIntoAndScanClosure::do_oop(p); } + bool do_header() { return true; } + virtual const bool do_nmethods() const { return true; } + Prefetch::style prefetch_style() { + return Prefetch::do_read; + } + void set_freelistLock(Mutex* m) { + _freelistLock = m; + } + + private: + inline void do_yield_check(); + void do_yield_work(); + bool take_from_overflow_list(); +}; + +// Tn this, the parallel avatar of MarkRefsIntoAndScanClosure, the revisit +// stack and the bitMap are shared, so access needs to be suitably +// sycnhronized. An OopTaskQueue structure, supporting efficient +// workstealing, replaces a CMSMarkStack for storing grey objects. +class Par_MarkRefsIntoAndScanClosure: public OopsInGenClosure { + MemRegion _span; + CMSBitMap* _bit_map; + OopTaskQueue* _work_queue; + const uint _low_water_mark; + Par_PushAndMarkClosure _par_pushAndMarkClosure; + public: + Par_MarkRefsIntoAndScanClosure(CMSCollector* collector, + MemRegion span, + ReferenceProcessor* rp, + CMSBitMap* bit_map, + OopTaskQueue* work_queue, + CMSMarkStack* revisit_stack); + void do_oop(oop* p); + void do_oop_nv(oop* p) { Par_MarkRefsIntoAndScanClosure::do_oop(p); } + bool do_header() { return true; } + virtual const bool do_nmethods() const { return true; } + Prefetch::style prefetch_style() { + return Prefetch::do_read; + } + void trim_queue(uint size); +}; + +// This closure is used during the concurrent marking phase +// following the first checkpoint. Its use is buried in +// the closure MarkFromRootsClosure. +class PushOrMarkClosure: public OopClosure { + CMSCollector* _collector; + MemRegion _span; + CMSBitMap* _bitMap; + CMSMarkStack* _markStack; + CMSMarkStack* _revisitStack; + HeapWord* const _finger; + MarkFromRootsClosure* const _parent; + bool const _should_remember_klasses; + public: + PushOrMarkClosure(CMSCollector* cms_collector, + MemRegion span, + CMSBitMap* bitMap, + CMSMarkStack* markStack, + CMSMarkStack* revisitStack, + HeapWord* finger, + MarkFromRootsClosure* parent); + void do_oop(oop* p); + void do_oop_nv(oop* p) { PushOrMarkClosure::do_oop(p); } + const bool should_remember_klasses() const { + return _should_remember_klasses; + } + void remember_klass(Klass* k); + // Deal with a stack overflow condition + void handle_stack_overflow(HeapWord* lost); + private: + inline void do_yield_check(); +}; + +// A parallel (MT) version of the above. +// This closure is used during the concurrent marking phase +// following the first checkpoint. Its use is buried in +// the closure Par_MarkFromRootsClosure. +class Par_PushOrMarkClosure: public OopClosure { + CMSCollector* _collector; + MemRegion _whole_span; + MemRegion _span; // local chunk + CMSBitMap* _bit_map; + OopTaskQueue* _work_queue; + CMSMarkStack* _overflow_stack; + CMSMarkStack* _revisit_stack; + HeapWord* const _finger; + HeapWord** const _global_finger_addr; + Par_MarkFromRootsClosure* const _parent; + bool const _should_remember_klasses; + public: + Par_PushOrMarkClosure(CMSCollector* cms_collector, + MemRegion span, + CMSBitMap* bit_map, + OopTaskQueue* work_queue, + CMSMarkStack* mark_stack, + CMSMarkStack* revisit_stack, + HeapWord* finger, + HeapWord** global_finger_addr, + Par_MarkFromRootsClosure* parent); + void do_oop(oop* p); + void do_oop_nv(oop* p) { Par_PushOrMarkClosure::do_oop(p); } + const bool should_remember_klasses() const { + return _should_remember_klasses; + } + void remember_klass(Klass* k); + // Deal with a stack overflow condition + void handle_stack_overflow(HeapWord* lost); + private: + inline void do_yield_check(); +}; + +// For objects in CMS generation, this closure marks +// given objects (transitively) as being reachable/live. +// This is currently used during the (weak) reference object +// processing phase of the CMS final checkpoint step. +class CMSKeepAliveClosure: public OopClosure { + CMSCollector* _collector; + MemRegion _span; + CMSMarkStack* _mark_stack; + CMSBitMap* _bit_map; + public: + CMSKeepAliveClosure(CMSCollector* collector, MemRegion span, + CMSBitMap* bit_map, CMSMarkStack* mark_stack): + _collector(collector), + _span(span), + _bit_map(bit_map), + _mark_stack(mark_stack) { } + + void do_oop(oop* p); + void do_oop_nv(oop* p) { CMSKeepAliveClosure::do_oop(p); } +}; + +class CMSInnerParMarkAndPushClosure: public OopClosure { + CMSCollector* _collector; + MemRegion _span; + OopTaskQueue* _work_queue; + CMSBitMap* _bit_map; + public: + CMSInnerParMarkAndPushClosure(CMSCollector* collector, + MemRegion span, CMSBitMap* bit_map, + OopTaskQueue* work_queue): + _collector(collector), + _span(span), + _bit_map(bit_map), + _work_queue(work_queue) { } + void do_oop(oop* p); + void do_oop_nv(oop* p) { CMSInnerParMarkAndPushClosure::do_oop(p); } +}; + +// A parallel (MT) version of the above, used when +// reference processing is parallel; the only difference +// is in the do_oop method. +class CMSParKeepAliveClosure: public OopClosure { + CMSCollector* _collector; + MemRegion _span; + OopTaskQueue* _work_queue; + CMSBitMap* _bit_map; + CMSInnerParMarkAndPushClosure _mark_and_push; + const uint _low_water_mark; + void trim_queue(uint max); + public: + CMSParKeepAliveClosure(CMSCollector* collector, MemRegion span, + CMSBitMap* bit_map, OopTaskQueue* work_queue); + void do_oop(oop* p); + void do_oop_nv(oop* p) { CMSParKeepAliveClosure::do_oop(p); } +};