Mercurial > hg > truffle
annotate src/share/vm/gc_implementation/g1/g1RemSet.cpp @ 1666:5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
Summary: During concurrent refinment, filter cards in young regions after it has been determined that the region has been allocated from and the young type of the region has been set.
Reviewed-by: iveresov, tonyp, jcoomes
author | johnc |
---|---|
date | Mon, 19 Jul 2010 11:06:34 -0700 |
parents | 215576b54709 |
children | 2d160770d2e5 |
rev | line source |
---|---|
342 | 1 /* |
1666
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1611
diff
changeset
|
2 * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. |
342 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1282
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1282
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1282
diff
changeset
|
21 * questions. |
342 | 22 * |
23 */ | |
24 | |
25 #include "incls/_precompiled.incl" | |
26 #include "incls/_g1RemSet.cpp.incl" | |
27 | |
28 #define CARD_REPEAT_HISTO 0 | |
29 | |
30 #if CARD_REPEAT_HISTO | |
31 static size_t ct_freq_sz; | |
32 static jbyte* ct_freq = NULL; | |
33 | |
34 void init_ct_freq_table(size_t heap_sz_bytes) { | |
35 if (ct_freq == NULL) { | |
36 ct_freq_sz = heap_sz_bytes/CardTableModRefBS::card_size; | |
37 ct_freq = new jbyte[ct_freq_sz]; | |
38 for (size_t j = 0; j < ct_freq_sz; j++) ct_freq[j] = 0; | |
39 } | |
40 } | |
41 | |
42 void ct_freq_note_card(size_t index) { | |
43 assert(0 <= index && index < ct_freq_sz, "Bounds error."); | |
44 if (ct_freq[index] < 100) { ct_freq[index]++; } | |
45 } | |
46 | |
47 static IntHistogram card_repeat_count(10, 10); | |
48 | |
49 void ct_freq_update_histo_and_reset() { | |
50 for (size_t j = 0; j < ct_freq_sz; j++) { | |
51 card_repeat_count.add_entry(ct_freq[j]); | |
52 ct_freq[j] = 0; | |
53 } | |
54 | |
55 } | |
56 #endif | |
57 | |
58 | |
59 class IntoCSOopClosure: public OopsInHeapRegionClosure { | |
60 OopsInHeapRegionClosure* _blk; | |
61 G1CollectedHeap* _g1; | |
62 public: | |
63 IntoCSOopClosure(G1CollectedHeap* g1, OopsInHeapRegionClosure* blk) : | |
64 _g1(g1), _blk(blk) {} | |
65 void set_region(HeapRegion* from) { | |
66 _blk->set_region(from); | |
67 } | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
796
diff
changeset
|
68 virtual void do_oop(narrowOop* p) { do_oop_work(p); } |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
796
diff
changeset
|
69 virtual void do_oop( oop* p) { do_oop_work(p); } |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
796
diff
changeset
|
70 template <class T> void do_oop_work(T* p) { |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
796
diff
changeset
|
71 oop obj = oopDesc::load_decode_heap_oop(p); |
342 | 72 if (_g1->obj_in_cs(obj)) _blk->do_oop(p); |
73 } | |
74 bool apply_to_weak_ref_discovered_field() { return true; } | |
75 bool idempotent() { return true; } | |
76 }; | |
77 | |
78 class IntoCSRegionClosure: public HeapRegionClosure { | |
79 IntoCSOopClosure _blk; | |
80 G1CollectedHeap* _g1; | |
81 public: | |
82 IntoCSRegionClosure(G1CollectedHeap* g1, OopsInHeapRegionClosure* blk) : | |
83 _g1(g1), _blk(g1, blk) {} | |
84 bool doHeapRegion(HeapRegion* r) { | |
85 if (!r->in_collection_set()) { | |
86 _blk.set_region(r); | |
87 if (r->isHumongous()) { | |
88 if (r->startsHumongous()) { | |
89 oop obj = oop(r->bottom()); | |
90 obj->oop_iterate(&_blk); | |
91 } | |
92 } else { | |
93 r->oop_before_save_marks_iterate(&_blk); | |
94 } | |
95 } | |
96 return false; | |
97 } | |
98 }; | |
99 | |
100 void | |
101 StupidG1RemSet::oops_into_collection_set_do(OopsInHeapRegionClosure* oc, | |
102 int worker_i) { | |
103 IntoCSRegionClosure rc(_g1, oc); | |
104 _g1->heap_region_iterate(&rc); | |
105 } | |
106 | |
107 class VerifyRSCleanCardOopClosure: public OopClosure { | |
108 G1CollectedHeap* _g1; | |
109 public: | |
110 VerifyRSCleanCardOopClosure(G1CollectedHeap* g1) : _g1(g1) {} | |
111 | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
796
diff
changeset
|
112 virtual void do_oop(narrowOop* p) { do_oop_work(p); } |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
796
diff
changeset
|
113 virtual void do_oop( oop* p) { do_oop_work(p); } |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
796
diff
changeset
|
114 template <class T> void do_oop_work(T* p) { |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
796
diff
changeset
|
115 oop obj = oopDesc::load_decode_heap_oop(p); |
342 | 116 HeapRegion* to = _g1->heap_region_containing(obj); |
117 guarantee(to == NULL || !to->in_collection_set(), | |
118 "Missed a rem set member."); | |
119 } | |
120 }; | |
121 | |
122 HRInto_G1RemSet::HRInto_G1RemSet(G1CollectedHeap* g1, CardTableModRefBS* ct_bs) | |
123 : G1RemSet(g1), _ct_bs(ct_bs), _g1p(_g1->g1_policy()), | |
124 _cg1r(g1->concurrent_g1_refine()), | |
125 _par_traversal_in_progress(false), _new_refs(NULL), | |
126 _cards_scanned(NULL), _total_cards_scanned(0) | |
127 { | |
128 _seq_task = new SubTasksDone(NumSeqTasks); | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
129 guarantee(n_workers() > 0, "There should be some workers"); |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
796
diff
changeset
|
130 _new_refs = NEW_C_HEAP_ARRAY(GrowableArray<OopOrNarrowOopStar>*, n_workers()); |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
131 for (uint i = 0; i < n_workers(); i++) { |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
796
diff
changeset
|
132 _new_refs[i] = new (ResourceObj::C_HEAP) GrowableArray<OopOrNarrowOopStar>(8192,true); |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
133 } |
342 | 134 } |
135 | |
136 HRInto_G1RemSet::~HRInto_G1RemSet() { | |
137 delete _seq_task; | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
138 for (uint i = 0; i < n_workers(); i++) { |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
139 delete _new_refs[i]; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
140 } |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
796
diff
changeset
|
141 FREE_C_HEAP_ARRAY(GrowableArray<OopOrNarrowOopStar>*, _new_refs); |
342 | 142 } |
143 | |
144 void CountNonCleanMemRegionClosure::do_MemRegion(MemRegion mr) { | |
145 if (_g1->is_in_g1_reserved(mr.start())) { | |
146 _n += (int) ((mr.byte_size() / CardTableModRefBS::card_size)); | |
147 if (_start_first == NULL) _start_first = mr.start(); | |
148 } | |
149 } | |
150 | |
151 class ScanRSClosure : public HeapRegionClosure { | |
152 size_t _cards_done, _cards; | |
153 G1CollectedHeap* _g1h; | |
154 OopsInHeapRegionClosure* _oc; | |
155 G1BlockOffsetSharedArray* _bot_shared; | |
156 CardTableModRefBS *_ct_bs; | |
157 int _worker_i; | |
1261 | 158 int _block_size; |
342 | 159 bool _try_claimed; |
160 public: | |
161 ScanRSClosure(OopsInHeapRegionClosure* oc, int worker_i) : | |
162 _oc(oc), | |
163 _cards(0), | |
164 _cards_done(0), | |
165 _worker_i(worker_i), | |
166 _try_claimed(false) | |
167 { | |
168 _g1h = G1CollectedHeap::heap(); | |
169 _bot_shared = _g1h->bot_shared(); | |
170 _ct_bs = (CardTableModRefBS*) (_g1h->barrier_set()); | |
1261 | 171 _block_size = MAX2<int>(G1RSetScanBlockSize, 1); |
342 | 172 } |
173 | |
174 void set_try_claimed() { _try_claimed = true; } | |
175 | |
176 void scanCard(size_t index, HeapRegion *r) { | |
177 _cards_done++; | |
178 DirtyCardToOopClosure* cl = | |
179 r->new_dcto_closure(_oc, | |
180 CardTableModRefBS::Precise, | |
181 HeapRegionDCTOC::IntoCSFilterKind); | |
182 | |
183 // Set the "from" region in the closure. | |
184 _oc->set_region(r); | |
185 HeapWord* card_start = _bot_shared->address_for_index(index); | |
186 HeapWord* card_end = card_start + G1BlockOffsetSharedArray::N_words; | |
187 Space *sp = SharedHeap::heap()->space_containing(card_start); | |
188 MemRegion sm_region; | |
189 if (ParallelGCThreads > 0) { | |
190 // first find the used area | |
191 sm_region = sp->used_region_at_save_marks(); | |
192 } else { | |
193 // The closure is not idempotent. We shouldn't look at objects | |
194 // allocated during the GC. | |
195 sm_region = sp->used_region_at_save_marks(); | |
196 } | |
197 MemRegion mr = sm_region.intersection(MemRegion(card_start,card_end)); | |
198 if (!mr.is_empty()) { | |
199 cl->do_MemRegion(mr); | |
200 } | |
201 } | |
202 | |
203 void printCard(HeapRegion* card_region, size_t card_index, | |
204 HeapWord* card_start) { | |
205 gclog_or_tty->print_cr("T %d Region [" PTR_FORMAT ", " PTR_FORMAT ") " | |
206 "RS names card %p: " | |
207 "[" PTR_FORMAT ", " PTR_FORMAT ")", | |
208 _worker_i, | |
209 card_region->bottom(), card_region->end(), | |
210 card_index, | |
211 card_start, card_start + G1BlockOffsetSharedArray::N_words); | |
212 } | |
213 | |
214 bool doHeapRegion(HeapRegion* r) { | |
215 assert(r->in_collection_set(), "should only be called on elements of CS."); | |
216 HeapRegionRemSet* hrrs = r->rem_set(); | |
217 if (hrrs->iter_is_complete()) return false; // All done. | |
218 if (!_try_claimed && !hrrs->claim_iter()) return false; | |
796
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
219 _g1h->push_dirty_cards_region(r); |
342 | 220 // If we didn't return above, then |
221 // _try_claimed || r->claim_iter() | |
222 // is true: either we're supposed to work on claimed-but-not-complete | |
223 // regions, or we successfully claimed the region. | |
224 HeapRegionRemSetIterator* iter = _g1h->rem_set_iterator(_worker_i); | |
225 hrrs->init_iterator(iter); | |
226 size_t card_index; | |
1261 | 227 |
228 // We claim cards in block so as to recude the contention. The block size is determined by | |
229 // the G1RSetScanBlockSize parameter. | |
230 size_t jump_to_card = hrrs->iter_claimed_next(_block_size); | |
231 for (size_t current_card = 0; iter->has_next(card_index); current_card++) { | |
232 if (current_card >= jump_to_card + _block_size) { | |
233 jump_to_card = hrrs->iter_claimed_next(_block_size); | |
747 | 234 } |
1261 | 235 if (current_card < jump_to_card) continue; |
342 | 236 HeapWord* card_start = _g1h->bot_shared()->address_for_index(card_index); |
237 #if 0 | |
238 gclog_or_tty->print("Rem set iteration yielded card [" PTR_FORMAT ", " PTR_FORMAT ").\n", | |
239 card_start, card_start + CardTableModRefBS::card_size_in_words); | |
240 #endif | |
241 | |
242 HeapRegion* card_region = _g1h->heap_region_containing(card_start); | |
243 assert(card_region != NULL, "Yielding cards not in the heap?"); | |
244 _cards++; | |
245 | |
796
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
246 if (!card_region->is_on_dirty_cards_region_list()) { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
247 _g1h->push_dirty_cards_region(card_region); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
248 } |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
249 |
747 | 250 // If the card is dirty, then we will scan it during updateRS. |
251 if (!card_region->in_collection_set() && !_ct_bs->is_card_dirty(card_index)) { | |
1261 | 252 // We make the card as "claimed" lazily (so races are possible but they're benign), |
253 // which reduces the number of duplicate scans (the rsets of the regions in the cset | |
254 // can intersect). | |
255 if (!_ct_bs->is_card_claimed(card_index)) { | |
256 _ct_bs->set_card_claimed(card_index); | |
257 scanCard(card_index, card_region); | |
258 } | |
342 | 259 } |
260 } | |
747 | 261 if (!_try_claimed) { |
262 hrrs->set_iter_complete(); | |
263 } | |
342 | 264 return false; |
265 } | |
266 // Set all cards back to clean. | |
267 void cleanup() {_g1h->cleanUpCardTable();} | |
268 size_t cards_done() { return _cards_done;} | |
269 size_t cards_looked_up() { return _cards;} | |
270 }; | |
271 | |
272 // We want the parallel threads to start their scanning at | |
273 // different collection set regions to avoid contention. | |
274 // If we have: | |
275 // n collection set regions | |
276 // p threads | |
277 // Then thread t will start at region t * floor (n/p) | |
278 | |
279 HeapRegion* HRInto_G1RemSet::calculateStartRegion(int worker_i) { | |
280 HeapRegion* result = _g1p->collection_set(); | |
281 if (ParallelGCThreads > 0) { | |
282 size_t cs_size = _g1p->collection_set_size(); | |
283 int n_workers = _g1->workers()->total_workers(); | |
284 size_t cs_spans = cs_size / n_workers; | |
285 size_t ind = cs_spans * worker_i; | |
286 for (size_t i = 0; i < ind; i++) | |
287 result = result->next_in_collection_set(); | |
288 } | |
289 return result; | |
290 } | |
291 | |
292 void HRInto_G1RemSet::scanRS(OopsInHeapRegionClosure* oc, int worker_i) { | |
293 double rs_time_start = os::elapsedTime(); | |
294 HeapRegion *startRegion = calculateStartRegion(worker_i); | |
295 | |
1261 | 296 ScanRSClosure scanRScl(oc, worker_i); |
342 | 297 _g1->collection_set_iterate_from(startRegion, &scanRScl); |
298 scanRScl.set_try_claimed(); | |
299 _g1->collection_set_iterate_from(startRegion, &scanRScl); | |
300 | |
1261 | 301 double scan_rs_time_sec = os::elapsedTime() - rs_time_start; |
342 | 302 |
303 assert( _cards_scanned != NULL, "invariant" ); | |
304 _cards_scanned[worker_i] = scanRScl.cards_done(); | |
305 | |
306 _g1p->record_scan_rs_time(worker_i, scan_rs_time_sec * 1000.0); | |
307 } | |
308 | |
309 void HRInto_G1RemSet::updateRS(int worker_i) { | |
310 ConcurrentG1Refine* cg1r = _g1->concurrent_g1_refine(); | |
311 | |
312 double start = os::elapsedTime(); | |
794 | 313 // Apply the appropriate closure to all remaining log entries. |
314 _g1->iterate_dirty_card_closure(false, worker_i); | |
315 // Now there should be no dirty cards. | |
316 if (G1RSLogCheckCardTable) { | |
317 CountNonCleanMemRegionClosure cl(_g1); | |
318 _ct_bs->mod_card_iterate(&cl); | |
319 // XXX This isn't true any more: keeping cards of young regions | |
320 // marked dirty broke it. Need some reasonable fix. | |
321 guarantee(cl.n() == 0, "Card table should be clean."); | |
342 | 322 } |
794 | 323 |
342 | 324 _g1p->record_update_rs_time(worker_i, (os::elapsedTime() - start) * 1000.0); |
325 } | |
326 | |
327 #ifndef PRODUCT | |
328 class PrintRSClosure : public HeapRegionClosure { | |
329 int _count; | |
330 public: | |
331 PrintRSClosure() : _count(0) {} | |
332 bool doHeapRegion(HeapRegion* r) { | |
333 HeapRegionRemSet* hrrs = r->rem_set(); | |
334 _count += (int) hrrs->occupied(); | |
335 if (hrrs->occupied() == 0) { | |
336 gclog_or_tty->print("Heap Region [" PTR_FORMAT ", " PTR_FORMAT ") " | |
337 "has no remset entries\n", | |
338 r->bottom(), r->end()); | |
339 } else { | |
340 gclog_or_tty->print("Printing rem set for heap region [" PTR_FORMAT ", " PTR_FORMAT ")\n", | |
341 r->bottom(), r->end()); | |
342 r->print(); | |
343 hrrs->print(); | |
344 gclog_or_tty->print("\nDone printing rem set\n"); | |
345 } | |
346 return false; | |
347 } | |
348 int occupied() {return _count;} | |
349 }; | |
350 #endif | |
351 | |
352 class CountRSSizeClosure: public HeapRegionClosure { | |
353 size_t _n; | |
354 size_t _tot; | |
355 size_t _max; | |
356 HeapRegion* _max_r; | |
357 enum { | |
358 N = 20, | |
359 MIN = 6 | |
360 }; | |
361 int _histo[N]; | |
362 public: | |
363 CountRSSizeClosure() : _n(0), _tot(0), _max(0), _max_r(NULL) { | |
364 for (int i = 0; i < N; i++) _histo[i] = 0; | |
365 } | |
366 bool doHeapRegion(HeapRegion* r) { | |
367 if (!r->continuesHumongous()) { | |
368 size_t occ = r->rem_set()->occupied(); | |
369 _n++; | |
370 _tot += occ; | |
371 if (occ > _max) { | |
372 _max = occ; | |
373 _max_r = r; | |
374 } | |
375 // Fit it into a histo bin. | |
376 int s = 1 << MIN; | |
377 int i = 0; | |
378 while (occ > (size_t) s && i < (N-1)) { | |
379 s = s << 1; | |
380 i++; | |
381 } | |
382 _histo[i]++; | |
383 } | |
384 return false; | |
385 } | |
386 size_t n() { return _n; } | |
387 size_t tot() { return _tot; } | |
388 size_t mx() { return _max; } | |
389 HeapRegion* mxr() { return _max_r; } | |
390 void print_histo() { | |
391 int mx = N; | |
392 while (mx >= 0) { | |
393 if (_histo[mx-1] > 0) break; | |
394 mx--; | |
395 } | |
396 gclog_or_tty->print_cr("Number of regions with given RS sizes:"); | |
397 gclog_or_tty->print_cr(" <= %8d %8d", 1 << MIN, _histo[0]); | |
398 for (int i = 1; i < mx-1; i++) { | |
399 gclog_or_tty->print_cr(" %8d - %8d %8d", | |
400 (1 << (MIN + i - 1)) + 1, | |
401 1 << (MIN + i), | |
402 _histo[i]); | |
403 } | |
404 gclog_or_tty->print_cr(" > %8d %8d", (1 << (MIN+mx-2))+1, _histo[mx-1]); | |
405 } | |
406 }; | |
407 | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
796
diff
changeset
|
408 template <class T> void |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
796
diff
changeset
|
409 HRInto_G1RemSet::scanNewRefsRS_work(OopsInHeapRegionClosure* oc, |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
796
diff
changeset
|
410 int worker_i) { |
342 | 411 double scan_new_refs_start_sec = os::elapsedTime(); |
412 G1CollectedHeap* g1h = G1CollectedHeap::heap(); | |
413 CardTableModRefBS* ct_bs = (CardTableModRefBS*) (g1h->barrier_set()); | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
414 for (int i = 0; i < _new_refs[worker_i]->length(); i++) { |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
796
diff
changeset
|
415 T* p = (T*) _new_refs[worker_i]->at(i); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
796
diff
changeset
|
416 oop obj = oopDesc::load_decode_heap_oop(p); |
342 | 417 // *p was in the collection set when p was pushed on "_new_refs", but |
418 // another thread may have processed this location from an RS, so it | |
419 // might not point into the CS any longer. If so, it's obviously been | |
420 // processed, and we don't need to do anything further. | |
421 if (g1h->obj_in_cs(obj)) { | |
422 HeapRegion* r = g1h->heap_region_containing(p); | |
423 | |
424 DEBUG_ONLY(HeapRegion* to = g1h->heap_region_containing(obj)); | |
425 oc->set_region(r); | |
426 // If "p" has already been processed concurrently, this is | |
427 // idempotent. | |
428 oc->do_oop(p); | |
429 } | |
430 } | |
1261 | 431 double scan_new_refs_time_ms = (os::elapsedTime() - scan_new_refs_start_sec) * 1000.0; |
432 _g1p->record_scan_new_refs_time(worker_i, scan_new_refs_time_ms); | |
342 | 433 } |
434 | |
435 void HRInto_G1RemSet::cleanupHRRS() { | |
436 HeapRegionRemSet::cleanup(); | |
437 } | |
438 | |
439 void | |
440 HRInto_G1RemSet::oops_into_collection_set_do(OopsInHeapRegionClosure* oc, | |
441 int worker_i) { | |
442 #if CARD_REPEAT_HISTO | |
443 ct_freq_update_histo_and_reset(); | |
444 #endif | |
445 if (worker_i == 0) { | |
446 _cg1r->clear_and_record_card_counts(); | |
447 } | |
448 | |
449 // Make this into a command-line flag... | |
450 if (G1RSCountHisto && (ParallelGCThreads == 0 || worker_i == 0)) { | |
451 CountRSSizeClosure count_cl; | |
452 _g1->heap_region_iterate(&count_cl); | |
453 gclog_or_tty->print_cr("Avg of %d RS counts is %f, max is %d, " | |
454 "max region is " PTR_FORMAT, | |
455 count_cl.n(), (float)count_cl.tot()/(float)count_cl.n(), | |
456 count_cl.mx(), count_cl.mxr()); | |
457 count_cl.print_histo(); | |
458 } | |
459 | |
460 if (ParallelGCThreads > 0) { | |
638
2a5da27ccae9
6816154: G1: introduce flags to enable/disable RSet updating and scanning
tonyp
parents:
637
diff
changeset
|
461 // The two flags below were introduced temporarily to serialize |
2a5da27ccae9
6816154: G1: introduce flags to enable/disable RSet updating and scanning
tonyp
parents:
637
diff
changeset
|
462 // the updating and scanning of remembered sets. There are some |
2a5da27ccae9
6816154: G1: introduce flags to enable/disable RSet updating and scanning
tonyp
parents:
637
diff
changeset
|
463 // race conditions when these two operations are done in parallel |
2a5da27ccae9
6816154: G1: introduce flags to enable/disable RSet updating and scanning
tonyp
parents:
637
diff
changeset
|
464 // and they are causing failures. When we resolve said race |
2a5da27ccae9
6816154: G1: introduce flags to enable/disable RSet updating and scanning
tonyp
parents:
637
diff
changeset
|
465 // conditions, we'll revert back to parallel remembered set |
2a5da27ccae9
6816154: G1: introduce flags to enable/disable RSet updating and scanning
tonyp
parents:
637
diff
changeset
|
466 // updating and scanning. See CRs 6677707 and 6677708. |
1282 | 467 if (G1UseParallelRSetUpdating || (worker_i == 0)) { |
342 | 468 updateRS(worker_i); |
469 scanNewRefsRS(oc, worker_i); | |
648
2314b7336582
6820321: G1: Error: guarantee(check_nums(total, n, parts), "all seq lengths should match")
tonyp
parents:
640
diff
changeset
|
470 } else { |
2314b7336582
6820321: G1: Error: guarantee(check_nums(total, n, parts), "all seq lengths should match")
tonyp
parents:
640
diff
changeset
|
471 _g1p->record_update_rs_processed_buffers(worker_i, 0.0); |
2314b7336582
6820321: G1: Error: guarantee(check_nums(total, n, parts), "all seq lengths should match")
tonyp
parents:
640
diff
changeset
|
472 _g1p->record_update_rs_time(worker_i, 0.0); |
2314b7336582
6820321: G1: Error: guarantee(check_nums(total, n, parts), "all seq lengths should match")
tonyp
parents:
640
diff
changeset
|
473 _g1p->record_scan_new_refs_time(worker_i, 0.0); |
638
2a5da27ccae9
6816154: G1: introduce flags to enable/disable RSet updating and scanning
tonyp
parents:
637
diff
changeset
|
474 } |
1282 | 475 if (G1UseParallelRSetScanning || (worker_i == 0)) { |
342 | 476 scanRS(oc, worker_i); |
648
2314b7336582
6820321: G1: Error: guarantee(check_nums(total, n, parts), "all seq lengths should match")
tonyp
parents:
640
diff
changeset
|
477 } else { |
2314b7336582
6820321: G1: Error: guarantee(check_nums(total, n, parts), "all seq lengths should match")
tonyp
parents:
640
diff
changeset
|
478 _g1p->record_scan_rs_time(worker_i, 0.0); |
342 | 479 } |
480 } else { | |
481 assert(worker_i == 0, "invariant"); | |
482 updateRS(0); | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
483 scanNewRefsRS(oc, 0); |
342 | 484 scanRS(oc, 0); |
485 } | |
486 } | |
487 | |
488 void HRInto_G1RemSet:: | |
489 prepare_for_oops_into_collection_set_do() { | |
490 #if G1_REM_SET_LOGGING | |
491 PrintRSClosure cl; | |
492 _g1->collection_set_iterate(&cl); | |
493 #endif | |
494 cleanupHRRS(); | |
495 ConcurrentG1Refine* cg1r = _g1->concurrent_g1_refine(); | |
496 _g1->set_refine_cte_cl_concurrency(false); | |
497 DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); | |
498 dcqs.concatenate_logs(); | |
499 | |
500 assert(!_par_traversal_in_progress, "Invariant between iterations."); | |
501 if (ParallelGCThreads > 0) { | |
502 set_par_traversal(true); | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
503 _seq_task->set_par_threads((int)n_workers()); |
342 | 504 } |
505 guarantee( _cards_scanned == NULL, "invariant" ); | |
506 _cards_scanned = NEW_C_HEAP_ARRAY(size_t, n_workers()); | |
545 | 507 for (uint i = 0; i < n_workers(); ++i) { |
508 _cards_scanned[i] = 0; | |
509 } | |
342 | 510 _total_cards_scanned = 0; |
511 } | |
512 | |
513 | |
514 class cleanUpIteratorsClosure : public HeapRegionClosure { | |
515 bool doHeapRegion(HeapRegion *r) { | |
516 HeapRegionRemSet* hrrs = r->rem_set(); | |
517 hrrs->init_for_par_iteration(); | |
518 return false; | |
519 } | |
520 }; | |
521 | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
522 class UpdateRSetOopsIntoCSImmediate : public OopClosure { |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
523 G1CollectedHeap* _g1; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
524 public: |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
525 UpdateRSetOopsIntoCSImmediate(G1CollectedHeap* g1) : _g1(g1) { } |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
796
diff
changeset
|
526 virtual void do_oop(narrowOop* p) { do_oop_work(p); } |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
796
diff
changeset
|
527 virtual void do_oop( oop* p) { do_oop_work(p); } |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
796
diff
changeset
|
528 template <class T> void do_oop_work(T* p) { |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
796
diff
changeset
|
529 HeapRegion* to = _g1->heap_region_containing(oopDesc::load_decode_heap_oop(p)); |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
530 if (to->in_collection_set()) { |
677 | 531 to->rem_set()->add_reference(p, 0); |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
532 } |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
533 } |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
534 }; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
535 |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
536 class UpdateRSetOopsIntoCSDeferred : public OopClosure { |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
537 G1CollectedHeap* _g1; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
538 CardTableModRefBS* _ct_bs; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
539 DirtyCardQueue* _dcq; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
540 public: |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
541 UpdateRSetOopsIntoCSDeferred(G1CollectedHeap* g1, DirtyCardQueue* dcq) : |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
542 _g1(g1), _ct_bs((CardTableModRefBS*)_g1->barrier_set()), _dcq(dcq) { } |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
796
diff
changeset
|
543 virtual void do_oop(narrowOop* p) { do_oop_work(p); } |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
796
diff
changeset
|
544 virtual void do_oop( oop* p) { do_oop_work(p); } |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
796
diff
changeset
|
545 template <class T> void do_oop_work(T* p) { |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
796
diff
changeset
|
546 oop obj = oopDesc::load_decode_heap_oop(p); |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
547 if (_g1->obj_in_cs(obj)) { |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
548 size_t card_index = _ct_bs->index_for(p); |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
549 if (_ct_bs->mark_card_deferred(card_index)) { |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
550 _dcq->enqueue((jbyte*)_ct_bs->byte_for_index(card_index)); |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
551 } |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
552 } |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
553 } |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
554 }; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
555 |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
796
diff
changeset
|
556 template <class T> void HRInto_G1RemSet::new_refs_iterate_work(OopClosure* cl) { |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
557 for (size_t i = 0; i < n_workers(); i++) { |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
558 for (int j = 0; j < _new_refs[i]->length(); j++) { |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
796
diff
changeset
|
559 T* p = (T*) _new_refs[i]->at(j); |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
560 cl->do_oop(p); |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
561 } |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
562 } |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
563 } |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
564 |
342 | 565 void HRInto_G1RemSet::cleanup_after_oops_into_collection_set_do() { |
566 guarantee( _cards_scanned != NULL, "invariant" ); | |
567 _total_cards_scanned = 0; | |
568 for (uint i = 0; i < n_workers(); ++i) | |
569 _total_cards_scanned += _cards_scanned[i]; | |
570 FREE_C_HEAP_ARRAY(size_t, _cards_scanned); | |
571 _cards_scanned = NULL; | |
572 // Cleanup after copy | |
573 #if G1_REM_SET_LOGGING | |
574 PrintRSClosure cl; | |
575 _g1->heap_region_iterate(&cl); | |
576 #endif | |
577 _g1->set_refine_cte_cl_concurrency(true); | |
578 cleanUpIteratorsClosure iterClosure; | |
579 _g1->collection_set_iterate(&iterClosure); | |
580 // Set all cards back to clean. | |
581 _g1->cleanUpCardTable(); | |
794 | 582 |
342 | 583 if (ParallelGCThreads > 0) { |
584 set_par_traversal(false); | |
585 } | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
586 |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
587 if (_g1->evacuation_failed()) { |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
588 // Restore remembered sets for the regions pointing into |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
589 // the collection set. |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
590 if (G1DeferredRSUpdate) { |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
591 DirtyCardQueue dcq(&_g1->dirty_card_queue_set()); |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
592 UpdateRSetOopsIntoCSDeferred deferred_update(_g1, &dcq); |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
593 new_refs_iterate(&deferred_update); |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
594 } else { |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
595 UpdateRSetOopsIntoCSImmediate immediate_update(_g1); |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
596 new_refs_iterate(&immediate_update); |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
597 } |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
598 } |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
599 for (uint i = 0; i < n_workers(); i++) { |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
600 _new_refs[i]->clear(); |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
601 } |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
545
diff
changeset
|
602 |
342 | 603 assert(!_par_traversal_in_progress, "Invariant between iterations."); |
604 } | |
605 | |
606 class UpdateRSObjectClosure: public ObjectClosure { | |
607 UpdateRSOopClosure* _update_rs_oop_cl; | |
608 public: | |
609 UpdateRSObjectClosure(UpdateRSOopClosure* update_rs_oop_cl) : | |
610 _update_rs_oop_cl(update_rs_oop_cl) {} | |
611 void do_object(oop obj) { | |
612 obj->oop_iterate(_update_rs_oop_cl); | |
613 } | |
614 | |
615 }; | |
616 | |
617 class ScrubRSClosure: public HeapRegionClosure { | |
618 G1CollectedHeap* _g1h; | |
619 BitMap* _region_bm; | |
620 BitMap* _card_bm; | |
621 CardTableModRefBS* _ctbs; | |
622 public: | |
623 ScrubRSClosure(BitMap* region_bm, BitMap* card_bm) : | |
624 _g1h(G1CollectedHeap::heap()), | |
625 _region_bm(region_bm), _card_bm(card_bm), | |
626 _ctbs(NULL) | |
627 { | |
628 ModRefBarrierSet* bs = _g1h->mr_bs(); | |
629 guarantee(bs->is_a(BarrierSet::CardTableModRef), "Precondition"); | |
630 _ctbs = (CardTableModRefBS*)bs; | |
631 } | |
632 | |
633 bool doHeapRegion(HeapRegion* r) { | |
634 if (!r->continuesHumongous()) { | |
635 r->rem_set()->scrub(_ctbs, _region_bm, _card_bm); | |
636 } | |
637 return false; | |
638 } | |
639 }; | |
640 | |
641 void HRInto_G1RemSet::scrub(BitMap* region_bm, BitMap* card_bm) { | |
642 ScrubRSClosure scrub_cl(region_bm, card_bm); | |
643 _g1->heap_region_iterate(&scrub_cl); | |
644 } | |
645 | |
646 void HRInto_G1RemSet::scrub_par(BitMap* region_bm, BitMap* card_bm, | |
647 int worker_num, int claim_val) { | |
648 ScrubRSClosure scrub_cl(region_bm, card_bm); | |
649 _g1->heap_region_par_iterate_chunked(&scrub_cl, worker_num, claim_val); | |
650 } | |
651 | |
652 | |
653 static IntHistogram out_of_histo(50, 50); | |
654 | |
890
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
655 void HRInto_G1RemSet::concurrentRefineOneCard_impl(jbyte* card_ptr, int worker_i) { |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
656 // Construct the region representing the card. |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
657 HeapWord* start = _ct_bs->addr_for(card_ptr); |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
658 // And find the region containing it. |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
659 HeapRegion* r = _g1->heap_region_containing(start); |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
660 assert(r != NULL, "unexpected null"); |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
661 |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
662 HeapWord* end = _ct_bs->addr_for(card_ptr + 1); |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
663 MemRegion dirtyRegion(start, end); |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
664 |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
665 #if CARD_REPEAT_HISTO |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
666 init_ct_freq_table(_g1->g1_reserved_obj_bytes()); |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
667 ct_freq_note_card(_ct_bs->index_for(start)); |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
668 #endif |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
669 |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
670 UpdateRSOopClosure update_rs_oop_cl(this, worker_i); |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
671 update_rs_oop_cl.set_from(r); |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
672 FilterOutOfRegionClosure filter_then_update_rs_oop_cl(r, &update_rs_oop_cl); |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
673 |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
674 // Undirty the card. |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
675 *card_ptr = CardTableModRefBS::clean_card_val(); |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
676 // We must complete this write before we do any of the reads below. |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
677 OrderAccess::storeload(); |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
678 // And process it, being careful of unallocated portions of TLAB's. |
1666
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1611
diff
changeset
|
679 |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1611
diff
changeset
|
680 // The region for the current card may be a young region. The |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1611
diff
changeset
|
681 // current card may have been a card that was evicted from the |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1611
diff
changeset
|
682 // card cache. When the card was inserted into the cache, we had |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1611
diff
changeset
|
683 // determined that its region was non-young. While in the cache, |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1611
diff
changeset
|
684 // the region may have been freed during a cleanup pause, reallocated |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1611
diff
changeset
|
685 // and tagged as young. |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1611
diff
changeset
|
686 // |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1611
diff
changeset
|
687 // We wish to filter out cards for such a region but the current |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1611
diff
changeset
|
688 // thread, if we're running conucrrently, may "see" the young type |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1611
diff
changeset
|
689 // change at any time (so an earlier "is_young" check may pass or |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1611
diff
changeset
|
690 // fail arbitrarily). We tell the iteration code to perform this |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1611
diff
changeset
|
691 // filtering when it has been determined that there has been an actual |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1611
diff
changeset
|
692 // allocation in this region and making it safe to check the young type. |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1611
diff
changeset
|
693 bool filter_young = true; |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1611
diff
changeset
|
694 |
890
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
695 HeapWord* stop_point = |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
696 r->oops_on_card_seq_iterate_careful(dirtyRegion, |
1666
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1611
diff
changeset
|
697 &filter_then_update_rs_oop_cl, |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1611
diff
changeset
|
698 filter_young); |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1611
diff
changeset
|
699 |
890
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
700 // If stop_point is non-null, then we encountered an unallocated region |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
701 // (perhaps the unfilled portion of a TLAB.) For now, we'll dirty the |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
702 // card and re-enqueue: if we put off the card until a GC pause, then the |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
703 // unallocated portion will be filled in. Alternatively, we might try |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
704 // the full complexity of the technique used in "regular" precleaning. |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
705 if (stop_point != NULL) { |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
706 // The card might have gotten re-dirtied and re-enqueued while we |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
707 // worked. (In fact, it's pretty likely.) |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
708 if (*card_ptr != CardTableModRefBS::dirty_card_val()) { |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
709 *card_ptr = CardTableModRefBS::dirty_card_val(); |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
710 MutexLockerEx x(Shared_DirtyCardQ_lock, |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
711 Mutex::_no_safepoint_check_flag); |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
712 DirtyCardQueue* sdcq = |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
713 JavaThread::dirty_card_queue_set().shared_dirty_card_queue(); |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
714 sdcq->enqueue(card_ptr); |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
715 } |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
716 } else { |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
717 out_of_histo.add_entry(filter_then_update_rs_oop_cl.out_of_region()); |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
718 _conc_refine_cards++; |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
719 } |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
720 } |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
721 |
342 | 722 void HRInto_G1RemSet::concurrentRefineOneCard(jbyte* card_ptr, int worker_i) { |
723 // If the card is no longer dirty, nothing to do. | |
724 if (*card_ptr != CardTableModRefBS::dirty_card_val()) return; | |
725 | |
726 // Construct the region representing the card. | |
727 HeapWord* start = _ct_bs->addr_for(card_ptr); | |
728 // And find the region containing it. | |
729 HeapRegion* r = _g1->heap_region_containing(start); | |
730 if (r == NULL) { | |
731 guarantee(_g1->is_in_permanent(start), "Or else where?"); | |
732 return; // Not in the G1 heap (might be in perm, for example.) | |
733 } | |
734 // Why do we have to check here whether a card is on a young region, | |
735 // given that we dirty young regions and, as a result, the | |
736 // post-barrier is supposed to filter them out and never to enqueue | |
737 // them? When we allocate a new region as the "allocation region" we | |
738 // actually dirty its cards after we release the lock, since card | |
739 // dirtying while holding the lock was a performance bottleneck. So, | |
740 // as a result, it is possible for other threads to actually | |
741 // allocate objects in the region (after the acquire the lock) | |
742 // before all the cards on the region are dirtied. This is unlikely, | |
743 // and it doesn't happen often, but it can happen. So, the extra | |
744 // check below filters out those cards. | |
637
25e146966e7c
6817419: G1: Enable extensive verification for humongous regions
iveresov
parents:
626
diff
changeset
|
745 if (r->is_young()) { |
342 | 746 return; |
747 } | |
748 // While we are processing RSet buffers during the collection, we | |
749 // actually don't want to scan any cards on the collection set, | |
750 // since we don't want to update remebered sets with entries that | |
751 // point into the collection set, given that live objects from the | |
752 // collection set are about to move and such entries will be stale | |
753 // very soon. This change also deals with a reliability issue which | |
754 // involves scanning a card in the collection set and coming across | |
755 // an array that was being chunked and looking malformed. Note, | |
756 // however, that if evacuation fails, we have to scan any objects | |
757 // that were not moved and create any missing entries. | |
758 if (r->in_collection_set()) { | |
759 return; | |
760 } | |
761 | |
890
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
762 // Should we defer processing the card? |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
763 // |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
764 // Previously the result from the insert_cache call would be |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
765 // either card_ptr (implying that card_ptr was currently "cold"), |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
766 // null (meaning we had inserted the card ptr into the "hot" |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
767 // cache, which had some headroom), or a "hot" card ptr |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
768 // extracted from the "hot" cache. |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
769 // |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
770 // Now that the _card_counts cache in the ConcurrentG1Refine |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
771 // instance is an evicting hash table, the result we get back |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
772 // could be from evicting the card ptr in an already occupied |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
773 // bucket (in which case we have replaced the card ptr in the |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
774 // bucket with card_ptr and "defer" is set to false). To avoid |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
775 // having a data structure (updates to which would need a lock) |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
776 // to hold these unprocessed dirty cards, we need to immediately |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
777 // process card_ptr. The actions needed to be taken on return |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
778 // from cache_insert are summarized in the following table: |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
779 // |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
780 // res defer action |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
781 // -------------------------------------------------------------- |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
782 // null false card evicted from _card_counts & replaced with |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
783 // card_ptr; evicted ptr added to hot cache. |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
784 // No need to process res; immediately process card_ptr |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
785 // |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
786 // null true card not evicted from _card_counts; card_ptr added |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
787 // to hot cache. |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
788 // Nothing to do. |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
789 // |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
790 // non-null false card evicted from _card_counts & replaced with |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
791 // card_ptr; evicted ptr is currently "cold" or |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
792 // caused an eviction from the hot cache. |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
793 // Immediately process res; process card_ptr. |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
794 // |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
795 // non-null true card not evicted from _card_counts; card_ptr is |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
796 // currently cold, or caused an eviction from hot |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
797 // cache. |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
798 // Immediately process res; no need to process card_ptr. |
342 | 799 |
890
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
800 jbyte* res = card_ptr; |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
801 bool defer = false; |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
802 if (_cg1r->use_cache()) { |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
803 jbyte* res = _cg1r->cache_insert(card_ptr, &defer); |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
804 if (res != NULL && (res != card_ptr || defer)) { |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
805 start = _ct_bs->addr_for(res); |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
806 r = _g1->heap_region_containing(start); |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
807 if (r == NULL) { |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
808 assert(_g1->is_in_permanent(start), "Or else where?"); |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
809 } else { |
1666
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1611
diff
changeset
|
810 // Checking whether the region we got back from the cache |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1611
diff
changeset
|
811 // is young here is inappropriate. The region could have been |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1611
diff
changeset
|
812 // freed, reallocated and tagged as young while in the cache. |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1611
diff
changeset
|
813 // Hence we could see its young type change at any time. |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1611
diff
changeset
|
814 // |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1611
diff
changeset
|
815 // Process card pointer we get back from the hot card cache. This |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1611
diff
changeset
|
816 // will check whether the region containing the card is young |
5cbac8938c4c
6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents:
1611
diff
changeset
|
817 // _after_ checking that the region has been allocated from. |
890
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
818 concurrentRefineOneCard_impl(res, worker_i); |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
819 } |
342 | 820 } |
821 } | |
822 | |
890
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
823 if (!defer) { |
6cb8e9df7174
6819077: G1: first GC thread coming late into the GC.
johnc
parents:
845
diff
changeset
|
824 concurrentRefineOneCard_impl(card_ptr, worker_i); |
342 | 825 } |
826 } | |
827 | |
828 class HRRSStatsIter: public HeapRegionClosure { | |
829 size_t _occupied; | |
830 size_t _total_mem_sz; | |
831 size_t _max_mem_sz; | |
832 HeapRegion* _max_mem_sz_region; | |
833 public: | |
834 HRRSStatsIter() : | |
835 _occupied(0), | |
836 _total_mem_sz(0), | |
837 _max_mem_sz(0), | |
838 _max_mem_sz_region(NULL) | |
839 {} | |
840 | |
841 bool doHeapRegion(HeapRegion* r) { | |
842 if (r->continuesHumongous()) return false; | |
843 size_t mem_sz = r->rem_set()->mem_size(); | |
844 if (mem_sz > _max_mem_sz) { | |
845 _max_mem_sz = mem_sz; | |
846 _max_mem_sz_region = r; | |
847 } | |
848 _total_mem_sz += mem_sz; | |
849 size_t occ = r->rem_set()->occupied(); | |
850 _occupied += occ; | |
851 return false; | |
852 } | |
853 size_t total_mem_sz() { return _total_mem_sz; } | |
854 size_t max_mem_sz() { return _max_mem_sz; } | |
855 size_t occupied() { return _occupied; } | |
856 HeapRegion* max_mem_sz_region() { return _max_mem_sz_region; } | |
857 }; | |
858 | |
794 | 859 class PrintRSThreadVTimeClosure : public ThreadClosure { |
860 public: | |
861 virtual void do_thread(Thread *t) { | |
862 ConcurrentG1RefineThread* crt = (ConcurrentG1RefineThread*) t; | |
863 gclog_or_tty->print(" %5.2f", crt->vtime_accum()); | |
864 } | |
865 }; | |
866 | |
342 | 867 void HRInto_G1RemSet::print_summary_info() { |
868 G1CollectedHeap* g1 = G1CollectedHeap::heap(); | |
869 | |
870 #if CARD_REPEAT_HISTO | |
871 gclog_or_tty->print_cr("\nG1 card_repeat count histogram: "); | |
872 gclog_or_tty->print_cr(" # of repeats --> # of cards with that number."); | |
873 card_repeat_count.print_on(gclog_or_tty); | |
874 #endif | |
875 | |
876 if (FILTEROUTOFREGIONCLOSURE_DOHISTOGRAMCOUNT) { | |
877 gclog_or_tty->print_cr("\nG1 rem-set out-of-region histogram: "); | |
878 gclog_or_tty->print_cr(" # of CS ptrs --> # of cards with that number."); | |
879 out_of_histo.print_on(gclog_or_tty); | |
880 } | |
794 | 881 gclog_or_tty->print_cr("\n Concurrent RS processed %d cards", |
882 _conc_refine_cards); | |
342 | 883 DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); |
884 jint tot_processed_buffers = | |
885 dcqs.processed_buffers_mut() + dcqs.processed_buffers_rs_thread(); | |
886 gclog_or_tty->print_cr(" Of %d completed buffers:", tot_processed_buffers); | |
794 | 887 gclog_or_tty->print_cr(" %8d (%5.1f%%) by conc RS threads.", |
342 | 888 dcqs.processed_buffers_rs_thread(), |
889 100.0*(float)dcqs.processed_buffers_rs_thread()/ | |
890 (float)tot_processed_buffers); | |
891 gclog_or_tty->print_cr(" %8d (%5.1f%%) by mutator threads.", | |
892 dcqs.processed_buffers_mut(), | |
893 100.0*(float)dcqs.processed_buffers_mut()/ | |
894 (float)tot_processed_buffers); | |
794 | 895 gclog_or_tty->print_cr(" Conc RS threads times(s)"); |
896 PrintRSThreadVTimeClosure p; | |
897 gclog_or_tty->print(" "); | |
898 g1->concurrent_g1_refine()->threads_do(&p); | |
342 | 899 gclog_or_tty->print_cr(""); |
794 | 900 |
342 | 901 if (G1UseHRIntoRS) { |
902 HRRSStatsIter blk; | |
903 g1->heap_region_iterate(&blk); | |
904 gclog_or_tty->print_cr(" Total heap region rem set sizes = " SIZE_FORMAT "K." | |
905 " Max = " SIZE_FORMAT "K.", | |
906 blk.total_mem_sz()/K, blk.max_mem_sz()/K); | |
907 gclog_or_tty->print_cr(" Static structures = " SIZE_FORMAT "K," | |
908 " free_lists = " SIZE_FORMAT "K.", | |
909 HeapRegionRemSet::static_mem_size()/K, | |
910 HeapRegionRemSet::fl_mem_size()/K); | |
911 gclog_or_tty->print_cr(" %d occupied cards represented.", | |
912 blk.occupied()); | |
913 gclog_or_tty->print_cr(" Max sz region = [" PTR_FORMAT ", " PTR_FORMAT " )" | |
677 | 914 ", cap = " SIZE_FORMAT "K, occ = " SIZE_FORMAT "K.", |
342 | 915 blk.max_mem_sz_region()->bottom(), blk.max_mem_sz_region()->end(), |
916 (blk.max_mem_sz_region()->rem_set()->mem_size() + K - 1)/K, | |
917 (blk.max_mem_sz_region()->rem_set()->occupied() + K - 1)/K); | |
918 gclog_or_tty->print_cr(" Did %d coarsenings.", | |
919 HeapRegionRemSet::n_coarsenings()); | |
920 | |
921 } | |
922 } | |
923 void HRInto_G1RemSet::prepare_for_verify() { | |
637
25e146966e7c
6817419: G1: Enable extensive verification for humongous regions
iveresov
parents:
626
diff
changeset
|
924 if (G1HRRSFlushLogBuffersOnVerify && |
25e146966e7c
6817419: G1: Enable extensive verification for humongous regions
iveresov
parents:
626
diff
changeset
|
925 (VerifyBeforeGC || VerifyAfterGC) |
25e146966e7c
6817419: G1: Enable extensive verification for humongous regions
iveresov
parents:
626
diff
changeset
|
926 && !_g1->full_collection()) { |
342 | 927 cleanupHRRS(); |
928 _g1->set_refine_cte_cl_concurrency(false); | |
929 if (SafepointSynchronize::is_at_safepoint()) { | |
930 DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); | |
931 dcqs.concatenate_logs(); | |
932 } | |
933 bool cg1r_use_cache = _cg1r->use_cache(); | |
934 _cg1r->set_use_cache(false); | |
935 updateRS(0); | |
936 _cg1r->set_use_cache(cg1r_use_cache); | |
637
25e146966e7c
6817419: G1: Enable extensive verification for humongous regions
iveresov
parents:
626
diff
changeset
|
937 |
25e146966e7c
6817419: G1: Enable extensive verification for humongous regions
iveresov
parents:
626
diff
changeset
|
938 assert(JavaThread::dirty_card_queue_set().completed_buffers_num() == 0, "All should be consumed"); |
342 | 939 } |
940 } |