1.1 --- a/src/share/vm/memory/cardTableModRefBS.cpp Mon Mar 02 16:37:04 2009 -0800 1.2 +++ b/src/share/vm/memory/cardTableModRefBS.cpp Fri Mar 06 13:50:14 2009 -0800 1.3 @@ -356,18 +356,62 @@ 1.4 inline_write_ref_field(field, newVal); 1.5 } 1.6 1.7 +/* 1.8 + Claimed and deferred bits are used together in G1 during the evacuation 1.9 + pause. These bits can have the following state transitions: 1.10 + 1. The claimed bit can be put over any other card state. Except that 1.11 + the "dirty -> dirty and claimed" transition is checked for in 1.12 + G1 code and is not used. 1.13 + 2. Deferred bit can be set only if the previous state of the card 1.14 + was either clean or claimed. mark_card_deferred() is wait-free. 1.15 + We do not care if the operation is be successful because if 1.16 + it does not it will only result in duplicate entry in the update 1.17 + buffer because of the "cache-miss". So it's not worth spinning. 1.18 + */ 1.19 + 1.20 1.21 bool CardTableModRefBS::claim_card(size_t card_index) { 1.22 jbyte val = _byte_map[card_index]; 1.23 - if (val != claimed_card_val()) { 1.24 - jbyte res = Atomic::cmpxchg((jbyte) claimed_card_val(), &_byte_map[card_index], val); 1.25 - if (res == val) 1.26 + assert(val != dirty_card_val(), "Shouldn't claim a dirty card"); 1.27 + while (val == clean_card_val() || 1.28 + (val & (clean_card_mask_val() | claimed_card_val())) != claimed_card_val()) { 1.29 + jbyte new_val = val; 1.30 + if (val == clean_card_val()) { 1.31 + new_val = (jbyte)claimed_card_val(); 1.32 + } else { 1.33 + new_val = val | (jbyte)claimed_card_val(); 1.34 + } 1.35 + jbyte res = Atomic::cmpxchg(new_val, &_byte_map[card_index], val); 1.36 + if (res == val) { 1.37 return true; 1.38 - else return false; 1.39 + } 1.40 + val = res; 1.41 } 1.42 return false; 1.43 } 1.44 1.45 +bool CardTableModRefBS::mark_card_deferred(size_t card_index) { 1.46 + jbyte val = _byte_map[card_index]; 1.47 + // It's already processed 1.48 + if ((val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val()) { 1.49 + return false; 1.50 + } 1.51 + // Cached bit can be installed either on a clean card or on a claimed card. 1.52 + jbyte new_val = val; 1.53 + if (val == clean_card_val()) { 1.54 + new_val = (jbyte)deferred_card_val(); 1.55 + } else { 1.56 + if (val & claimed_card_val()) { 1.57 + new_val = val | (jbyte)deferred_card_val(); 1.58 + } 1.59 + } 1.60 + if (new_val != val) { 1.61 + Atomic::cmpxchg(new_val, &_byte_map[card_index], val); 1.62 + } 1.63 + return true; 1.64 +} 1.65 + 1.66 + 1.67 void CardTableModRefBS::non_clean_card_iterate(Space* sp, 1.68 MemRegion mr, 1.69 DirtyCardToOopClosure* dcto_cl,