src/share/vm/memory/cardTableRS.cpp

Print this page

        

*** 1,7 **** /* ! * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. --- 1,7 ---- /* ! * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.
*** 171,180 **** --- 171,184 ---- assert(!_is_par || (SharedHeap::heap()->n_par_threads() == SharedHeap::heap()->workers()->active_workers()), "Mismatch"); } + bool ClearNoncleanCardWrapper::is_word_aligned(jbyte* entry) { + return (((intptr_t)entry) & (BytesPerWord-1)) == 0; + } + 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());
*** 185,213 **** 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); } // 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) { --- 189,237 ---- 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; + + cur_entry--; } 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 range of clean cards + if (is_word_aligned(cur_entry)) { + jbyte* cur_row = cur_entry - BytesPerWord; + while(cur_row >= limit) { + if (*((intptr_t*)cur_row) == CardTableRS::clean_card_row()) { + cur_row -= BytesPerWord; + } + else { + break; + } + } + cur_entry = cur_row + (BytesPerWord - 1); + HeapWord* last_hw = _ct->addr_for(cur_row + BytesPerWord); + end_of_non_clean = last_hw; + start_of_non_clean = last_hw; + } else { // 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; + cur_entry--; + } } // 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". } // 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) {