421 |
421 |
422 void CardTableModRefBS::write_ref_field_work(void* field, oop newVal) { |
422 void CardTableModRefBS::write_ref_field_work(void* field, oop newVal) { |
423 inline_write_ref_field(field, newVal); |
423 inline_write_ref_field(field, newVal); |
424 } |
424 } |
425 |
425 |
426 /* |
|
427 Claimed and deferred bits are used together in G1 during the evacuation |
|
428 pause. These bits can have the following state transitions: |
|
429 1. The claimed bit can be put over any other card state. Except that |
|
430 the "dirty -> dirty and claimed" transition is checked for in |
|
431 G1 code and is not used. |
|
432 2. Deferred bit can be set only if the previous state of the card |
|
433 was either clean or claimed. mark_card_deferred() is wait-free. |
|
434 We do not care if the operation is be successful because if |
|
435 it does not it will only result in duplicate entry in the update |
|
436 buffer because of the "cache-miss". So it's not worth spinning. |
|
437 */ |
|
438 |
|
439 |
|
440 bool CardTableModRefBS::claim_card(size_t card_index) { |
|
441 jbyte val = _byte_map[card_index]; |
|
442 assert(val != dirty_card_val(), "Shouldn't claim a dirty card"); |
|
443 while (val == clean_card_val() || |
|
444 (val & (clean_card_mask_val() | claimed_card_val())) != claimed_card_val()) { |
|
445 jbyte new_val = val; |
|
446 if (val == clean_card_val()) { |
|
447 new_val = (jbyte)claimed_card_val(); |
|
448 } else { |
|
449 new_val = val | (jbyte)claimed_card_val(); |
|
450 } |
|
451 jbyte res = Atomic::cmpxchg(new_val, &_byte_map[card_index], val); |
|
452 if (res == val) { |
|
453 return true; |
|
454 } |
|
455 val = res; |
|
456 } |
|
457 return false; |
|
458 } |
|
459 |
|
460 bool CardTableModRefBS::mark_card_deferred(size_t card_index) { |
|
461 jbyte val = _byte_map[card_index]; |
|
462 // It's already processed |
|
463 if ((val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val()) { |
|
464 return false; |
|
465 } |
|
466 // Cached bit can be installed either on a clean card or on a claimed card. |
|
467 jbyte new_val = val; |
|
468 if (val == clean_card_val()) { |
|
469 new_val = (jbyte)deferred_card_val(); |
|
470 } else { |
|
471 if (val & claimed_card_val()) { |
|
472 new_val = val | (jbyte)deferred_card_val(); |
|
473 } |
|
474 } |
|
475 if (new_val != val) { |
|
476 Atomic::cmpxchg(new_val, &_byte_map[card_index], val); |
|
477 } |
|
478 return true; |
|
479 } |
|
480 |
426 |
481 void CardTableModRefBS::non_clean_card_iterate_possibly_parallel(Space* sp, |
427 void CardTableModRefBS::non_clean_card_iterate_possibly_parallel(Space* sp, |
482 MemRegion mr, |
428 MemRegion mr, |
483 OopsInGenClosure* cl, |
429 OopsInGenClosure* cl, |
484 CardTableRS* ct) { |
430 CardTableRS* ct) { |