src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp

Print this page
rev 6936 : [mq]: 8057143


 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);