diff -r a5d8d1764e94 -r 3aaaaad1ccb0 hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp Fri Sep 18 09:57:47 2009 -0700 +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp Wed Sep 23 23:56:15 2009 -0700 @@ -88,17 +88,50 @@ } }; +// KlassRememberingOopClosure is used when marking of the permanent generation +// is being done. It adds fields to support revisiting of klasses +// for class unloading. _should_remember_klasses should be set to +// indicate if klasses should be remembered. Currently that is whenever +// CMS class unloading is turned on. The _revisit_stack is used +// to save the klasses for later processing. +class KlassRememberingOopClosure : public OopClosure { + protected: + CMSCollector* _collector; + CMSMarkStack* _revisit_stack; + bool const _should_remember_klasses; + public: + void check_remember_klasses() const PRODUCT_RETURN; + virtual const bool should_remember_klasses() const { + check_remember_klasses(); + return _should_remember_klasses; + } + virtual void remember_klass(Klass* k); + + KlassRememberingOopClosure(CMSCollector* collector, + ReferenceProcessor* rp, + CMSMarkStack* revisit_stack); +}; + +// Similar to KlassRememberingOopClosure for use when multiple +// GC threads will execute the closure. + +class Par_KlassRememberingOopClosure : public KlassRememberingOopClosure { + public: + Par_KlassRememberingOopClosure(CMSCollector* collector, + ReferenceProcessor* rp, + CMSMarkStack* revisit_stack): + KlassRememberingOopClosure(collector, rp, revisit_stack) {} + virtual void remember_klass(Klass* k); +}; + // The non-parallel version (the parallel version appears further below). -class PushAndMarkClosure: public OopClosure { +class PushAndMarkClosure: public KlassRememberingOopClosure { private: - 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; protected: DO_OOP_WORK_DEFN public: @@ -118,10 +151,12 @@ Prefetch::style prefetch_style() { return Prefetch::do_read; } - virtual const bool should_remember_klasses() const { - return _should_remember_klasses; + // In support of class unloading + virtual const bool should_remember_mdo() const { + return false; + // return _should_remember_klasses; } - virtual void remember_klass(Klass* k); + virtual void remember_mdo(DataLayout* v); }; // In the parallel case, the revisit stack, the bit map and the @@ -130,14 +165,11 @@ // 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 { +class Par_PushAndMarkClosure: public Par_KlassRememberingOopClosure { private: - CMSCollector* _collector; MemRegion _span; CMSBitMap* _bit_map; OopTaskQueue* _work_queue; - CMSMarkStack* _revisit_stack; - bool const _should_remember_klasses; protected: DO_OOP_WORK_DEFN public: @@ -155,10 +187,12 @@ Prefetch::style prefetch_style() { return Prefetch::do_read; } - virtual const bool should_remember_klasses() const { - return _should_remember_klasses; + // In support of class unloading + virtual const bool should_remember_mdo() const { + return false; + // return _should_remember_klasses; } - virtual void remember_klass(Klass* k); + virtual void remember_mdo(DataLayout* v); }; // The non-parallel version (the parallel version appears further below). @@ -196,6 +230,12 @@ void set_freelistLock(Mutex* m) { _freelistLock = m; } + virtual const bool should_remember_klasses() const { + return _pushAndMarkClosure.should_remember_klasses(); + } + virtual void remember_klass(Klass* k) { + _pushAndMarkClosure.remember_klass(k); + } private: inline void do_yield_check(); @@ -229,6 +269,16 @@ inline void do_oop_nv(narrowOop* p) { Par_MarkRefsIntoAndScanClosure::do_oop_work(p); } bool do_header() { return true; } virtual const bool do_nmethods() const { return true; } + // When ScanMarkedObjectsAgainClosure is used, + // it passes [Par_]MarkRefsIntoAndScanClosure to oop_oop_iterate(), + // and this delegation is used. + virtual const bool should_remember_klasses() const { + return _par_pushAndMarkClosure.should_remember_klasses(); + } + // See comment on should_remember_klasses() above. + virtual void remember_klass(Klass* k) { + _par_pushAndMarkClosure.remember_klass(k); + } Prefetch::style prefetch_style() { return Prefetch::do_read; } @@ -238,17 +288,14 @@ // 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 { +class PushOrMarkClosure: public KlassRememberingOopClosure { private: - CMSCollector* _collector; MemRegion _span; CMSBitMap* _bitMap; CMSMarkStack* _markStack; - CMSMarkStack* _revisitStack; HeapWord* const _finger; MarkFromRootsClosure* const _parent; - bool const _should_remember_klasses; protected: DO_OOP_WORK_DEFN public: @@ -263,10 +310,13 @@ virtual void do_oop(narrowOop* p); inline void do_oop_nv(oop* p) { PushOrMarkClosure::do_oop_work(p); } inline void do_oop_nv(narrowOop* p) { PushOrMarkClosure::do_oop_work(p); } - virtual const bool should_remember_klasses() const { - return _should_remember_klasses; + // In support of class unloading + virtual const bool should_remember_mdo() const { + return false; + // return _should_remember_klasses; } - virtual void remember_klass(Klass* k); + virtual void remember_mdo(DataLayout* v); + // Deal with a stack overflow condition void handle_stack_overflow(HeapWord* lost); private: @@ -277,20 +327,17 @@ // 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 { +class Par_PushOrMarkClosure: public Par_KlassRememberingOopClosure { private: - 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; protected: DO_OOP_WORK_DEFN public: @@ -307,10 +354,13 @@ virtual void do_oop(narrowOop* p); inline void do_oop_nv(oop* p) { Par_PushOrMarkClosure::do_oop_work(p); } inline void do_oop_nv(narrowOop* p) { Par_PushOrMarkClosure::do_oop_work(p); } - virtual const bool should_remember_klasses() const { - return _should_remember_klasses; + // In support of class unloading + virtual const bool should_remember_mdo() const { + return false; + // return _should_remember_klasses; } - virtual void remember_klass(Klass* k); + virtual void remember_mdo(DataLayout* v); + // Deal with a stack overflow condition void handle_stack_overflow(HeapWord* lost); private: @@ -323,9 +373,8 @@ // processing phase of the CMS final checkpoint step, as // well as during the concurrent precleaning of the discovered // reference lists. -class CMSKeepAliveClosure: public OopClosure { +class CMSKeepAliveClosure: public KlassRememberingOopClosure { private: - CMSCollector* _collector; const MemRegion _span; CMSMarkStack* _mark_stack; CMSBitMap* _bit_map; @@ -335,14 +384,7 @@ public: CMSKeepAliveClosure(CMSCollector* collector, MemRegion span, CMSBitMap* bit_map, CMSMarkStack* mark_stack, - bool cpc): - _collector(collector), - _span(span), - _bit_map(bit_map), - _mark_stack(mark_stack), - _concurrent_precleaning(cpc) { - assert(!_span.is_empty(), "Empty span could spell trouble"); - } + CMSMarkStack* revisit_stack, bool cpc); bool concurrent_precleaning() const { return _concurrent_precleaning; } virtual void do_oop(oop* p); virtual void do_oop(narrowOop* p); @@ -350,9 +392,8 @@ inline void do_oop_nv(narrowOop* p) { CMSKeepAliveClosure::do_oop_work(p); } }; -class CMSInnerParMarkAndPushClosure: public OopClosure { +class CMSInnerParMarkAndPushClosure: public Par_KlassRememberingOopClosure { private: - CMSCollector* _collector; MemRegion _span; OopTaskQueue* _work_queue; CMSBitMap* _bit_map; @@ -361,11 +402,8 @@ public: CMSInnerParMarkAndPushClosure(CMSCollector* collector, MemRegion span, CMSBitMap* bit_map, - OopTaskQueue* work_queue): - _collector(collector), - _span(span), - _bit_map(bit_map), - _work_queue(work_queue) { } + CMSMarkStack* revisit_stack, + OopTaskQueue* work_queue); virtual void do_oop(oop* p); virtual void do_oop(narrowOop* p); inline void do_oop_nv(oop* p) { CMSInnerParMarkAndPushClosure::do_oop_work(p); } @@ -375,9 +413,8 @@ // 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 { +class CMSParKeepAliveClosure: public Par_KlassRememberingOopClosure { private: - CMSCollector* _collector; MemRegion _span; OopTaskQueue* _work_queue; CMSBitMap* _bit_map; @@ -389,7 +426,8 @@ DO_OOP_WORK_DEFN public: CMSParKeepAliveClosure(CMSCollector* collector, MemRegion span, - CMSBitMap* bit_map, OopTaskQueue* work_queue); + CMSBitMap* bit_map, CMSMarkStack* revisit_stack, + OopTaskQueue* work_queue); virtual void do_oop(oop* p); virtual void do_oop(narrowOop* p); inline void do_oop_nv(oop* p) { CMSParKeepAliveClosure::do_oop_work(p); }