< prev index next >

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

Print this page




 445     return;
 446   }
 447 
 448   // Otherwise find a per-region table to add it to.
 449   size_t ind = from_hrm_ind & _mod_max_fine_entries_mask;
 450   PerRegionTable* prt = find_region_table(ind, from_hr);
 451   if (prt == NULL) {
 452     MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag);
 453     // Confirm that it's really not there...
 454     prt = find_region_table(ind, from_hr);
 455     if (prt == NULL) {
 456 
 457       uintptr_t from_hr_bot_card_index =
 458         uintptr_t(from_hr->bottom())
 459           >> CardTableModRefBS::card_shift;
 460       CardIdx_t card_index = from_card - from_hr_bot_card_index;
 461       assert(0 <= card_index && (size_t)card_index < HeapRegion::CardsPerRegion,
 462              "Must be in range.");
 463       if (G1HRRSUseSparseTable &&
 464           _sparse_table.add_card(from_hrm_ind, card_index)) {
 465         if (G1RecordHRRSOops) {
 466           HeapRegionRemSet::record(_hr, from);
 467           if (G1TraceHeapRegionRememberedSet) {
 468             gclog_or_tty->print("   Added card " PTR_FORMAT " to region "
 469                                 "[" PTR_FORMAT "...) for ref " PTR_FORMAT ".\n",
 470                                 align_size_down(uintptr_t(from),
 471                                                 CardTableModRefBS::card_size),
 472                                 p2i(_hr->bottom()), p2i(from));
 473           }
 474         }
 475         if (G1TraceHeapRegionRememberedSet) {
 476           gclog_or_tty->print_cr("   added card to sparse table.");
 477         }
 478         assert(contains_reference_locked(from), "We just added it!");
 479         return;
 480       } else {
 481         if (G1TraceHeapRegionRememberedSet) {
 482           gclog_or_tty->print_cr("   [tid %u] sparse table entry "
 483                         "overflow(f: %d, t: %u)",
 484                         tid, from_hrm_ind, cur_hrm_ind);
 485         }
 486       }
 487 
 488       if (_n_fine_entries == _max_fine_entries) {
 489         prt = delete_region_table();
 490         // There is no need to clear the links to the 'all' list here:
 491         // prt will be reused immediately, i.e. remain in the 'all' list.
 492         prt->init(from_hr, false /* clear_links_to_all_list */);
 493       } else {
 494         prt = PerRegionTable::alloc(from_hr);


 514         assert(sprt_entry != NULL, "There should have been an entry");
 515         for (int i = 0; i < SparsePRTEntry::cards_num(); i++) {
 516           CardIdx_t c = sprt_entry->card(i);
 517           if (c != SparsePRTEntry::NullEntry) {
 518             prt->add_card(c);
 519           }
 520         }
 521         // Now we can delete the sparse entry.
 522         bool res = _sparse_table.delete_entry(from_hrm_ind);
 523         assert(res, "It should have been there.");
 524       }
 525     }
 526     assert(prt != NULL && prt->hr() == from_hr, "consequence");
 527   }
 528   // Note that we can't assert "prt->hr() == from_hr", because of the
 529   // possibility of concurrent reuse.  But see head comment of
 530   // OtherRegionsTable for why this is OK.
 531   assert(prt != NULL, "Inv");
 532 
 533   prt->add_reference(from);
 534 
 535   if (G1RecordHRRSOops) {
 536     HeapRegionRemSet::record(_hr, from);
 537     if (G1TraceHeapRegionRememberedSet) {
 538       gclog_or_tty->print("Added card " PTR_FORMAT " to region "
 539                           "[" PTR_FORMAT "...) for ref " PTR_FORMAT ".\n",
 540                           align_size_down(uintptr_t(from),
 541                                           CardTableModRefBS::card_size),
 542                           p2i(_hr->bottom()), p2i(from));
 543     }
 544   }
 545   assert(contains_reference(from), "We just added it!");
 546 }
 547 
 548 PerRegionTable*
 549 OtherRegionsTable::find_region_table(size_t ind, HeapRegion* hr) const {
 550   assert(ind < _max_fine_entries, "Preconditions.");
 551   PerRegionTable* prt = _fine_grain_regions[ind];
 552   while (prt != NULL && prt->hr() != hr) {
 553     prt = prt->collision_list_next();
 554   }
 555   // Loop postcondition is the method postcondition.
 556   return prt;
 557 }
 558 
 559 jint OtherRegionsTable::_n_coarsenings = 0;
 560 
 561 PerRegionTable* OtherRegionsTable::delete_region_table() {
 562   assert(_m->owned_by_self(), "Precondition");
 563   assert(_n_fine_entries == _max_fine_entries, "Precondition");
 564   PerRegionTable* max = NULL;


1052   case Fine:
1053     if (fine_has_next(card_index)) {
1054       _n_yielded_fine++;
1055       return true;
1056     }
1057     // Otherwise, deliberate fall-through
1058     _is = Coarse;
1059   case Coarse:
1060     if (coarse_has_next(card_index)) {
1061       _n_yielded_coarse++;
1062       return true;
1063     }
1064     // Otherwise...
1065     break;
1066   }
1067   assert(ParallelGCThreads > 1 ||
1068          n_yielded() == _hrrs->occupied(),
1069          "Should have yielded all the cards in the rem set "
1070          "(in the non-par case).");
1071   return false;
1072 }
1073 
1074 
1075 
1076 OopOrNarrowOopStar* HeapRegionRemSet::_recorded_oops = NULL;
1077 HeapWord**          HeapRegionRemSet::_recorded_cards = NULL;
1078 HeapRegion**        HeapRegionRemSet::_recorded_regions = NULL;
1079 int                 HeapRegionRemSet::_n_recorded = 0;
1080 
1081 HeapRegionRemSet::Event* HeapRegionRemSet::_recorded_events = NULL;
1082 int*         HeapRegionRemSet::_recorded_event_index = NULL;
1083 int          HeapRegionRemSet::_n_recorded_events = 0;
1084 
1085 void HeapRegionRemSet::record(HeapRegion* hr, OopOrNarrowOopStar f) {
1086   if (_recorded_oops == NULL) {
1087     assert(_n_recorded == 0
1088            && _recorded_cards == NULL
1089            && _recorded_regions == NULL,
1090            "Inv");
1091     _recorded_oops    = NEW_C_HEAP_ARRAY(OopOrNarrowOopStar, MaxRecorded, mtGC);
1092     _recorded_cards   = NEW_C_HEAP_ARRAY(HeapWord*,          MaxRecorded, mtGC);
1093     _recorded_regions = NEW_C_HEAP_ARRAY(HeapRegion*,        MaxRecorded, mtGC);
1094   }
1095   if (_n_recorded == MaxRecorded) {
1096     gclog_or_tty->print_cr("Filled up 'recorded' (%d).", MaxRecorded);
1097   } else {
1098     _recorded_cards[_n_recorded] =
1099       (HeapWord*)align_size_down(uintptr_t(f),
1100                                  CardTableModRefBS::card_size);
1101     _recorded_oops[_n_recorded] = f;
1102     _recorded_regions[_n_recorded] = hr;
1103     _n_recorded++;
1104   }
1105 }
1106 
1107 void HeapRegionRemSet::record_event(Event evnt) {
1108   if (!G1RecordHRRSEvents) return;
1109 
1110   if (_recorded_events == NULL) {
1111     assert(_n_recorded_events == 0
1112            && _recorded_event_index == NULL,
1113            "Inv");
1114     _recorded_events = NEW_C_HEAP_ARRAY(Event, MaxRecordedEvents, mtGC);
1115     _recorded_event_index = NEW_C_HEAP_ARRAY(int, MaxRecordedEvents, mtGC);
1116   }
1117   if (_n_recorded_events == MaxRecordedEvents) {
1118     gclog_or_tty->print_cr("Filled up 'recorded_events' (%d).", MaxRecordedEvents);
1119   } else {
1120     _recorded_events[_n_recorded_events] = evnt;
1121     _recorded_event_index[_n_recorded_events] = _n_recorded;
1122     _n_recorded_events++;
1123   }
1124 }
1125 
1126 void HeapRegionRemSet::print_event(outputStream* str, Event evnt) {
1127   switch (evnt) {
1128   case Event_EvacStart:
1129     str->print("Evac Start");
1130     break;
1131   case Event_EvacEnd:
1132     str->print("Evac End");
1133     break;
1134   case Event_RSUpdateEnd:
1135     str->print("RS Update End");
1136     break;
1137   }
1138 }
1139 
1140 void HeapRegionRemSet::print_recorded() {
1141   int cur_evnt = 0;
1142   Event cur_evnt_kind = Event_illegal;
1143   int cur_evnt_ind = 0;
1144   if (_n_recorded_events > 0) {
1145     cur_evnt_kind = _recorded_events[cur_evnt];
1146     cur_evnt_ind = _recorded_event_index[cur_evnt];
1147   }
1148 
1149   for (int i = 0; i < _n_recorded; i++) {
1150     while (cur_evnt < _n_recorded_events && i == cur_evnt_ind) {
1151       gclog_or_tty->print("Event: ");
1152       print_event(gclog_or_tty, cur_evnt_kind);
1153       gclog_or_tty->cr();
1154       cur_evnt++;
1155       if (cur_evnt < MaxRecordedEvents) {
1156         cur_evnt_kind = _recorded_events[cur_evnt];
1157         cur_evnt_ind = _recorded_event_index[cur_evnt];
1158       }
1159     }
1160     gclog_or_tty->print("Added card " PTR_FORMAT " to region [" PTR_FORMAT "...]"
1161                         " for ref " PTR_FORMAT ".\n",
1162                         p2i(_recorded_cards[i]), p2i(_recorded_regions[i]->bottom()),
1163                         p2i(_recorded_oops[i]));
1164   }
1165 }
1166 
1167 void HeapRegionRemSet::reset_for_cleanup_tasks() {
1168   SparsePRT::reset_for_cleanup_tasks();
1169 }
1170 
1171 void HeapRegionRemSet::do_cleanup_work(HRRSCleanupTask* hrrs_cleanup_task) {
1172   _other_regions.do_cleanup_work(hrrs_cleanup_task);
1173 }
1174 
1175 void
1176 HeapRegionRemSet::finish_cleanup_task(HRRSCleanupTask* hrrs_cleanup_task) {
1177   SparsePRT::finish_cleanup_task(hrrs_cleanup_task);
1178 }
1179 
1180 #ifndef PRODUCT
1181 void PerRegionTable::test_fl_mem_size() {
1182   PerRegionTable* dummy = alloc(NULL);
1183 
1184   size_t min_prt_size = sizeof(void*) + dummy->bm()->size_in_words() * HeapWordSize;




 445     return;
 446   }
 447 
 448   // Otherwise find a per-region table to add it to.
 449   size_t ind = from_hrm_ind & _mod_max_fine_entries_mask;
 450   PerRegionTable* prt = find_region_table(ind, from_hr);
 451   if (prt == NULL) {
 452     MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag);
 453     // Confirm that it's really not there...
 454     prt = find_region_table(ind, from_hr);
 455     if (prt == NULL) {
 456 
 457       uintptr_t from_hr_bot_card_index =
 458         uintptr_t(from_hr->bottom())
 459           >> CardTableModRefBS::card_shift;
 460       CardIdx_t card_index = from_card - from_hr_bot_card_index;
 461       assert(0 <= card_index && (size_t)card_index < HeapRegion::CardsPerRegion,
 462              "Must be in range.");
 463       if (G1HRRSUseSparseTable &&
 464           _sparse_table.add_card(from_hrm_ind, card_index)) {










 465         if (G1TraceHeapRegionRememberedSet) {
 466           gclog_or_tty->print_cr("   added card to sparse table.");
 467         }
 468         assert(contains_reference_locked(from), "We just added it!");
 469         return;
 470       } else {
 471         if (G1TraceHeapRegionRememberedSet) {
 472           gclog_or_tty->print_cr("   [tid %u] sparse table entry "
 473                         "overflow(f: %d, t: %u)",
 474                         tid, from_hrm_ind, cur_hrm_ind);
 475         }
 476       }
 477 
 478       if (_n_fine_entries == _max_fine_entries) {
 479         prt = delete_region_table();
 480         // There is no need to clear the links to the 'all' list here:
 481         // prt will be reused immediately, i.e. remain in the 'all' list.
 482         prt->init(from_hr, false /* clear_links_to_all_list */);
 483       } else {
 484         prt = PerRegionTable::alloc(from_hr);


 504         assert(sprt_entry != NULL, "There should have been an entry");
 505         for (int i = 0; i < SparsePRTEntry::cards_num(); i++) {
 506           CardIdx_t c = sprt_entry->card(i);
 507           if (c != SparsePRTEntry::NullEntry) {
 508             prt->add_card(c);
 509           }
 510         }
 511         // Now we can delete the sparse entry.
 512         bool res = _sparse_table.delete_entry(from_hrm_ind);
 513         assert(res, "It should have been there.");
 514       }
 515     }
 516     assert(prt != NULL && prt->hr() == from_hr, "consequence");
 517   }
 518   // Note that we can't assert "prt->hr() == from_hr", because of the
 519   // possibility of concurrent reuse.  But see head comment of
 520   // OtherRegionsTable for why this is OK.
 521   assert(prt != NULL, "Inv");
 522 
 523   prt->add_reference(from);











 524   assert(contains_reference(from), "We just added it!");
 525 }
 526 
 527 PerRegionTable*
 528 OtherRegionsTable::find_region_table(size_t ind, HeapRegion* hr) const {
 529   assert(ind < _max_fine_entries, "Preconditions.");
 530   PerRegionTable* prt = _fine_grain_regions[ind];
 531   while (prt != NULL && prt->hr() != hr) {
 532     prt = prt->collision_list_next();
 533   }
 534   // Loop postcondition is the method postcondition.
 535   return prt;
 536 }
 537 
 538 jint OtherRegionsTable::_n_coarsenings = 0;
 539 
 540 PerRegionTable* OtherRegionsTable::delete_region_table() {
 541   assert(_m->owned_by_self(), "Precondition");
 542   assert(_n_fine_entries == _max_fine_entries, "Precondition");
 543   PerRegionTable* max = NULL;


1031   case Fine:
1032     if (fine_has_next(card_index)) {
1033       _n_yielded_fine++;
1034       return true;
1035     }
1036     // Otherwise, deliberate fall-through
1037     _is = Coarse;
1038   case Coarse:
1039     if (coarse_has_next(card_index)) {
1040       _n_yielded_coarse++;
1041       return true;
1042     }
1043     // Otherwise...
1044     break;
1045   }
1046   assert(ParallelGCThreads > 1 ||
1047          n_yielded() == _hrrs->occupied(),
1048          "Should have yielded all the cards in the rem set "
1049          "(in the non-par case).");
1050   return false;





























































































1051 }
1052 
1053 void HeapRegionRemSet::reset_for_cleanup_tasks() {
1054   SparsePRT::reset_for_cleanup_tasks();
1055 }
1056 
1057 void HeapRegionRemSet::do_cleanup_work(HRRSCleanupTask* hrrs_cleanup_task) {
1058   _other_regions.do_cleanup_work(hrrs_cleanup_task);
1059 }
1060 
1061 void
1062 HeapRegionRemSet::finish_cleanup_task(HRRSCleanupTask* hrrs_cleanup_task) {
1063   SparsePRT::finish_cleanup_task(hrrs_cleanup_task);
1064 }
1065 
1066 #ifndef PRODUCT
1067 void PerRegionTable::test_fl_mem_size() {
1068   PerRegionTable* dummy = alloc(NULL);
1069 
1070   size_t min_prt_size = sizeof(void*) + dummy->bm()->size_in_words() * HeapWordSize;


< prev index next >