void ClearNoncleanCardWrapper::do_MemRegion(MemRegion mr) { assert(mr.word_size() > 0, "Error"); assert(_ct->is_aligned(mr.start()), "mr.start() should be card aligned"); // mr.end() may not necessarily be card aligned. jbyte* cur_entry = _ct->byte_for(mr.last()); const jbyte* limit = _ct->byte_for(mr.start()); HeapWord* end_of_non_clean = mr.end(); HeapWord* start_of_non_clean = end_of_non_clean; while (cur_entry >= limit) { HeapWord* cur_hw = _ct->addr_for(cur_entry); if ((*cur_entry != CardTableRS::clean_card_val()) && clear_card(cur_entry)) { // Continue the dirty range by opening the // dirty window one card to the left. start_of_non_clean = cur_hw; } else { // We hit a "clean" card; process any non-empty // "dirty" range accumulated so far. if (start_of_non_clean < end_of_non_clean) { const MemRegion mrd(start_of_non_clean, end_of_non_clean); _dirty_card_closure->do_MemRegion(mrd); } // fast forward through potential continuous whole-word range of clean cards beginning at a word-boundary if (is_word_aligned(cur_entry)) { jbyte* cur_row = cur_entry - BytesPerWord; while (cur_row >= limit && *((intptr_t*)cur_row) == CardTableRS::clean_card_row()) { cur_row -= BytesPerWord; } cur_entry = cur_row + BytesPerWord; cur_hw = _ct->addr_for(cur_entry); } // Reset the dirty window, while continuing to look // for the next dirty card that will start a // new dirty window. end_of_non_clean = cur_hw; start_of_non_clean = cur_hw; } // Note that "cur_entry" leads "start_of_non_clean" in // its leftward excursion after this point // in the loop and, when we hit the left end of "mr", // will point off of the left end of the card-table // for "mr". cur_entry--; } // If the first card of "mr" was dirty, we will have // been left with a dirty window, co-initial with "mr", // which we now process. if (start_of_non_clean < end_of_non_clean) { const MemRegion mrd(start_of_non_clean, end_of_non_clean); _dirty_card_closure->do_MemRegion(mrd); } }
void do_MemRegion(MemRegion mr) { // We start at the high end of "mr", walking backwards // while accumulating a contiguous dirty range of cards in // [start_of_non_clean, end_of_non_clean) which we then // process en masse. HeapWord* end_of_non_clean = mr.end(); HeapWord* start_of_non_clean = end_of_non_clean; jbyte* entry = _ct->byte_for(mr.last()); const jbyte* first_entry = _ct->byte_for(mr.start()); while (entry >= first_entry) { HeapWord* cur = _ct->addr_for(entry); if (!clear_card(entry)) { // We hit a clean card; process any non-empty // dirty range accumulated so far. if (start_of_non_clean < end_of_non_clean) { MemRegion mr2(start_of_non_clean, end_of_non_clean); _dirty_card_closure->do_MemRegion(mr2); } // Reset the dirty window while continuing to // look for the next dirty window to process. end_of_non_clean = cur; start_of_non_clean = end_of_non_clean; } // Open the left end of the window one card to the left. start_of_non_clean = cur; // Note that "entry" leads "start_of_non_clean" in // its leftward excursion after this point // in the loop and, when we hit the left end of "mr", // will point off of the left end of the card-table // for "mr". entry--; } // If the first card of "mr" was dirty, we will have // been left with a dirty window, co-initial with "mr", // which we now process. if (start_of_non_clean < end_of_non_clean) { MemRegion mr2(start_of_non_clean, end_of_non_clean); _dirty_card_closure->do_MemRegion(mr2); } }
void do_MemRegion(MemRegion mr) { HeapWord* end_of_non_clean = mr.end(); HeapWord* start_of_non_clean = end_of_non_clean; jbyte* entry = _ct->byte_for(mr.last()); HeapWord* cur = _ct->addr_for(entry); while (mr.contains(cur)) { jbyte entry_val = *entry; if (!clear_card(entry)) { if (start_of_non_clean < end_of_non_clean) { MemRegion mr2(start_of_non_clean, end_of_non_clean); _dirty_card_closure->do_MemRegion(mr2); } end_of_non_clean = cur; start_of_non_clean = end_of_non_clean; } entry--; start_of_non_clean = cur; cur = _ct->addr_for(entry); } if (start_of_non_clean < end_of_non_clean) { MemRegion mr2(start_of_non_clean, end_of_non_clean); _dirty_card_closure->do_MemRegion(mr2); } }