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 */
24
25 #include "precompiled.hpp"
26 #include "gc/g1/dirtyCardQueue.hpp"
27 #include "gc/g1/g1BarrierSet.hpp"
28 #include "gc/g1/g1BlockOffsetTable.inline.hpp"
29 #include "gc/g1/g1CardTable.inline.hpp"
30 #include "gc/g1/g1CollectedHeap.inline.hpp"
31 #include "gc/g1/g1ConcurrentRefine.hpp"
32 #include "gc/g1/g1FromCardCache.hpp"
33 #include "gc/g1/g1GCPhaseTimes.hpp"
34 #include "gc/g1/g1HotCardCache.hpp"
35 #include "gc/g1/g1OopClosures.inline.hpp"
36 #include "gc/g1/g1RemSet.hpp"
37 #include "gc/g1/heapRegion.inline.hpp"
38 #include "gc/g1/heapRegionManager.inline.hpp"
39 #include "gc/g1/heapRegionRemSet.hpp"
40 #include "gc/shared/gcTraceTime.inline.hpp"
41 #include "gc/shared/suspendibleThreadSet.hpp"
42 #include "memory/iterator.hpp"
43 #include "memory/resourceArea.hpp"
44 #include "oops/access.inline.hpp"
45 #include "oops/oop.inline.hpp"
46 #include "utilities/align.hpp"
47 #include "utilities/globalDefinitions.hpp"
48 #include "utilities/intHisto.hpp"
49 #include "utilities/stack.inline.hpp"
50 #include "utilities/ticks.inline.hpp"
51
52 // Collects information about the overall remembered set scan progress during an evacuation.
53 class G1RemSetScanState : public CHeapObj<mtGC> {
54 private:
55 class G1ClearCardTableTask : public AbstractGangTask {
289 _prev_period_summary() {
290 }
291
292 G1RemSet::~G1RemSet() {
293 if (_scan_state != NULL) {
294 delete _scan_state;
295 }
296 }
297
298 uint G1RemSet::num_par_rem_sets() {
299 return DirtyCardQueueSet::num_par_ids() + G1ConcurrentRefine::max_num_threads() + MAX2(ConcGCThreads, ParallelGCThreads);
300 }
301
302 void G1RemSet::initialize(size_t capacity, uint max_regions) {
303 G1FromCardCache::initialize(num_par_rem_sets(), max_regions);
304 _scan_state->initialize(max_regions);
305 }
306
307 G1ScanRSForRegionClosure::G1ScanRSForRegionClosure(G1RemSetScanState* scan_state,
308 G1ScanObjsDuringScanRSClosure* scan_obj_on_card,
309 CodeBlobClosure* code_root_cl,
310 uint worker_i) :
311 _scan_state(scan_state),
312 _scan_objs_on_card_cl(scan_obj_on_card),
313 _code_root_cl(code_root_cl),
314 _strong_code_root_scan_time_sec(0.0),
315 _cards_claimed(0),
316 _cards_scanned(0),
317 _cards_skipped(0),
318 _worker_i(worker_i) {
319 _g1h = G1CollectedHeap::heap();
320 _bot = _g1h->bot();
321 _ct = _g1h->card_table();
322 }
323
324 void G1ScanRSForRegionClosure::scan_card(MemRegion mr, uint region_idx_for_card) {
325 HeapRegion* const card_region = _g1h->region_at(region_idx_for_card);
326 _scan_objs_on_card_cl->set_region(card_region);
327 card_region->oops_on_card_seq_iterate_careful<true>(mr, _scan_objs_on_card_cl);
328 _cards_scanned++;
329 }
330
331 void G1ScanRSForRegionClosure::scan_strong_code_roots(HeapRegion* r) {
332 double scan_start = os::elapsedTime();
333 r->strong_code_roots_do(_code_root_cl);
334 _strong_code_root_scan_time_sec += (os::elapsedTime() - scan_start);
335 }
336
337 void G1ScanRSForRegionClosure::claim_card(size_t card_index, const uint region_idx_for_card){
338 _ct->set_card_claimed(card_index);
339 _scan_state->add_dirty_region(region_idx_for_card);
340 }
341
342 bool G1ScanRSForRegionClosure::do_heap_region(HeapRegion* r) {
343 assert(r->in_collection_set(), "should only be called on elements of CS.");
344 uint region_idx = r->hrm_index();
345
346 if (_scan_state->iter_is_complete(region_idx)) {
347 return false;
348 }
349 if (_scan_state->claim_iter(region_idx)) {
350 // If we ever free the collection set concurrently, we should also
351 // clear the card table concurrently therefore we won't need to
352 // add regions of the collection set to the dirty cards region.
353 _scan_state->add_dirty_region(region_idx);
354 }
355
356 // We claim cards in blocks so as to reduce the contention.
357 size_t const block_size = G1RSetScanBlockSize;
358
359 HeapRegionRemSetIterator iter(r->rem_set());
360 size_t card_index;
361
362 size_t claimed_card_block = _scan_state->iter_claimed_next(region_idx, block_size);
363 for (size_t current_card = 0; iter.has_next(card_index); current_card++) {
364 if (current_card >= claimed_card_block + block_size) {
365 claimed_card_block = _scan_state->iter_claimed_next(region_idx, block_size);
366 }
367 if (current_card < claimed_card_block) {
368 _cards_skipped++;
380
381 assert(_g1h->region_at(region_idx_for_card)->is_in_reserved(card_start),
382 "Card start " PTR_FORMAT " to scan outside of region %u", p2i(card_start), _g1h->region_at(region_idx_for_card)->hrm_index());
383 HeapWord* const top = _scan_state->scan_top(region_idx_for_card);
384 if (card_start >= top) {
385 continue;
386 }
387
388 // We claim lazily (so races are possible but they're benign), which reduces the
389 // number of duplicate scans (the rsets of the regions in the cset can intersect).
390 // Claim the card after checking bounds above: the remembered set may contain
391 // random cards into current survivor, and we would then have an incorrectly
392 // claimed card in survivor space. Card table clear does not reset the card table
393 // of survivor space regions.
394 claim_card(card_index, region_idx_for_card);
395
396 MemRegion const mr(card_start, MIN2(card_start + BOTConstants::N_words, top));
397
398 scan_card(mr, region_idx_for_card);
399 }
400 if (_scan_state->set_iter_complete(region_idx)) {
401 // Scan the strong code root list attached to the current region
402 scan_strong_code_roots(r);
403 }
404 return false;
405 }
406
407 void G1RemSet::scan_rem_set(G1ParScanThreadState* pss,
408 CodeBlobClosure* heap_region_codeblobs,
409 uint worker_i) {
410 double rs_time_start = os::elapsedTime();
411
412 G1ScanObjsDuringScanRSClosure scan_cl(_g1h, pss);
413 G1ScanRSForRegionClosure cl(_scan_state, &scan_cl, heap_region_codeblobs, worker_i);
414 _g1h->collection_set_iterate_from(&cl, worker_i);
415
416 double scan_rs_time_sec = (os::elapsedTime() - rs_time_start) -
417 cl.strong_code_root_scan_time_sec();
418
419 G1GCPhaseTimes* p = _g1p->phase_times();
420
421 p->record_time_secs(G1GCPhaseTimes::ScanRS, worker_i, scan_rs_time_sec);
422 p->record_thread_work_item(G1GCPhaseTimes::ScanRS, worker_i, cl.cards_scanned(), G1GCPhaseTimes::ScanRSScannedCards);
423 p->record_thread_work_item(G1GCPhaseTimes::ScanRS, worker_i, cl.cards_claimed(), G1GCPhaseTimes::ScanRSClaimedCards);
424 p->record_thread_work_item(G1GCPhaseTimes::ScanRS, worker_i, cl.cards_skipped(), G1GCPhaseTimes::ScanRSSkippedCards);
425
426 p->record_time_secs(G1GCPhaseTimes::CodeRoots, worker_i, cl.strong_code_root_scan_time_sec());
427 }
428
429 // Closure used for updating rem sets. Only called during an evacuation pause.
430 class G1RefineCardClosure: public CardTableEntryClosure {
431 G1RemSet* _g1rs;
432 G1ScanObjsDuringUpdateRSClosure* _update_rs_cl;
433
434 size_t _cards_scanned;
435 size_t _cards_skipped;
436 public:
437 G1RefineCardClosure(G1CollectedHeap* g1h, G1ScanObjsDuringUpdateRSClosure* update_rs_cl) :
438 _g1rs(g1h->g1_rem_set()), _update_rs_cl(update_rs_cl), _cards_scanned(0), _cards_skipped(0)
439 {}
440
441 bool do_card_ptr(jbyte* card_ptr, uint worker_i) {
442 // The only time we care about recording cards that
443 // contain references that point into the collection set
444 // is during RSet updating within an evacuation pause.
445 // In this case worker_i should be the id of a GC worker thread.
446 assert(SafepointSynchronize::is_at_safepoint(), "not during an evacuation pause");
447
448 bool card_scanned = _g1rs->refine_card_during_gc(card_ptr, _update_rs_cl);
449
450 if (card_scanned) {
451 _cards_scanned++;
452 } else {
453 _cards_skipped++;
454 }
455 return true;
456 }
457
458 size_t cards_scanned() const { return _cards_scanned; }
459 size_t cards_skipped() const { return _cards_skipped; }
460 };
461
462 void G1RemSet::update_rem_set(G1ParScanThreadState* pss, uint worker_i) {
463 G1ScanObjsDuringUpdateRSClosure update_rs_cl(_g1h, pss, worker_i);
464 G1RefineCardClosure refine_card_cl(_g1h, &update_rs_cl);
465
466 G1GCParPhaseTimesTracker x(_g1p->phase_times(), G1GCPhaseTimes::UpdateRS, worker_i);
467 if (G1HotCardCache::default_use_cache()) {
468 // Apply the closure to the entries of the hot card cache.
469 G1GCParPhaseTimesTracker y(_g1p->phase_times(), G1GCPhaseTimes::ScanHCC, worker_i);
470 _g1h->iterate_hcc_closure(&refine_card_cl, worker_i);
471 }
472 // Apply the closure to all remaining log entries.
473 _g1h->iterate_dirty_card_closure(&refine_card_cl, worker_i);
474
475 G1GCPhaseTimes* p = _g1p->phase_times();
476 p->record_thread_work_item(G1GCPhaseTimes::UpdateRS, worker_i, refine_card_cl.cards_scanned(), G1GCPhaseTimes::UpdateRSScannedCards);
477 p->record_thread_work_item(G1GCPhaseTimes::UpdateRS, worker_i, refine_card_cl.cards_skipped(), G1GCPhaseTimes::UpdateRSSkippedCards);
478 }
479
480 void G1RemSet::cleanupHRRS() {
481 HeapRegionRemSet::cleanup();
482 }
483
484 void G1RemSet::oops_into_collection_set_do(G1ParScanThreadState* pss,
485 CodeBlobClosure* heap_region_codeblobs,
486 uint worker_i) {
487 update_rem_set(pss, worker_i);
488 scan_rem_set(pss, heap_region_codeblobs, worker_i);;
489 }
490
491 void G1RemSet::prepare_for_oops_into_collection_set_do() {
492 DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set();
493 dcqs.concatenate_logs();
494
495 _scan_state->reset();
496 }
497
498 void G1RemSet::cleanup_after_oops_into_collection_set_do() {
499 G1GCPhaseTimes* phase_times = _g1h->g1_policy()->phase_times();
500
501 // Set all cards back to clean.
502 double start = os::elapsedTime();
503 _scan_state->clear_card_table(_g1h->workers());
504 phase_times->record_clear_ct_time((os::elapsedTime() - start) * 1000.0);
505 }
506
507 inline void check_card_ptr(jbyte* card_ptr, G1CardTable* ct) {
508 #ifdef ASSERT
|
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 */
24
25 #include "precompiled.hpp"
26 #include "gc/g1/dirtyCardQueue.hpp"
27 #include "gc/g1/g1BarrierSet.hpp"
28 #include "gc/g1/g1BlockOffsetTable.inline.hpp"
29 #include "gc/g1/g1CardTable.inline.hpp"
30 #include "gc/g1/g1CollectedHeap.inline.hpp"
31 #include "gc/g1/g1ConcurrentRefine.hpp"
32 #include "gc/g1/g1FromCardCache.hpp"
33 #include "gc/g1/g1GCPhaseTimes.hpp"
34 #include "gc/g1/g1HotCardCache.hpp"
35 #include "gc/g1/g1OopClosures.inline.hpp"
36 #include "gc/g1/g1RootClosures.hpp"
37 #include "gc/g1/g1RemSet.hpp"
38 #include "gc/g1/heapRegion.inline.hpp"
39 #include "gc/g1/heapRegionManager.inline.hpp"
40 #include "gc/g1/heapRegionRemSet.hpp"
41 #include "gc/shared/gcTraceTime.inline.hpp"
42 #include "gc/shared/suspendibleThreadSet.hpp"
43 #include "memory/iterator.hpp"
44 #include "memory/resourceArea.hpp"
45 #include "oops/access.inline.hpp"
46 #include "oops/oop.inline.hpp"
47 #include "utilities/align.hpp"
48 #include "utilities/globalDefinitions.hpp"
49 #include "utilities/intHisto.hpp"
50 #include "utilities/stack.inline.hpp"
51 #include "utilities/ticks.inline.hpp"
52
53 // Collects information about the overall remembered set scan progress during an evacuation.
54 class G1RemSetScanState : public CHeapObj<mtGC> {
55 private:
56 class G1ClearCardTableTask : public AbstractGangTask {
290 _prev_period_summary() {
291 }
292
293 G1RemSet::~G1RemSet() {
294 if (_scan_state != NULL) {
295 delete _scan_state;
296 }
297 }
298
299 uint G1RemSet::num_par_rem_sets() {
300 return DirtyCardQueueSet::num_par_ids() + G1ConcurrentRefine::max_num_threads() + MAX2(ConcGCThreads, ParallelGCThreads);
301 }
302
303 void G1RemSet::initialize(size_t capacity, uint max_regions) {
304 G1FromCardCache::initialize(num_par_rem_sets(), max_regions);
305 _scan_state->initialize(max_regions);
306 }
307
308 G1ScanRSForRegionClosure::G1ScanRSForRegionClosure(G1RemSetScanState* scan_state,
309 G1ScanObjsDuringScanRSClosure* scan_obj_on_card,
310 G1ParScanThreadState* pss,
311 uint worker_i) :
312 _g1h(G1CollectedHeap::heap()),
313 _ct(_g1h->card_table()),
314 _pss(pss),
315 _scan_objs_on_card_cl(scan_obj_on_card),
316 _scan_state(scan_state),
317 _worker_i(worker_i),
318 _cards_claimed(0),
319 _cards_scanned(0),
320 _cards_skipped(0),
321 _rem_set_root_scan_time(),
322 _rem_set_trim_partially_time(),
323 _strong_code_root_scan_time(),
324 _strong_code_trim_partially_time() {
325 }
326
327 void G1ScanRSForRegionClosure::claim_card(size_t card_index, const uint region_idx_for_card){
328 _ct->set_card_claimed(card_index);
329 _scan_state->add_dirty_region(region_idx_for_card);
330 }
331
332 void G1ScanRSForRegionClosure::scan_card(MemRegion mr, uint region_idx_for_card) {
333 HeapRegion* const card_region = _g1h->region_at(region_idx_for_card);
334 _scan_objs_on_card_cl->set_region(card_region);
335 card_region->oops_on_card_seq_iterate_careful<true>(mr, _scan_objs_on_card_cl);
336 _scan_objs_on_card_cl->trim_queue_partially();
337 _cards_scanned++;
338 }
339
340 void G1ScanRSForRegionClosure::scan_rem_set_roots(HeapRegion* r) {
341 uint const region_idx = r->hrm_index();
342
343 if (_scan_state->claim_iter(region_idx)) {
344 // If we ever free the collection set concurrently, we should also
345 // clear the card table concurrently therefore we won't need to
346 // add regions of the collection set to the dirty cards region.
347 _scan_state->add_dirty_region(region_idx);
348 }
349
350 // We claim cards in blocks so as to reduce the contention.
351 size_t const block_size = G1RSetScanBlockSize;
352
353 HeapRegionRemSetIterator iter(r->rem_set());
354 size_t card_index;
355
356 size_t claimed_card_block = _scan_state->iter_claimed_next(region_idx, block_size);
357 for (size_t current_card = 0; iter.has_next(card_index); current_card++) {
358 if (current_card >= claimed_card_block + block_size) {
359 claimed_card_block = _scan_state->iter_claimed_next(region_idx, block_size);
360 }
361 if (current_card < claimed_card_block) {
362 _cards_skipped++;
374
375 assert(_g1h->region_at(region_idx_for_card)->is_in_reserved(card_start),
376 "Card start " PTR_FORMAT " to scan outside of region %u", p2i(card_start), _g1h->region_at(region_idx_for_card)->hrm_index());
377 HeapWord* const top = _scan_state->scan_top(region_idx_for_card);
378 if (card_start >= top) {
379 continue;
380 }
381
382 // We claim lazily (so races are possible but they're benign), which reduces the
383 // number of duplicate scans (the rsets of the regions in the cset can intersect).
384 // Claim the card after checking bounds above: the remembered set may contain
385 // random cards into current survivor, and we would then have an incorrectly
386 // claimed card in survivor space. Card table clear does not reset the card table
387 // of survivor space regions.
388 claim_card(card_index, region_idx_for_card);
389
390 MemRegion const mr(card_start, MIN2(card_start + BOTConstants::N_words, top));
391
392 scan_card(mr, region_idx_for_card);
393 }
394 }
395
396 void G1ScanRSForRegionClosure::scan_strong_code_roots(HeapRegion* r) {
397 r->strong_code_roots_do(_pss->closures()->weak_codeblobs());
398 }
399
400 bool G1ScanRSForRegionClosure::do_heap_region(HeapRegion* r) {
401 assert(r->in_collection_set(),
402 "Should only be called on elements of the collection set but region %u is not.",
403 r->hrm_index());
404 uint const region_idx = r->hrm_index();
405
406 // Do an early out if we know we are complete.
407 if (_scan_state->iter_is_complete(region_idx)) {
408 return false;
409 }
410
411 {
412 G1EvacPhaseWithTrimTimeTracker timer(_pss, _rem_set_root_scan_time, _rem_set_trim_partially_time);
413 scan_rem_set_roots(r);
414 }
415
416 if (_scan_state->set_iter_complete(region_idx)) {
417 G1EvacPhaseWithTrimTimeTracker timer(_pss, _strong_code_root_scan_time, _strong_code_trim_partially_time);
418 // Scan the strong code root list attached to the current region
419 scan_strong_code_roots(r);
420 }
421 return false;
422 }
423
424 void G1RemSet::scan_rem_set(G1ParScanThreadState* pss, uint worker_i) {
425 G1ScanObjsDuringScanRSClosure scan_cl(_g1h, pss);
426 G1ScanRSForRegionClosure cl(_scan_state, &scan_cl, pss, worker_i);
427 _g1h->collection_set_iterate_from(&cl, worker_i);
428
429 G1GCPhaseTimes* p = _g1p->phase_times();
430
431 p->record_time_secs(G1GCPhaseTimes::ScanRS, worker_i, TicksToTimeHelper::seconds(cl.rem_set_root_scan_time()));
432 p->add_time_secs(G1GCPhaseTimes::ObjCopy, worker_i, TicksToTimeHelper::seconds(cl.rem_set_trim_partially_time()));
433
434 p->record_thread_work_item(G1GCPhaseTimes::ScanRS, worker_i, cl.cards_scanned(), G1GCPhaseTimes::ScanRSScannedCards);
435 p->record_thread_work_item(G1GCPhaseTimes::ScanRS, worker_i, cl.cards_claimed(), G1GCPhaseTimes::ScanRSClaimedCards);
436 p->record_thread_work_item(G1GCPhaseTimes::ScanRS, worker_i, cl.cards_skipped(), G1GCPhaseTimes::ScanRSSkippedCards);
437
438 p->record_time_secs(G1GCPhaseTimes::CodeRoots, worker_i, TicksToTimeHelper::seconds(cl.strong_code_root_scan_time()));
439 p->add_time_secs(G1GCPhaseTimes::ObjCopy, worker_i, TicksToTimeHelper::seconds(cl.strong_code_root_trim_partially_time()));
440 }
441
442 // Closure used for updating rem sets. Only called during an evacuation pause.
443 class G1RefineCardClosure: public CardTableEntryClosure {
444 G1RemSet* _g1rs;
445 G1ScanObjsDuringUpdateRSClosure* _update_rs_cl;
446
447 size_t _cards_scanned;
448 size_t _cards_skipped;
449 public:
450 G1RefineCardClosure(G1CollectedHeap* g1h, G1ScanObjsDuringUpdateRSClosure* update_rs_cl) :
451 _g1rs(g1h->g1_rem_set()), _update_rs_cl(update_rs_cl), _cards_scanned(0), _cards_skipped(0)
452 {}
453
454 bool do_card_ptr(jbyte* card_ptr, uint worker_i) {
455 // The only time we care about recording cards that
456 // contain references that point into the collection set
457 // is during RSet updating within an evacuation pause.
458 // In this case worker_i should be the id of a GC worker thread.
459 assert(SafepointSynchronize::is_at_safepoint(), "not during an evacuation pause");
460
461 bool card_scanned = _g1rs->refine_card_during_gc(card_ptr, _update_rs_cl);
462
463 if (card_scanned) {
464 _update_rs_cl->trim_queue_partially();
465 _cards_scanned++;
466 } else {
467 _cards_skipped++;
468 }
469 return true;
470 }
471
472 size_t cards_scanned() const { return _cards_scanned; }
473 size_t cards_skipped() const { return _cards_skipped; }
474 };
475
476 void G1RemSet::update_rem_set(G1ParScanThreadState* pss, uint worker_i) {
477 G1GCPhaseTimes* p = _g1p->phase_times();
478
479 // Apply closure to log entries in the HCC.
480 if (G1HotCardCache::default_use_cache()) {
481 G1EvacPhaseTimesTracker x(p, pss, G1GCPhaseTimes::ScanHCC, worker_i);
482
483 G1ScanObjsDuringUpdateRSClosure scan_hcc_cl(_g1h, pss, worker_i);
484 G1RefineCardClosure refine_card_cl(_g1h, &scan_hcc_cl);
485 _g1h->iterate_hcc_closure(&refine_card_cl, worker_i);
486 }
487
488 // Now apply the closure to all remaining log entries.
489 {
490 G1EvacPhaseTimesTracker x(p, pss, G1GCPhaseTimes::UpdateRS, worker_i);
491
492 G1ScanObjsDuringUpdateRSClosure update_rs_cl(_g1h, pss, worker_i);
493 G1RefineCardClosure refine_card_cl(_g1h, &update_rs_cl);
494 _g1h->iterate_dirty_card_closure(&refine_card_cl, worker_i);
495
496 p->record_thread_work_item(G1GCPhaseTimes::UpdateRS, worker_i, refine_card_cl.cards_scanned(), G1GCPhaseTimes::UpdateRSScannedCards);
497 p->record_thread_work_item(G1GCPhaseTimes::UpdateRS, worker_i, refine_card_cl.cards_skipped(), G1GCPhaseTimes::UpdateRSSkippedCards);
498 }
499 }
500
501 void G1RemSet::cleanupHRRS() {
502 HeapRegionRemSet::cleanup();
503 }
504
505 void G1RemSet::oops_into_collection_set_do(G1ParScanThreadState* pss, uint worker_i) {
506 update_rem_set(pss, worker_i);
507 scan_rem_set(pss, worker_i);;
508 }
509
510 void G1RemSet::prepare_for_oops_into_collection_set_do() {
511 DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set();
512 dcqs.concatenate_logs();
513
514 _scan_state->reset();
515 }
516
517 void G1RemSet::cleanup_after_oops_into_collection_set_do() {
518 G1GCPhaseTimes* phase_times = _g1h->g1_policy()->phase_times();
519
520 // Set all cards back to clean.
521 double start = os::elapsedTime();
522 _scan_state->clear_card_table(_g1h->workers());
523 phase_times->record_clear_ct_time((os::elapsedTime() - start) * 1000.0);
524 }
525
526 inline void check_card_ptr(jbyte* card_ptr, G1CardTable* ct) {
527 #ifdef ASSERT
|