src/share/vm/memory/cardTableModRefBS.cpp

changeset 1051
4f360ec815ba
parent 1016
9e5a6ed08fc9
child 1063
7bb995fbd3c0
     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,

mercurial