431 }
432
433 int from_card = (int)(uintptr_t(from) >> CardTableModRefBS::card_shift);
434
435 if (G1TraceHeapRegionRememberedSet) {
436 gclog_or_tty->print_cr("Table for [" PTR_FORMAT "...): card %d (cache = %d)",
437 hr()->bottom(), from_card,
438 FromCardCache::at((uint)tid, cur_hrm_ind));
439 }
440
441 if (FromCardCache::contains_or_replace((uint)tid, cur_hrm_ind, from_card)) {
442 if (G1TraceHeapRegionRememberedSet) {
443 gclog_or_tty->print_cr(" from-card cache hit.");
444 }
445 assert(contains_reference(from), "We just added it!");
446 return;
447 }
448
449 // Note that this may be a continued H region.
450 HeapRegion* from_hr = _g1h->heap_region_containing_raw(from);
451 RegionIdx_t from_hrs_ind = (RegionIdx_t) from_hr->hrm_index();
452
453 // If the region is already coarsened, return.
454 if (_coarse_map.at(from_hrs_ind)) {
455 if (G1TraceHeapRegionRememberedSet) {
456 gclog_or_tty->print_cr(" coarse map hit.");
457 }
458 assert(contains_reference(from), "We just added it!");
459 return;
460 }
461
462 // Otherwise find a per-region table to add it to.
463 size_t ind = from_hrs_ind & _mod_max_fine_entries_mask;
464 PerRegionTable* prt = find_region_table(ind, from_hr);
465 if (prt == NULL) {
466 MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag);
467 // Confirm that it's really not there...
468 prt = find_region_table(ind, from_hr);
469 if (prt == NULL) {
470
471 uintptr_t from_hr_bot_card_index =
472 uintptr_t(from_hr->bottom())
473 >> CardTableModRefBS::card_shift;
474 CardIdx_t card_index = from_card - from_hr_bot_card_index;
475 assert(0 <= card_index && (size_t)card_index < HeapRegion::CardsPerRegion,
476 "Must be in range.");
477 if (G1HRRSUseSparseTable &&
478 _sparse_table.add_card(from_hrs_ind, card_index)) {
479 if (G1RecordHRRSOops) {
480 HeapRegionRemSet::record(hr(), from);
481 if (G1TraceHeapRegionRememberedSet) {
482 gclog_or_tty->print(" Added card " PTR_FORMAT " to region "
483 "[" PTR_FORMAT "...) for ref " PTR_FORMAT ".\n",
484 align_size_down(uintptr_t(from),
485 CardTableModRefBS::card_size),
486 hr()->bottom(), from);
487 }
488 }
489 if (G1TraceHeapRegionRememberedSet) {
490 gclog_or_tty->print_cr(" added card to sparse table.");
491 }
492 assert(contains_reference_locked(from), "We just added it!");
493 return;
494 } else {
495 if (G1TraceHeapRegionRememberedSet) {
496 gclog_or_tty->print_cr(" [tid %d] sparse table entry "
497 "overflow(f: %d, t: %u)",
498 tid, from_hrs_ind, cur_hrm_ind);
499 }
500 }
501
502 if (_n_fine_entries == _max_fine_entries) {
503 prt = delete_region_table();
504 // There is no need to clear the links to the 'all' list here:
505 // prt will be reused immediately, i.e. remain in the 'all' list.
506 prt->init(from_hr, false /* clear_links_to_all_list */);
507 } else {
508 prt = PerRegionTable::alloc(from_hr);
509 link_to_all(prt);
510 }
511
512 PerRegionTable* first_prt = _fine_grain_regions[ind];
513 prt->set_collision_list_next(first_prt);
514 _fine_grain_regions[ind] = prt;
515 _n_fine_entries++;
516
517 if (G1HRRSUseSparseTable) {
518 // Transfer from sparse to fine-grain.
519 SparsePRTEntry *sprt_entry = _sparse_table.get_entry(from_hrs_ind);
520 assert(sprt_entry != NULL, "There should have been an entry");
521 for (int i = 0; i < SparsePRTEntry::cards_num(); i++) {
522 CardIdx_t c = sprt_entry->card(i);
523 if (c != SparsePRTEntry::NullEntry) {
524 prt->add_card(c);
525 }
526 }
527 // Now we can delete the sparse entry.
528 bool res = _sparse_table.delete_entry(from_hrs_ind);
529 assert(res, "It should have been there.");
530 }
531 }
532 assert(prt != NULL && prt->hr() == from_hr, "consequence");
533 }
534 // Note that we can't assert "prt->hr() == from_hr", because of the
535 // possibility of concurrent reuse. But see head comment of
536 // OtherRegionsTable for why this is OK.
537 assert(prt != NULL, "Inv");
538
539 prt->add_reference(from);
540
541 if (G1RecordHRRSOops) {
542 HeapRegionRemSet::record(hr(), from);
543 if (G1TraceHeapRegionRememberedSet) {
544 gclog_or_tty->print("Added card " PTR_FORMAT " to region "
545 "[" PTR_FORMAT "...) for ref " PTR_FORMAT ".\n",
546 align_size_down(uintptr_t(from),
547 CardTableModRefBS::card_size),
548 hr()->bottom(), from);
|
431 }
432
433 int from_card = (int)(uintptr_t(from) >> CardTableModRefBS::card_shift);
434
435 if (G1TraceHeapRegionRememberedSet) {
436 gclog_or_tty->print_cr("Table for [" PTR_FORMAT "...): card %d (cache = %d)",
437 hr()->bottom(), from_card,
438 FromCardCache::at((uint)tid, cur_hrm_ind));
439 }
440
441 if (FromCardCache::contains_or_replace((uint)tid, cur_hrm_ind, from_card)) {
442 if (G1TraceHeapRegionRememberedSet) {
443 gclog_or_tty->print_cr(" from-card cache hit.");
444 }
445 assert(contains_reference(from), "We just added it!");
446 return;
447 }
448
449 // Note that this may be a continued H region.
450 HeapRegion* from_hr = _g1h->heap_region_containing_raw(from);
451 RegionIdx_t from_hrm_ind = (RegionIdx_t) from_hr->hrm_index();
452
453 // If the region is already coarsened, return.
454 if (_coarse_map.at(from_hrm_ind)) {
455 if (G1TraceHeapRegionRememberedSet) {
456 gclog_or_tty->print_cr(" coarse map hit.");
457 }
458 assert(contains_reference(from), "We just added it!");
459 return;
460 }
461
462 // Otherwise find a per-region table to add it to.
463 size_t ind = from_hrm_ind & _mod_max_fine_entries_mask;
464 PerRegionTable* prt = find_region_table(ind, from_hr);
465 if (prt == NULL) {
466 MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag);
467 // Confirm that it's really not there...
468 prt = find_region_table(ind, from_hr);
469 if (prt == NULL) {
470
471 uintptr_t from_hr_bot_card_index =
472 uintptr_t(from_hr->bottom())
473 >> CardTableModRefBS::card_shift;
474 CardIdx_t card_index = from_card - from_hr_bot_card_index;
475 assert(0 <= card_index && (size_t)card_index < HeapRegion::CardsPerRegion,
476 "Must be in range.");
477 if (G1HRRSUseSparseTable &&
478 _sparse_table.add_card(from_hrm_ind, card_index)) {
479 if (G1RecordHRRSOops) {
480 HeapRegionRemSet::record(hr(), from);
481 if (G1TraceHeapRegionRememberedSet) {
482 gclog_or_tty->print(" Added card " PTR_FORMAT " to region "
483 "[" PTR_FORMAT "...) for ref " PTR_FORMAT ".\n",
484 align_size_down(uintptr_t(from),
485 CardTableModRefBS::card_size),
486 hr()->bottom(), from);
487 }
488 }
489 if (G1TraceHeapRegionRememberedSet) {
490 gclog_or_tty->print_cr(" added card to sparse table.");
491 }
492 assert(contains_reference_locked(from), "We just added it!");
493 return;
494 } else {
495 if (G1TraceHeapRegionRememberedSet) {
496 gclog_or_tty->print_cr(" [tid %d] sparse table entry "
497 "overflow(f: %d, t: %u)",
498 tid, from_hrm_ind, cur_hrm_ind);
499 }
500 }
501
502 if (_n_fine_entries == _max_fine_entries) {
503 prt = delete_region_table();
504 // There is no need to clear the links to the 'all' list here:
505 // prt will be reused immediately, i.e. remain in the 'all' list.
506 prt->init(from_hr, false /* clear_links_to_all_list */);
507 } else {
508 prt = PerRegionTable::alloc(from_hr);
509 link_to_all(prt);
510 }
511
512 PerRegionTable* first_prt = _fine_grain_regions[ind];
513 prt->set_collision_list_next(first_prt);
514 _fine_grain_regions[ind] = prt;
515 _n_fine_entries++;
516
517 if (G1HRRSUseSparseTable) {
518 // Transfer from sparse to fine-grain.
519 SparsePRTEntry *sprt_entry = _sparse_table.get_entry(from_hrm_ind);
520 assert(sprt_entry != NULL, "There should have been an entry");
521 for (int i = 0; i < SparsePRTEntry::cards_num(); i++) {
522 CardIdx_t c = sprt_entry->card(i);
523 if (c != SparsePRTEntry::NullEntry) {
524 prt->add_card(c);
525 }
526 }
527 // Now we can delete the sparse entry.
528 bool res = _sparse_table.delete_entry(from_hrm_ind);
529 assert(res, "It should have been there.");
530 }
531 }
532 assert(prt != NULL && prt->hr() == from_hr, "consequence");
533 }
534 // Note that we can't assert "prt->hr() == from_hr", because of the
535 // possibility of concurrent reuse. But see head comment of
536 // OtherRegionsTable for why this is OK.
537 assert(prt != NULL, "Inv");
538
539 prt->add_reference(from);
540
541 if (G1RecordHRRSOops) {
542 HeapRegionRemSet::record(hr(), from);
543 if (G1TraceHeapRegionRememberedSet) {
544 gclog_or_tty->print("Added card " PTR_FORMAT " to region "
545 "[" PTR_FORMAT "...) for ref " PTR_FORMAT ".\n",
546 align_size_down(uintptr_t(from),
547 CardTableModRefBS::card_size),
548 hr()->bottom(), from);
|