Tue, 30 Sep 2014 09:44:36 +0200
8052172: Evacuation failure handling in G1 does not evacuate all objects if -XX:-G1DeferredRSUpdate is set
Summary: Remove -XX:-G1DeferredRSUpdate functionality as it is racy. During evacuation failure handling, threads where evacuation failure handling occurred may try to add remembered sets to regions which remembered sets are currently being scanned. The iterator to handle the remembered set scan does not support addition of entries during scan and so may skip valid references.
Reviewed-by: iveresov, brutisso, mgerdin
1 /*
2 * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
25 #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1REMSET_HPP
26 #define SHARE_VM_GC_IMPLEMENTATION_G1_G1REMSET_HPP
28 #include "gc_implementation/g1/g1RemSetSummary.hpp"
30 // A G1RemSet provides ways of iterating over pointers into a selected
31 // collection set.
33 class G1CollectedHeap;
34 class CardTableModRefBarrierSet;
35 class ConcurrentG1Refine;
37 // A G1RemSet in which each heap region has a rem set that records the
38 // external heap references into it. Uses a mod ref bs to track updates,
39 // so that they can be used to update the individual region remsets.
41 class G1RemSet: public CHeapObj<mtGC> {
42 private:
43 G1RemSetSummary _prev_period_summary;
44 protected:
45 G1CollectedHeap* _g1;
46 size_t _conc_refine_cards;
47 uint n_workers();
49 protected:
50 enum SomePrivateConstants {
51 UpdateRStoMergeSync = 0,
52 MergeRStoDoDirtySync = 1,
53 DoDirtySync = 2,
54 LastSync = 3,
56 SeqTask = 0,
57 NumSeqTasks = 1
58 };
60 CardTableModRefBS* _ct_bs;
61 SubTasksDone* _seq_task;
62 G1CollectorPolicy* _g1p;
64 ConcurrentG1Refine* _cg1r;
66 size_t* _cards_scanned;
67 size_t _total_cards_scanned;
69 // Used for caching the closure that is responsible for scanning
70 // references into the collection set.
71 OopsInHeapRegionClosure** _cset_rs_update_cl;
73 // Print the given summary info
74 virtual void print_summary_info(G1RemSetSummary * summary, const char * header = NULL);
75 public:
76 // This is called to reset dual hash tables after the gc pause
77 // is finished and the initial hash table is no longer being
78 // scanned.
79 void cleanupHRRS();
81 G1RemSet(G1CollectedHeap* g1, CardTableModRefBS* ct_bs);
82 ~G1RemSet();
84 // Invoke "blk->do_oop" on all pointers into the collection set
85 // from objects in regions outside the collection set (having
86 // invoked "blk->set_region" to set the "from" region correctly
87 // beforehand.)
88 //
89 // Invoke code_root_cl->do_code_blob on the unmarked nmethods
90 // on the strong code roots list for each region in the
91 // collection set.
92 //
93 // The "worker_i" param is for the parallel case where the id
94 // of the worker thread calling this function can be helpful in
95 // partitioning the work to be done. It should be the same as
96 // the "i" passed to the calling thread's work(i) function.
97 // In the sequential case this param will be ignored.
98 void oops_into_collection_set_do(OopsInHeapRegionClosure* blk,
99 CodeBlobClosure* code_root_cl,
100 uint worker_i);
102 // Prepare for and cleanup after an oops_into_collection_set_do
103 // call. Must call each of these once before and after (in sequential
104 // code) any threads call oops_into_collection_set_do. (This offers an
105 // opportunity to sequential setup and teardown of structures needed by a
106 // parallel iteration over the CS's RS.)
107 void prepare_for_oops_into_collection_set_do();
108 void cleanup_after_oops_into_collection_set_do();
110 void scanRS(OopsInHeapRegionClosure* oc,
111 CodeBlobClosure* code_root_cl,
112 uint worker_i);
114 void updateRS(DirtyCardQueue* into_cset_dcq, uint worker_i);
116 CardTableModRefBS* ct_bs() { return _ct_bs; }
117 size_t cardsScanned() { return _total_cards_scanned; }
119 // Record, if necessary, the fact that *p (where "p" is in region "from",
120 // which is required to be non-NULL) has changed to a new non-NULL value.
121 template <class T> void write_ref(HeapRegion* from, T* p);
122 template <class T> void par_write_ref(HeapRegion* from, T* p, int tid);
124 // Requires "region_bm" and "card_bm" to be bitmaps with 1 bit per region
125 // or card, respectively, such that a region or card with a corresponding
126 // 0 bit contains no part of any live object. Eliminates any remembered
127 // set entries that correspond to dead heap ranges.
128 void scrub(BitMap* region_bm, BitMap* card_bm);
130 // Like the above, but assumes is called in parallel: "worker_num" is the
131 // parallel thread id of the current thread, and "claim_val" is the
132 // value that should be used to claim heap regions.
133 void scrub_par(BitMap* region_bm, BitMap* card_bm,
134 uint worker_num, int claim_val);
136 // Refine the card corresponding to "card_ptr".
137 // If check_for_refs_into_cset is true, a true result is returned
138 // if the given card contains oops that have references into the
139 // current collection set.
140 virtual bool refine_card(jbyte* card_ptr,
141 uint worker_i,
142 bool check_for_refs_into_cset);
144 // Print accumulated summary info from the start of the VM.
145 virtual void print_summary_info();
147 // Print accumulated summary info from the last time called.
148 virtual void print_periodic_summary_info(const char* header);
150 // Prepare remembered set for verification.
151 virtual void prepare_for_verify();
153 size_t conc_refine_cards() const {
154 return _conc_refine_cards;
155 }
156 };
158 class CountNonCleanMemRegionClosure: public MemRegionClosure {
159 G1CollectedHeap* _g1;
160 int _n;
161 HeapWord* _start_first;
162 public:
163 CountNonCleanMemRegionClosure(G1CollectedHeap* g1) :
164 _g1(g1), _n(0), _start_first(NULL)
165 {}
166 void do_MemRegion(MemRegion mr);
167 int n() { return _n; };
168 HeapWord* start_first() { return _start_first; }
169 };
171 class UpdateRSOopClosure: public ExtendedOopClosure {
172 HeapRegion* _from;
173 G1RemSet* _rs;
174 uint _worker_i;
176 template <class T> void do_oop_work(T* p);
178 public:
179 UpdateRSOopClosure(G1RemSet* rs, uint worker_i = 0) :
180 _from(NULL), _rs(rs), _worker_i(worker_i)
181 {}
183 void set_from(HeapRegion* from) {
184 assert(from != NULL, "from region must be non-NULL");
185 _from = from;
186 }
188 virtual void do_oop(narrowOop* p) { do_oop_work(p); }
189 virtual void do_oop(oop* p) { do_oop_work(p); }
191 // Override: this closure is idempotent.
192 // bool idempotent() { return true; }
193 bool apply_to_weak_ref_discovered_field() { return true; }
194 };
196 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1REMSET_HPP