ysr@777: /* tschatzl@6269: * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. ysr@777: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ysr@777: * ysr@777: * This code is free software; you can redistribute it and/or modify it ysr@777: * under the terms of the GNU General Public License version 2 only, as ysr@777: * published by the Free Software Foundation. ysr@777: * ysr@777: * This code is distributed in the hope that it will be useful, but WITHOUT ysr@777: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ysr@777: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ysr@777: * version 2 for more details (a copy is included in the LICENSE file that ysr@777: * accompanied this code). ysr@777: * ysr@777: * You should have received a copy of the GNU General Public License version ysr@777: * 2 along with this work; if not, write to the Free Software Foundation, ysr@777: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ysr@777: * trims@1907: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA trims@1907: * or visit www.oracle.com if you need additional information or have any trims@1907: * questions. ysr@777: * ysr@777: */ ysr@777: stefank@2314: #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1OOPCLOSURES_HPP stefank@2314: #define SHARE_VM_GC_IMPLEMENTATION_G1_G1OOPCLOSURES_HPP stefank@2314: stefank@6992: #include "memory/iterator.hpp" stefank@6992: ysr@777: class HeapRegion; ysr@777: class G1CollectedHeap; ysr@777: class G1RemSet; ysr@777: class ConcurrentMark; ysr@777: class DirtyCardToOopClosure; ysr@777: class CMBitMap; ysr@777: class CMMarkStack; ysr@777: class G1ParScanThreadState; tonyp@2968: class CMTask; johnc@3175: class ReferenceProcessor; ysr@777: ysr@777: // A class that scans oops in a given heap region (much as OopsInGenClosure ysr@777: // scans oops in a generation.) tschatzl@6231: class OopsInHeapRegionClosure: public ExtendedOopClosure { ysr@777: protected: ysr@777: HeapRegion* _from; ysr@777: public: tonyp@2962: void set_region(HeapRegion* from) { _from = from; } ysr@777: }; ysr@777: ysr@777: class G1ParClosureSuper : public OopsInHeapRegionClosure { ysr@777: protected: ysr@777: G1CollectedHeap* _g1; ysr@777: G1ParScanThreadState* _par_scan_state; johnc@3463: uint _worker_id; ysr@777: public: tschatzl@6939: // Initializes the instance, leaving _par_scan_state uninitialized. Must be done tschatzl@6939: // later using the set_par_scan_thread_state() method. tschatzl@6939: G1ParClosureSuper(G1CollectedHeap* g1); ysr@777: G1ParClosureSuper(G1CollectedHeap* g1, G1ParScanThreadState* par_scan_state); ysr@777: bool apply_to_weak_ref_discovered_field() { return true; } tschatzl@6939: tschatzl@6939: void set_par_scan_thread_state(G1ParScanThreadState* par_scan_state); ysr@777: }; ysr@777: iveresov@1696: class G1ParPushHeapRSClosure : public G1ParClosureSuper { iveresov@1696: public: johnc@3175: G1ParPushHeapRSClosure(G1CollectedHeap* g1, johnc@3179: G1ParScanThreadState* par_scan_state): johnc@3179: G1ParClosureSuper(g1, par_scan_state) { } johnc@3175: iveresov@1696: template void do_oop_nv(T* p); iveresov@1696: virtual void do_oop(oop* p) { do_oop_nv(p); } iveresov@1696: virtual void do_oop(narrowOop* p) { do_oop_nv(p); } iveresov@1696: }; iveresov@1696: ysr@777: class G1ParScanClosure : public G1ParClosureSuper { ysr@777: public: tschatzl@6939: G1ParScanClosure(G1CollectedHeap* g1, ReferenceProcessor* rp) : tschatzl@6939: G1ParClosureSuper(g1) { johnc@3175: assert(_ref_processor == NULL, "sanity"); johnc@3175: _ref_processor = rp; johnc@3175: } johnc@3175: ysr@1280: template void do_oop_nv(T* p); ysr@777: virtual void do_oop(oop* p) { do_oop_nv(p); } ysr@777: virtual void do_oop(narrowOop* p) { do_oop_nv(p); } ysr@777: }; ysr@777: coleenp@4037: // Add back base class for metadata coleenp@4037: class G1ParCopyHelper : public G1ParClosureSuper { tschatzl@6329: protected: coleenp@4037: Klass* _scanned_klass; tschatzl@6329: ConcurrentMark* _cm; coleenp@4037: tschatzl@6329: // Mark the object if it's not already marked. This is used to mark tschatzl@6329: // objects pointed to by roots that are guaranteed not to move tschatzl@6329: // during the GC (i.e., non-CSet objects). It is MT-safe. tschatzl@6329: void mark_object(oop obj); tschatzl@6329: tschatzl@6329: // Mark the object if it's not already marked. This is used to mark tschatzl@6329: // objects pointed to by roots that have been forwarded during a tschatzl@6329: // GC. It is MT-safe. tschatzl@6329: void mark_forwarded_object(oop from_obj, oop to_obj); coleenp@4037: public: tschatzl@6329: G1ParCopyHelper(G1CollectedHeap* g1, G1ParScanThreadState* par_scan_state); coleenp@4037: coleenp@4037: void set_scanned_klass(Klass* k) { _scanned_klass = k; } coleenp@4037: template void do_klass_barrier(T* p, oop new_obj); coleenp@4037: }; coleenp@4037: stefank@6992: template coleenp@4037: class G1ParCopyClosure : public G1ParCopyHelper { tschatzl@6331: private: brutisso@3690: template void do_oop_work(T* p); ysr@777: ysr@777: public: johnc@3175: G1ParCopyClosure(G1CollectedHeap* g1, G1ParScanThreadState* par_scan_state, johnc@3175: ReferenceProcessor* rp) : coleenp@4037: G1ParCopyHelper(g1, par_scan_state) { johnc@3175: assert(_ref_processor == NULL, "sanity"); johnc@3175: } johnc@3175: tschatzl@6329: template void do_oop_nv(T* p) { do_oop_work(p); } ysr@777: virtual void do_oop(oop* p) { do_oop_nv(p); } ysr@777: virtual void do_oop(narrowOop* p) { do_oop_nv(p); } stefank@6992: stefank@6992: G1CollectedHeap* g1() { return _g1; }; stefank@6992: G1ParScanThreadState* pss() { return _par_scan_state; } stefank@6992: ReferenceProcessor* rp() { return _ref_processor; }; ysr@777: }; ysr@777: stefank@6992: typedef G1ParCopyClosure G1ParScanExtRootClosure; stefank@6992: typedef G1ParCopyClosure G1ParScanAndMarkExtRootClosure; stefank@6992: typedef G1ParCopyClosure G1ParScanAndMarkWeakExtRootClosure; johnc@3175: // We use a separate closure to handle references during evacuation johnc@3175: // failure processing. johnc@3175: stefank@6992: typedef G1ParCopyClosure G1ParScanHeapEvacFailureClosure; ysr@777: coleenp@4037: class FilterIntoCSClosure: public ExtendedOopClosure { ysr@777: G1CollectedHeap* _g1; ysr@777: OopClosure* _oc; ysr@777: DirtyCardToOopClosure* _dcto_cl; ysr@777: public: ysr@777: FilterIntoCSClosure( DirtyCardToOopClosure* dcto_cl, johnc@3175: G1CollectedHeap* g1, johnc@3179: OopClosure* oc) : johnc@3179: _dcto_cl(dcto_cl), _g1(g1), _oc(oc) { } johnc@3175: ysr@1280: template void do_oop_nv(T* p); ysr@1280: virtual void do_oop(oop* p) { do_oop_nv(p); } ysr@1280: virtual void do_oop(narrowOop* p) { do_oop_nv(p); } ysr@777: bool apply_to_weak_ref_discovered_field() { return true; } ysr@777: }; ysr@777: coleenp@4037: class FilterOutOfRegionClosure: public ExtendedOopClosure { ysr@777: HeapWord* _r_bottom; ysr@777: HeapWord* _r_end; ysr@777: OopClosure* _oc; ysr@777: public: ysr@777: FilterOutOfRegionClosure(HeapRegion* r, OopClosure* oc); ysr@1280: template void do_oop_nv(T* p); ysr@1280: virtual void do_oop(oop* p) { do_oop_nv(p); } ysr@1280: virtual void do_oop(narrowOop* p) { do_oop_nv(p); } ysr@777: bool apply_to_weak_ref_discovered_field() { return true; } ysr@777: }; stefank@2314: tonyp@2968: // Closure for iterating over object fields during concurrent marking stefank@6992: class G1CMOopClosure : public MetadataAwareOopClosure { stefank@6992: protected: stefank@6992: ConcurrentMark* _cm; tonyp@3464: private: tonyp@2968: G1CollectedHeap* _g1h; tonyp@2968: CMTask* _task; tonyp@2968: public: tonyp@2968: G1CMOopClosure(G1CollectedHeap* g1h, ConcurrentMark* cm, CMTask* task); tonyp@2968: template void do_oop_nv(T* p); tonyp@2968: virtual void do_oop( oop* p) { do_oop_nv(p); } tonyp@2968: virtual void do_oop(narrowOop* p) { do_oop_nv(p); } tonyp@2968: }; tonyp@2968: tonyp@3464: // Closure to scan the root regions during concurrent marking stefank@6992: class G1RootRegionScanClosure : public MetadataAwareOopClosure { tonyp@3464: private: tonyp@3464: G1CollectedHeap* _g1h; tonyp@3464: ConcurrentMark* _cm; tonyp@3464: uint _worker_id; tonyp@3464: public: tonyp@3464: G1RootRegionScanClosure(G1CollectedHeap* g1h, ConcurrentMark* cm, tonyp@3464: uint worker_id) : tonyp@3464: _g1h(g1h), _cm(cm), _worker_id(worker_id) { } tonyp@3464: template void do_oop_nv(T* p); tonyp@3464: virtual void do_oop( oop* p) { do_oop_nv(p); } tonyp@3464: virtual void do_oop(narrowOop* p) { do_oop_nv(p); } tonyp@3464: }; tonyp@3464: johnc@3466: // Closure that applies the given two closures in sequence. johnc@3466: // Used by the RSet refinement code (when updating RSets johnc@3466: // during an evacuation pause) to record cards containing johnc@3466: // pointers into the collection set. johnc@3466: coleenp@4037: class G1Mux2Closure : public ExtendedOopClosure { johnc@3466: OopClosure* _c1; johnc@3466: OopClosure* _c2; johnc@3466: public: johnc@3466: G1Mux2Closure(OopClosure *c1, OopClosure *c2); johnc@3466: template void do_oop_nv(T* p); johnc@3466: virtual void do_oop(oop* p) { do_oop_nv(p); } johnc@3466: virtual void do_oop(narrowOop* p) { do_oop_nv(p); } johnc@3466: }; johnc@3466: johnc@3466: // A closure that returns true if it is actually applied johnc@3466: // to a reference johnc@3466: coleenp@4037: class G1TriggerClosure : public ExtendedOopClosure { johnc@3466: bool _triggered; johnc@3466: public: johnc@3466: G1TriggerClosure(); johnc@3466: bool triggered() const { return _triggered; } johnc@3466: template void do_oop_nv(T* p); johnc@3466: virtual void do_oop(oop* p) { do_oop_nv(p); } johnc@3466: virtual void do_oop(narrowOop* p) { do_oop_nv(p); } johnc@3466: }; johnc@3466: johnc@3466: // A closure which uses a triggering closure to determine johnc@3466: // whether to apply an oop closure. johnc@3466: coleenp@4037: class G1InvokeIfNotTriggeredClosure: public ExtendedOopClosure { johnc@3466: G1TriggerClosure* _trigger_cl; johnc@3466: OopClosure* _oop_cl; johnc@3466: public: johnc@3466: G1InvokeIfNotTriggeredClosure(G1TriggerClosure* t, OopClosure* oc); johnc@3466: template void do_oop_nv(T* p); johnc@3466: virtual void do_oop(oop* p) { do_oop_nv(p); } johnc@3466: virtual void do_oop(narrowOop* p) { do_oop_nv(p); } johnc@3466: }; johnc@3466: coleenp@4037: class G1UpdateRSOrPushRefOopClosure: public ExtendedOopClosure { johnc@3466: G1CollectedHeap* _g1; johnc@3466: G1RemSet* _g1_rem_set; johnc@3466: HeapRegion* _from; johnc@3466: OopsInHeapRegionClosure* _push_ref_cl; johnc@3466: bool _record_refs_into_cset; vkempik@6552: uint _worker_i; johnc@3466: johnc@3466: public: johnc@3466: G1UpdateRSOrPushRefOopClosure(G1CollectedHeap* g1h, johnc@3466: G1RemSet* rs, johnc@3466: OopsInHeapRegionClosure* push_ref_cl, johnc@3466: bool record_refs_into_cset, vkempik@6552: uint worker_i = 0); johnc@3466: johnc@3466: void set_from(HeapRegion* from) { johnc@3466: assert(from != NULL, "from region must be non-NULL"); johnc@3466: _from = from; johnc@3466: } johnc@3466: johnc@3466: bool self_forwarded(oop obj) { johnc@3466: bool result = (obj->is_forwarded() && (obj->forwardee()== obj)); johnc@3466: return result; johnc@3466: } johnc@3466: johnc@3466: bool apply_to_weak_ref_discovered_field() { return true; } johnc@3466: johnc@3466: template void do_oop_nv(T* p); johnc@3466: virtual void do_oop(narrowOop* p) { do_oop_nv(p); } johnc@3466: virtual void do_oop(oop* p) { do_oop_nv(p); } johnc@3466: }; johnc@3466: stefank@2314: #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1OOPCLOSURES_HPP