提交 0847e662 编写于 作者: M mgerdin

8025305: Cleanup CardTableModRefBS usage in G1

Summary: Move some G1 specific code from CardTableModRefBS to G1SATBCardTableModRefBS.
Reviewed-by: brutisso, tschatzl, ehelin
上级 9e25a783
...@@ -81,7 +81,7 @@ inline void ConcurrentMark::count_region(MemRegion mr, HeapRegion* hr, ...@@ -81,7 +81,7 @@ inline void ConcurrentMark::count_region(MemRegion mr, HeapRegion* hr,
size_t* marked_bytes_array, size_t* marked_bytes_array,
BitMap* task_card_bm) { BitMap* task_card_bm) {
G1CollectedHeap* g1h = _g1h; G1CollectedHeap* g1h = _g1h;
CardTableModRefBS* ct_bs = (CardTableModRefBS*) (g1h->barrier_set()); CardTableModRefBS* ct_bs = g1h->g1_barrier_set();
HeapWord* start = mr.start(); HeapWord* start = mr.start();
HeapWord* end = mr.end(); HeapWord* end = mr.end();
......
...@@ -65,9 +65,7 @@ void G1CardCounts::initialize() { ...@@ -65,9 +65,7 @@ void G1CardCounts::initialize() {
// threshold limit is no more than this. // threshold limit is no more than this.
guarantee(G1ConcRSHotCardLimit <= max_jubyte, "sanity"); guarantee(G1ConcRSHotCardLimit <= max_jubyte, "sanity");
ModRefBarrierSet* bs = _g1h->mr_bs(); _ct_bs = _g1h->g1_barrier_set();
guarantee(bs->is_a(BarrierSet::CardTableModRef), "Precondition");
_ct_bs = (CardTableModRefBS*)bs;
_ct_bot = _ct_bs->byte_for_const(_g1h->reserved_region().start()); _ct_bot = _ct_bs->byte_for_const(_g1h->reserved_region().start());
// Allocate/Reserve the counts table // Allocate/Reserve the counts table
......
...@@ -125,10 +125,8 @@ class ClearLoggedCardTableEntryClosure: public CardTableEntryClosure { ...@@ -125,10 +125,8 @@ class ClearLoggedCardTableEntryClosure: public CardTableEntryClosure {
int _histo[256]; int _histo[256];
public: public:
ClearLoggedCardTableEntryClosure() : ClearLoggedCardTableEntryClosure() :
_calls(0) _calls(0), _g1h(G1CollectedHeap::heap()), _ctbs(_g1h->g1_barrier_set())
{ {
_g1h = G1CollectedHeap::heap();
_ctbs = (CardTableModRefBS*)_g1h->barrier_set();
for (int i = 0; i < 256; i++) _histo[i] = 0; for (int i = 0; i < 256; i++) _histo[i] = 0;
} }
bool do_card_ptr(jbyte* card_ptr, int worker_i) { bool do_card_ptr(jbyte* card_ptr, int worker_i) {
...@@ -158,11 +156,8 @@ class RedirtyLoggedCardTableEntryClosure: public CardTableEntryClosure { ...@@ -158,11 +156,8 @@ class RedirtyLoggedCardTableEntryClosure: public CardTableEntryClosure {
CardTableModRefBS* _ctbs; CardTableModRefBS* _ctbs;
public: public:
RedirtyLoggedCardTableEntryClosure() : RedirtyLoggedCardTableEntryClosure() :
_calls(0) _calls(0), _g1h(G1CollectedHeap::heap()), _ctbs(_g1h->g1_barrier_set()) {}
{
_g1h = G1CollectedHeap::heap();
_ctbs = (CardTableModRefBS*)_g1h->barrier_set();
}
bool do_card_ptr(jbyte* card_ptr, int worker_i) { bool do_card_ptr(jbyte* card_ptr, int worker_i) {
if (_g1h->is_in_reserved(_ctbs->addr_for(card_ptr))) { if (_g1h->is_in_reserved(_ctbs->addr_for(card_ptr))) {
_calls++; _calls++;
...@@ -478,7 +473,7 @@ bool G1CollectedHeap::is_scavengable(const void* p) { ...@@ -478,7 +473,7 @@ bool G1CollectedHeap::is_scavengable(const void* p) {
void G1CollectedHeap::check_ct_logs_at_safepoint() { void G1CollectedHeap::check_ct_logs_at_safepoint() {
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
CardTableModRefBS* ct_bs = (CardTableModRefBS*)barrier_set(); CardTableModRefBS* ct_bs = g1_barrier_set();
// Count the dirty cards at the start. // Count the dirty cards at the start.
CountNonCleanMemRegionClosure count1(this); CountNonCleanMemRegionClosure count1(this);
...@@ -1205,7 +1200,7 @@ public: ...@@ -1205,7 +1200,7 @@ public:
}; };
void G1CollectedHeap::clear_rsets_post_compaction() { void G1CollectedHeap::clear_rsets_post_compaction() {
PostMCRemSetClearClosure rs_clear(this, mr_bs()); PostMCRemSetClearClosure rs_clear(this, g1_barrier_set());
heap_region_iterate(&rs_clear); heap_region_iterate(&rs_clear);
} }
...@@ -2045,20 +2040,13 @@ jint G1CollectedHeap::initialize() { ...@@ -2045,20 +2040,13 @@ jint G1CollectedHeap::initialize() {
// Create the gen rem set (and barrier set) for the entire reserved region. // Create the gen rem set (and barrier set) for the entire reserved region.
_rem_set = collector_policy()->create_rem_set(_reserved, 2); _rem_set = collector_policy()->create_rem_set(_reserved, 2);
set_barrier_set(rem_set()->bs()); set_barrier_set(rem_set()->bs());
if (barrier_set()->is_a(BarrierSet::ModRef)) { if (!barrier_set()->is_a(BarrierSet::G1SATBCTLogging)) {
_mr_bs = (ModRefBarrierSet*)_barrier_set; vm_exit_during_initialization("G1 requires a G1SATBLoggingCardTableModRefBS");
} else {
vm_exit_during_initialization("G1 requires a mod ref bs.");
return JNI_ENOMEM; return JNI_ENOMEM;
} }
// Also create a G1 rem set. // Also create a G1 rem set.
if (mr_bs()->is_a(BarrierSet::CardTableModRef)) { _g1_rem_set = new G1RemSet(this, g1_barrier_set());
_g1_rem_set = new G1RemSet(this, (CardTableModRefBS*)mr_bs());
} else {
vm_exit_during_initialization("G1 requires a cardtable mod ref bs.");
return JNI_ENOMEM;
}
// Carve out the G1 part of the heap. // Carve out the G1 part of the heap.
...@@ -4555,7 +4543,7 @@ G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, uint queue_num) ...@@ -4555,7 +4543,7 @@ G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, uint queue_num)
: _g1h(g1h), : _g1h(g1h),
_refs(g1h->task_queue(queue_num)), _refs(g1h->task_queue(queue_num)),
_dcq(&g1h->dirty_card_queue_set()), _dcq(&g1h->dirty_card_queue_set()),
_ct_bs((CardTableModRefBS*)_g1h->barrier_set()), _ct_bs(g1h->g1_barrier_set()),
_g1_rem(g1h->g1_rem_set()), _g1_rem(g1h->g1_rem_set()),
_hash_seed(17), _queue_num(queue_num), _hash_seed(17), _queue_num(queue_num),
_term_attempts(0), _term_attempts(0),
...@@ -5984,11 +5972,11 @@ void G1CollectedHeap::update_sets_after_freeing_regions(size_t pre_used, ...@@ -5984,11 +5972,11 @@ void G1CollectedHeap::update_sets_after_freeing_regions(size_t pre_used,
} }
class G1ParCleanupCTTask : public AbstractGangTask { class G1ParCleanupCTTask : public AbstractGangTask {
CardTableModRefBS* _ct_bs; G1SATBCardTableModRefBS* _ct_bs;
G1CollectedHeap* _g1h; G1CollectedHeap* _g1h;
HeapRegion* volatile _su_head; HeapRegion* volatile _su_head;
public: public:
G1ParCleanupCTTask(CardTableModRefBS* ct_bs, G1ParCleanupCTTask(G1SATBCardTableModRefBS* ct_bs,
G1CollectedHeap* g1h) : G1CollectedHeap* g1h) :
AbstractGangTask("G1 Par Cleanup CT Task"), AbstractGangTask("G1 Par Cleanup CT Task"),
_ct_bs(ct_bs), _g1h(g1h) { } _ct_bs(ct_bs), _g1h(g1h) { }
...@@ -6011,9 +5999,9 @@ public: ...@@ -6011,9 +5999,9 @@ public:
#ifndef PRODUCT #ifndef PRODUCT
class G1VerifyCardTableCleanup: public HeapRegionClosure { class G1VerifyCardTableCleanup: public HeapRegionClosure {
G1CollectedHeap* _g1h; G1CollectedHeap* _g1h;
CardTableModRefBS* _ct_bs; G1SATBCardTableModRefBS* _ct_bs;
public: public:
G1VerifyCardTableCleanup(G1CollectedHeap* g1h, CardTableModRefBS* ct_bs) G1VerifyCardTableCleanup(G1CollectedHeap* g1h, G1SATBCardTableModRefBS* ct_bs)
: _g1h(g1h), _ct_bs(ct_bs) { } : _g1h(g1h), _ct_bs(ct_bs) { }
virtual bool doHeapRegion(HeapRegion* r) { virtual bool doHeapRegion(HeapRegion* r) {
if (r->is_survivor()) { if (r->is_survivor()) {
...@@ -6027,7 +6015,7 @@ public: ...@@ -6027,7 +6015,7 @@ public:
void G1CollectedHeap::verify_not_dirty_region(HeapRegion* hr) { void G1CollectedHeap::verify_not_dirty_region(HeapRegion* hr) {
// All of the region should be clean. // All of the region should be clean.
CardTableModRefBS* ct_bs = (CardTableModRefBS*)barrier_set(); G1SATBCardTableModRefBS* ct_bs = g1_barrier_set();
MemRegion mr(hr->bottom(), hr->end()); MemRegion mr(hr->bottom(), hr->end());
ct_bs->verify_not_dirty_region(mr); ct_bs->verify_not_dirty_region(mr);
} }
...@@ -6040,13 +6028,13 @@ void G1CollectedHeap::verify_dirty_region(HeapRegion* hr) { ...@@ -6040,13 +6028,13 @@ void G1CollectedHeap::verify_dirty_region(HeapRegion* hr) {
// not dirty that area (one less thing to have to do while holding // not dirty that area (one less thing to have to do while holding
// a lock). So we can only verify that [bottom(),pre_dummy_top()] // a lock). So we can only verify that [bottom(),pre_dummy_top()]
// is dirty. // is dirty.
CardTableModRefBS* ct_bs = (CardTableModRefBS*) barrier_set(); G1SATBCardTableModRefBS* ct_bs = g1_barrier_set();
MemRegion mr(hr->bottom(), hr->pre_dummy_top()); MemRegion mr(hr->bottom(), hr->pre_dummy_top());
ct_bs->verify_dirty_region(mr); ct_bs->verify_dirty_region(mr);
} }
void G1CollectedHeap::verify_dirty_young_list(HeapRegion* head) { void G1CollectedHeap::verify_dirty_young_list(HeapRegion* head) {
CardTableModRefBS* ct_bs = (CardTableModRefBS*) barrier_set(); G1SATBCardTableModRefBS* ct_bs = g1_barrier_set();
for (HeapRegion* hr = head; hr != NULL; hr = hr->get_next_young_region()) { for (HeapRegion* hr = head; hr != NULL; hr = hr->get_next_young_region()) {
verify_dirty_region(hr); verify_dirty_region(hr);
} }
...@@ -6058,7 +6046,7 @@ void G1CollectedHeap::verify_dirty_young_regions() { ...@@ -6058,7 +6046,7 @@ void G1CollectedHeap::verify_dirty_young_regions() {
#endif #endif
void G1CollectedHeap::cleanUpCardTable() { void G1CollectedHeap::cleanUpCardTable() {
CardTableModRefBS* ct_bs = (CardTableModRefBS*) (barrier_set()); G1SATBCardTableModRefBS* ct_bs = g1_barrier_set();
double start = os::elapsedTime(); double start = os::elapsedTime();
{ {
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "gc_implementation/g1/g1HRPrinter.hpp" #include "gc_implementation/g1/g1HRPrinter.hpp"
#include "gc_implementation/g1/g1MonitoringSupport.hpp" #include "gc_implementation/g1/g1MonitoringSupport.hpp"
#include "gc_implementation/g1/g1RemSet.hpp" #include "gc_implementation/g1/g1RemSet.hpp"
#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
#include "gc_implementation/g1/g1YCTypes.hpp" #include "gc_implementation/g1/g1YCTypes.hpp"
#include "gc_implementation/g1/heapRegionSeq.hpp" #include "gc_implementation/g1/heapRegionSeq.hpp"
#include "gc_implementation/g1/heapRegionSets.hpp" #include "gc_implementation/g1/heapRegionSets.hpp"
...@@ -791,8 +792,6 @@ protected: ...@@ -791,8 +792,6 @@ protected:
// The g1 remembered set of the heap. // The g1 remembered set of the heap.
G1RemSet* _g1_rem_set; G1RemSet* _g1_rem_set;
// And it's mod ref barrier set, used to track updates for the above.
ModRefBarrierSet* _mr_bs;
// A set of cards that cover the objects for which the Rsets should be updated // A set of cards that cover the objects for which the Rsets should be updated
// concurrently after the collection. // concurrently after the collection.
...@@ -1127,7 +1126,6 @@ public: ...@@ -1127,7 +1126,6 @@ public:
// The rem set and barrier set. // The rem set and barrier set.
G1RemSet* g1_rem_set() const { return _g1_rem_set; } G1RemSet* g1_rem_set() const { return _g1_rem_set; }
ModRefBarrierSet* mr_bs() const { return _mr_bs; }
unsigned get_gc_time_stamp() { unsigned get_gc_time_stamp() {
return _gc_time_stamp; return _gc_time_stamp;
...@@ -1346,6 +1344,10 @@ public: ...@@ -1346,6 +1344,10 @@ public:
virtual bool is_in_closed_subset(const void* p) const; virtual bool is_in_closed_subset(const void* p) const;
G1SATBCardTableModRefBS* g1_barrier_set() {
return (G1SATBCardTableModRefBS*) barrier_set();
}
// This resets the card table to all zeros. It is used after // This resets the card table to all zeros. It is used after
// a collection pause which used the card table to claim cards. // a collection pause which used the card table to claim cards.
void cleanUpCardTable(); void cleanUpCardTable();
...@@ -1875,7 +1877,7 @@ protected: ...@@ -1875,7 +1877,7 @@ protected:
G1CollectedHeap* _g1h; G1CollectedHeap* _g1h;
RefToScanQueue* _refs; RefToScanQueue* _refs;
DirtyCardQueue _dcq; DirtyCardQueue _dcq;
CardTableModRefBS* _ct_bs; G1SATBCardTableModRefBS* _ct_bs;
G1RemSet* _g1_rem; G1RemSet* _g1_rem;
G1ParGCAllocBufferContainer _surviving_alloc_buffer; G1ParGCAllocBufferContainer _surviving_alloc_buffer;
...@@ -1914,7 +1916,7 @@ protected: ...@@ -1914,7 +1916,7 @@ protected:
void add_to_undo_waste(size_t waste) { _undo_waste += waste; } void add_to_undo_waste(size_t waste) { _undo_waste += waste; }
DirtyCardQueue& dirty_card_queue() { return _dcq; } DirtyCardQueue& dirty_card_queue() { return _dcq; }
CardTableModRefBS* ctbs() { return _ct_bs; } G1SATBCardTableModRefBS* ctbs() { return _ct_bs; }
template <class T> void immediate_rs_update(HeapRegion* from, T* p, int tid) { template <class T> void immediate_rs_update(HeapRegion* from, T* p, int tid) {
if (!from->is_survivor()) { if (!from->is_survivor()) {
......
...@@ -134,7 +134,7 @@ G1CollectedHeap::dirty_young_block(HeapWord* start, size_t word_size) { ...@@ -134,7 +134,7 @@ G1CollectedHeap::dirty_young_block(HeapWord* start, size_t word_size) {
assert(containing_hr->is_in(end - 1), "it should also contain end - 1"); assert(containing_hr->is_in(end - 1), "it should also contain end - 1");
MemRegion mr(start, end); MemRegion mr(start, end);
((CardTableModRefBS*)_g1h->barrier_set())->dirty(mr); g1_barrier_set()->dirty(mr);
} }
inline RefToScanQueue* G1CollectedHeap::task_queue(int i) const { inline RefToScanQueue* G1CollectedHeap::task_queue(int i) const {
......
...@@ -41,11 +41,11 @@ class UpdateRSetDeferred : public OopsInHeapRegionClosure { ...@@ -41,11 +41,11 @@ class UpdateRSetDeferred : public OopsInHeapRegionClosure {
private: private:
G1CollectedHeap* _g1; G1CollectedHeap* _g1;
DirtyCardQueue *_dcq; DirtyCardQueue *_dcq;
CardTableModRefBS* _ct_bs; G1SATBCardTableModRefBS* _ct_bs;
public: public:
UpdateRSetDeferred(G1CollectedHeap* g1, DirtyCardQueue* dcq) : UpdateRSetDeferred(G1CollectedHeap* g1, DirtyCardQueue* dcq) :
_g1(g1), _ct_bs((CardTableModRefBS*)_g1->barrier_set()), _dcq(dcq) {} _g1(g1), _ct_bs(_g1->g1_barrier_set()), _dcq(dcq) {}
virtual void do_oop(narrowOop* p) { do_oop_work(p); } virtual void do_oop(narrowOop* p) { do_oop_work(p); }
virtual void do_oop( oop* p) { do_oop_work(p); } virtual void do_oop( oop* p) { do_oop_work(p); }
......
...@@ -220,7 +220,7 @@ class G1PrepareCompactClosure: public HeapRegionClosure { ...@@ -220,7 +220,7 @@ class G1PrepareCompactClosure: public HeapRegionClosure {
public: public:
G1PrepareCompactClosure(CompactibleSpace* cs) G1PrepareCompactClosure(CompactibleSpace* cs)
: _g1h(G1CollectedHeap::heap()), : _g1h(G1CollectedHeap::heap()),
_mrbs(G1CollectedHeap::heap()->mr_bs()), _mrbs(_g1h->g1_barrier_set()),
_cp(NULL, cs, cs->initialize_threshold()), _cp(NULL, cs, cs->initialize_threshold()),
_humongous_proxy_set("G1MarkSweep Humongous Proxy Set") { } _humongous_proxy_set("G1MarkSweep Humongous Proxy Set") { }
......
...@@ -109,7 +109,7 @@ class ScanRSClosure : public HeapRegionClosure { ...@@ -109,7 +109,7 @@ class ScanRSClosure : public HeapRegionClosure {
CodeBlobToOopClosure* _code_root_cl; CodeBlobToOopClosure* _code_root_cl;
G1BlockOffsetSharedArray* _bot_shared; G1BlockOffsetSharedArray* _bot_shared;
CardTableModRefBS *_ct_bs; G1SATBCardTableModRefBS *_ct_bs;
double _strong_code_root_scan_time_sec; double _strong_code_root_scan_time_sec;
int _worker_i; int _worker_i;
...@@ -130,7 +130,7 @@ public: ...@@ -130,7 +130,7 @@ public:
{ {
_g1h = G1CollectedHeap::heap(); _g1h = G1CollectedHeap::heap();
_bot_shared = _g1h->bot_shared(); _bot_shared = _g1h->bot_shared();
_ct_bs = (CardTableModRefBS*) (_g1h->barrier_set()); _ct_bs = _g1h->g1_barrier_set();
_block_size = MAX2<int>(G1RSetScanBlockSize, 1); _block_size = MAX2<int>(G1RSetScanBlockSize, 1);
} }
...@@ -505,12 +505,7 @@ public: ...@@ -505,12 +505,7 @@ public:
ScrubRSClosure(BitMap* region_bm, BitMap* card_bm) : ScrubRSClosure(BitMap* region_bm, BitMap* card_bm) :
_g1h(G1CollectedHeap::heap()), _g1h(G1CollectedHeap::heap()),
_region_bm(region_bm), _card_bm(card_bm), _region_bm(region_bm), _card_bm(card_bm),
_ctbs(NULL) _ctbs(_g1h->g1_barrier_set()) {}
{
ModRefBarrierSet* bs = _g1h->mr_bs();
guarantee(bs->is_a(BarrierSet::CardTableModRef), "Precondition");
_ctbs = (CardTableModRefBS*)bs;
}
bool doHeapRegion(HeapRegion* r) { bool doHeapRegion(HeapRegion* r) {
if (!r->continuesHumongous()) { if (!r->continuesHumongous()) {
......
...@@ -64,6 +64,27 @@ G1SATBCardTableModRefBS::write_ref_array_pre_work(T* dst, int count) { ...@@ -64,6 +64,27 @@ G1SATBCardTableModRefBS::write_ref_array_pre_work(T* dst, int count) {
} }
} }
bool G1SATBCardTableModRefBS::mark_card_deferred(size_t card_index) {
jbyte val = _byte_map[card_index];
// It's already processed
if ((val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val()) {
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()) {
new_val = (jbyte)deferred_card_val();
} else {
if (val & claimed_card_val()) {
new_val = val | (jbyte)deferred_card_val();
}
}
if (new_val != val) {
Atomic::cmpxchg(new_val, &_byte_map[card_index], val);
}
return true;
}
G1SATBCardTableLoggingModRefBS:: G1SATBCardTableLoggingModRefBS::
G1SATBCardTableLoggingModRefBS(MemRegion whole_heap, G1SATBCardTableLoggingModRefBS(MemRegion whole_heap,
int max_covered_regions) : int max_covered_regions) :
......
...@@ -89,6 +89,42 @@ public: ...@@ -89,6 +89,42 @@ public:
write_ref_array_pre_work(dst, count); write_ref_array_pre_work(dst, count);
} }
} }
/*
Claimed and deferred bits are used together in G1 during the evacuation
pause. These bits can have the following state transitions:
1. The claimed bit can be put over any other card state. Except that
the "dirty -> dirty and claimed" transition is checked for in
G1 code and is not used.
2. Deferred bit can be set only if the previous state of the card
was either clean or claimed. mark_card_deferred() is wait-free.
We do not care if the operation is be successful because if
it does not it will only result in duplicate entry in the update
buffer because of the "cache-miss". So it's not worth spinning.
*/
bool is_card_claimed(size_t card_index) {
jbyte val = _byte_map[card_index];
return (val & (clean_card_mask_val() | claimed_card_val())) == claimed_card_val();
}
void set_card_claimed(size_t card_index) {
jbyte val = _byte_map[card_index];
if (val == clean_card_val()) {
val = (jbyte)claimed_card_val();
} else {
val |= (jbyte)claimed_card_val();
}
_byte_map[card_index] = val;
}
bool mark_card_deferred(size_t card_index);
bool is_card_deferred(size_t card_index) {
jbyte val = _byte_map[card_index];
return (val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val();
}
}; };
// Adds card-table logging to the post-barrier. // Adds card-table logging to the post-barrier.
......
...@@ -423,60 +423,6 @@ void CardTableModRefBS::write_ref_field_work(void* field, oop newVal) { ...@@ -423,60 +423,6 @@ void CardTableModRefBS::write_ref_field_work(void* field, oop newVal) {
inline_write_ref_field(field, newVal); inline_write_ref_field(field, newVal);
} }
/*
Claimed and deferred bits are used together in G1 during the evacuation
pause. These bits can have the following state transitions:
1. The claimed bit can be put over any other card state. Except that
the "dirty -> dirty and claimed" transition is checked for in
G1 code and is not used.
2. Deferred bit can be set only if the previous state of the card
was either clean or claimed. mark_card_deferred() is wait-free.
We do not care if the operation is be successful because if
it does not it will only result in duplicate entry in the update
buffer because of the "cache-miss". So it's not worth spinning.
*/
bool CardTableModRefBS::claim_card(size_t card_index) {
jbyte val = _byte_map[card_index];
assert(val != dirty_card_val(), "Shouldn't claim a dirty card");
while (val == clean_card_val() ||
(val & (clean_card_mask_val() | claimed_card_val())) != claimed_card_val()) {
jbyte new_val = val;
if (val == clean_card_val()) {
new_val = (jbyte)claimed_card_val();
} else {
new_val = val | (jbyte)claimed_card_val();
}
jbyte res = Atomic::cmpxchg(new_val, &_byte_map[card_index], val);
if (res == val) {
return true;
}
val = res;
}
return false;
}
bool CardTableModRefBS::mark_card_deferred(size_t card_index) {
jbyte val = _byte_map[card_index];
// It's already processed
if ((val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val()) {
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()) {
new_val = (jbyte)deferred_card_val();
} else {
if (val & claimed_card_val()) {
new_val = val | (jbyte)deferred_card_val();
}
}
if (new_val != val) {
Atomic::cmpxchg(new_val, &_byte_map[card_index], val);
}
return true;
}
void CardTableModRefBS::non_clean_card_iterate_possibly_parallel(Space* sp, void CardTableModRefBS::non_clean_card_iterate_possibly_parallel(Space* sp,
MemRegion mr, MemRegion mr,
......
...@@ -339,34 +339,10 @@ public: ...@@ -339,34 +339,10 @@ public:
_byte_map[card_index] = dirty_card_val(); _byte_map[card_index] = dirty_card_val();
} }
bool is_card_claimed(size_t card_index) {
jbyte val = _byte_map[card_index];
return (val & (clean_card_mask_val() | claimed_card_val())) == claimed_card_val();
}
void set_card_claimed(size_t card_index) {
jbyte val = _byte_map[card_index];
if (val == clean_card_val()) {
val = (jbyte)claimed_card_val();
} else {
val |= (jbyte)claimed_card_val();
}
_byte_map[card_index] = val;
}
bool claim_card(size_t card_index);
bool is_card_clean(size_t card_index) { bool is_card_clean(size_t card_index) {
return _byte_map[card_index] == clean_card_val(); return _byte_map[card_index] == clean_card_val();
} }
bool is_card_deferred(size_t card_index) {
jbyte val = _byte_map[card_index];
return (val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val();
}
bool mark_card_deferred(size_t card_index);
// Card marking array base (adjusted for heap low boundary) // Card marking array base (adjusted for heap low boundary)
// This would be the 0th element of _byte_map, if the heap started at 0x0. // This would be the 0th element of _byte_map, if the heap started at 0x0.
// But since the heap starts at some higher address, this points to somewhere // But since the heap starts at some higher address, this points to somewhere
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册