--- old/src/share/vm/memory/cardTableRS.cpp 2012-02-20 10:33:13.747336500 +0100 +++ new/src/share/vm/memory/cardTableRS.cpp 2012-02-20 10:33:10.284130400 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -173,6 +173,10 @@ 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"); @@ -187,6 +191,8 @@ // 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. @@ -194,18 +200,36 @@ 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; + + // 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". - cur_entry--; } // If the first card of "mr" was dirty, we will have // been left with a dirty window, co-initial with "mr",