diff -r 9def9d6d969a -r 45a89fbcd8f7 hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp Fri Oct 04 13:33:02 2013 +0200 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp Tue Oct 08 17:35:51 2013 +0200 @@ -70,6 +70,12 @@ if ((val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val()) { return false; } + + if (val == g1_young_gen) { + // the card is for a young gen region. We don't need to keep track of all pointers into young + return false; + } + // Cached bit can be installed either on a clean card or on a claimed card. jbyte new_val = val; if (val == clean_card_val()) { @@ -85,6 +91,19 @@ return true; } +void G1SATBCardTableModRefBS::g1_mark_as_young(const MemRegion& mr) { + jbyte *const first = byte_for(mr.start()); + jbyte *const last = byte_after(mr.last()); + + memset(first, g1_young_gen, last - first); +} + +#ifndef PRODUCT +void G1SATBCardTableModRefBS::verify_g1_young_region(MemRegion mr) { + verify_region(mr, g1_young_gen, true); +} +#endif + G1SATBCardTableLoggingModRefBS:: G1SATBCardTableLoggingModRefBS(MemRegion whole_heap, int max_covered_regions) : @@ -97,7 +116,11 @@ void G1SATBCardTableLoggingModRefBS::write_ref_field_work(void* field, oop new_val) { - jbyte* byte = byte_for(field); + volatile jbyte* byte = byte_for(field); + if (*byte == g1_young_gen) { + return; + } + OrderAccess::storeload(); if (*byte != dirty_card) { *byte = dirty_card; Thread* thr = Thread::current(); @@ -129,7 +152,7 @@ void G1SATBCardTableLoggingModRefBS::invalidate(MemRegion mr, bool whole_heap) { - jbyte* byte = byte_for(mr.start()); + volatile jbyte* byte = byte_for(mr.start()); jbyte* last_byte = byte_for(mr.last()); Thread* thr = Thread::current(); if (whole_heap) { @@ -138,25 +161,35 @@ byte++; } } else { - // Enqueue if necessary. - if (thr->is_Java_thread()) { - JavaThread* jt = (JavaThread*)thr; - while (byte <= last_byte) { - if (*byte != dirty_card) { - *byte = dirty_card; - jt->dirty_card_queue().enqueue(byte); + // skip all consecutive young cards + for (; byte <= last_byte && *byte == g1_young_gen; byte++); + + if (byte <= last_byte) { + OrderAccess::storeload(); + // Enqueue if necessary. + if (thr->is_Java_thread()) { + JavaThread* jt = (JavaThread*)thr; + for (; byte <= last_byte; byte++) { + if (*byte == g1_young_gen) { + continue; + } + if (*byte != dirty_card) { + *byte = dirty_card; + jt->dirty_card_queue().enqueue(byte); + } } - byte++; - } - } else { - MutexLockerEx x(Shared_DirtyCardQ_lock, - Mutex::_no_safepoint_check_flag); - while (byte <= last_byte) { - if (*byte != dirty_card) { - *byte = dirty_card; - _dcqs.shared_dirty_card_queue()->enqueue(byte); + } else { + MutexLockerEx x(Shared_DirtyCardQ_lock, + Mutex::_no_safepoint_check_flag); + for (; byte <= last_byte; byte++) { + if (*byte == g1_young_gen) { + continue; + } + if (*byte != dirty_card) { + *byte = dirty_card; + _dcqs.shared_dirty_card_queue()->enqueue(byte); + } } - byte++; } } }