ysr@777: /* johnc@5078: * Copyright (c) 2001, 2013, 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_G1REMSET_HPP stefank@2314: #define SHARE_VM_GC_IMPLEMENTATION_G1_G1REMSET_HPP stefank@2314: tschatzl@5204: #include "gc_implementation/g1/g1RemSetSummary.hpp" tschatzl@5204: ysr@777: // A G1RemSet provides ways of iterating over pointers into a selected ysr@777: // collection set. ysr@777: ysr@777: class G1CollectedHeap; ysr@777: class CardTableModRefBarrierSet; ysr@777: class ConcurrentG1Refine; ysr@777: johnc@2216: // A G1RemSet in which each heap region has a rem set that records the johnc@2216: // external heap references into it. Uses a mod ref bs to track updates, johnc@2216: // so that they can be used to update the individual region remsets. johnc@2216: zgu@3900: class G1RemSet: public CHeapObj { tschatzl@5204: private: tschatzl@5204: G1RemSetSummary _prev_period_summary; ysr@777: protected: ysr@777: G1CollectedHeap* _g1; tschatzl@5204: size_t _conc_refine_cards; jmasa@3357: uint n_workers(); ysr@777: ysr@777: protected: ysr@777: enum SomePrivateConstants { ysr@777: UpdateRStoMergeSync = 0, ysr@777: MergeRStoDoDirtySync = 1, ysr@777: DoDirtySync = 2, ysr@777: LastSync = 3, ysr@777: ysr@777: SeqTask = 0, ysr@777: NumSeqTasks = 1 ysr@777: }; ysr@777: johnc@5014: CardTableModRefBS* _ct_bs; johnc@5014: SubTasksDone* _seq_task; johnc@5014: G1CollectorPolicy* _g1p; ysr@777: johnc@5014: ConcurrentG1Refine* _cg1r; ysr@777: johnc@5014: size_t* _cards_scanned; johnc@5014: size_t _total_cards_scanned; ysr@777: johnc@2060: // Used for caching the closure that is responsible for scanning johnc@2060: // references into the collection set. johnc@2060: OopsInHeapRegionClosure** _cset_rs_update_cl; ysr@1280: tschatzl@5204: // Print the given summary info tschatzl@5204: virtual void print_summary_info(G1RemSetSummary * summary, const char * header = NULL); ysr@777: public: ysr@777: // This is called to reset dual hash tables after the gc pause ysr@777: // is finished and the initial hash table is no longer being ysr@777: // scanned. ysr@777: void cleanupHRRS(); ysr@777: johnc@2216: G1RemSet(G1CollectedHeap* g1, CardTableModRefBS* ct_bs); johnc@2216: ~G1RemSet(); ysr@777: johnc@5548: // Invoke "blk->do_oop" on all pointers into the collection set johnc@5548: // from objects in regions outside the collection set (having johnc@5548: // invoked "blk->set_region" to set the "from" region correctly johnc@5548: // beforehand.) johnc@5548: // johnc@5548: // Invoke code_root_cl->do_code_blob on the unmarked nmethods johnc@5548: // on the strong code roots list for each region in the johnc@5548: // collection set. johnc@5548: // johnc@5548: // The "worker_i" param is for the parallel case where the id johnc@5548: // of the worker thread calling this function can be helpful in johnc@5548: // partitioning the work to be done. It should be the same as johnc@5548: // the "i" passed to the calling thread's work(i) function. johnc@5548: // In the sequential case this param will be ignored. johnc@5548: void oops_into_collection_set_do(OopsInHeapRegionClosure* blk, johnc@5548: CodeBlobToOopClosure* code_root_cl, vkempik@6552: uint worker_i); ysr@777: johnc@2216: // Prepare for and cleanup after an oops_into_collection_set_do johnc@2216: // call. Must call each of these once before and after (in sequential johnc@2216: // code) any threads call oops_into_collection_set_do. (This offers an johnc@2216: // opportunity to sequential setup and teardown of structures needed by a johnc@2216: // parallel iteration over the CS's RS.) ysr@777: void prepare_for_oops_into_collection_set_do(); ysr@777: void cleanup_after_oops_into_collection_set_do(); johnc@2216: johnc@5548: void scanRS(OopsInHeapRegionClosure* oc, johnc@5548: CodeBlobToOopClosure* code_root_cl, vkempik@6552: uint worker_i); johnc@5548: vkempik@6552: void updateRS(DirtyCardQueue* into_cset_dcq, uint worker_i); johnc@2216: ysr@777: CardTableModRefBS* ct_bs() { return _ct_bs; } ysr@777: size_t cardsScanned() { return _total_cards_scanned; } ysr@777: ysr@777: // Record, if necessary, the fact that *p (where "p" is in region "from", ysr@777: // which is required to be non-NULL) has changed to a new non-NULL value. johnc@2302: template void write_ref(HeapRegion* from, T* p); johnc@2302: template void par_write_ref(HeapRegion* from, T* p, int tid); ysr@777: johnc@2216: // Requires "region_bm" and "card_bm" to be bitmaps with 1 bit per region johnc@2216: // or card, respectively, such that a region or card with a corresponding johnc@2216: // 0 bit contains no part of any live object. Eliminates any remembered johnc@2216: // set entries that correspond to dead heap ranges. ysr@777: void scrub(BitMap* region_bm, BitMap* card_bm); johnc@2216: johnc@2216: // Like the above, but assumes is called in parallel: "worker_num" is the johnc@2216: // parallel thread id of the current thread, and "claim_val" is the johnc@2216: // value that should be used to claim heap regions. ysr@777: void scrub_par(BitMap* region_bm, BitMap* card_bm, jmasa@3357: uint worker_num, int claim_val); ysr@777: johnc@5078: // Refine the card corresponding to "card_ptr". johnc@2216: // If check_for_refs_into_cset is true, a true result is returned johnc@2216: // if the given card contains oops that have references into the johnc@2216: // current collection set. johnc@5078: virtual bool refine_card(jbyte* card_ptr, vkempik@6552: uint worker_i, johnc@5078: bool check_for_refs_into_cset); ysr@777: tschatzl@5204: // Print accumulated summary info from the start of the VM. ysr@777: virtual void print_summary_info(); johnc@2216: tschatzl@5204: // Print accumulated summary info from the last time called. tschatzl@5807: virtual void print_periodic_summary_info(const char* header); tschatzl@5204: johnc@2216: // Prepare remembered set for verification. ysr@777: virtual void prepare_for_verify(); tschatzl@5204: tschatzl@5204: size_t conc_refine_cards() const { tschatzl@5204: return _conc_refine_cards; tschatzl@5204: } ysr@777: }; ysr@777: ysr@777: class CountNonCleanMemRegionClosure: public MemRegionClosure { ysr@777: G1CollectedHeap* _g1; ysr@777: int _n; ysr@777: HeapWord* _start_first; ysr@777: public: ysr@777: CountNonCleanMemRegionClosure(G1CollectedHeap* g1) : ysr@777: _g1(g1), _n(0), _start_first(NULL) ysr@777: {} ysr@777: void do_MemRegion(MemRegion mr); ysr@777: int n() { return _n; }; ysr@777: HeapWord* start_first() { return _start_first; } ysr@777: }; apetrusenko@1061: coleenp@4037: class UpdateRSOopClosure: public ExtendedOopClosure { apetrusenko@1061: HeapRegion* _from; johnc@2216: G1RemSet* _rs; vkempik@6552: uint _worker_i; ysr@1280: ysr@1280: template void do_oop_work(T* p); ysr@1280: apetrusenko@1061: public: vkempik@6552: UpdateRSOopClosure(G1RemSet* rs, uint worker_i = 0) : johnc@2302: _from(NULL), _rs(rs), _worker_i(worker_i) johnc@2302: {} apetrusenko@1061: apetrusenko@1061: void set_from(HeapRegion* from) { apetrusenko@1061: assert(from != NULL, "from region must be non-NULL"); apetrusenko@1061: _from = from; apetrusenko@1061: } apetrusenko@1061: ysr@1280: virtual void do_oop(narrowOop* p) { do_oop_work(p); } ysr@1280: virtual void do_oop(oop* p) { do_oop_work(p); } apetrusenko@1061: apetrusenko@1061: // Override: this closure is idempotent. apetrusenko@1061: // bool idempotent() { return true; } apetrusenko@1061: bool apply_to_weak_ref_discovered_field() { return true; } apetrusenko@1061: }; johnc@2060: johnc@2060: class UpdateRSetImmediate: public OopsInHeapRegionClosure { johnc@2060: private: johnc@2060: G1RemSet* _g1_rem_set; johnc@2060: johnc@2060: template void do_oop_work(T* p); johnc@2060: public: johnc@2060: UpdateRSetImmediate(G1RemSet* rs) : johnc@2060: _g1_rem_set(rs) {} johnc@2060: johnc@2060: virtual void do_oop(narrowOop* p) { do_oop_work(p); } johnc@2060: virtual void do_oop( oop* p) { do_oop_work(p); } johnc@2060: }; johnc@2302: stefank@2314: stefank@2314: #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1REMSET_HPP