53 if (cl == NULL) return true;
54 for (size_t i = index; i < sz; i += oopSize) {
55 int ind = byte_index_to_index((int)i);
56 jbyte* card_ptr = (jbyte*)buf[ind];
57 if (card_ptr != NULL) {
58 // Set the entry to null, so we don't do it again (via the test
59 // above) if we reconsider this buffer.
60 if (consume) buf[ind] = NULL;
61 if (!cl->do_card_ptr(card_ptr, worker_i)) return false;
62 }
63 }
64 return true;
65 }
66
67 #ifdef _MSC_VER // the use of 'this' below gets a warning, make it go away
68 #pragma warning( disable:4355 ) // 'this' : used in base member initializer list
69 #endif // _MSC_VER
70
71 DirtyCardQueueSet::DirtyCardQueueSet(bool notify_when_complete) :
72 PtrQueueSet(notify_when_complete),
73 _mut_process_closure(NULL),
74 _shared_dirty_card_queue(this, true /*perm*/),
75 _free_ids(NULL),
76 _processed_buffers_mut(0), _processed_buffers_rs_thread(0)
77 {
78 _all_active = true;
79 }
80
81 // Determines how many mutator threads can process the buffers in parallel.
82 uint DirtyCardQueueSet::num_par_ids() {
83 return (uint)os::processor_count();
84 }
85
86 void DirtyCardQueueSet::initialize(CardTableEntryClosure* cl, Monitor* cbl_mon, Mutex* fl_lock,
87 int process_completed_threshold,
88 int max_completed_queue,
89 Mutex* lock, PtrQueueSet* fl_owner) {
90 _mut_process_closure = cl;
91 PtrQueueSet::initialize(cbl_mon, fl_lock, process_completed_threshold,
92 max_completed_queue, fl_owner);
93 set_buffer_size(G1UpdateBufferSize);
94 _shared_dirty_card_queue.set_lock(lock);
95 _free_ids = new FreeIdSet((int) num_par_ids(), _cbl_mon);
96 }
97
98 void DirtyCardQueueSet::handle_zero_index_for_thread(JavaThread* t) {
99 t->dirty_card_queue().handle_zero_index();
100 }
101
102 void DirtyCardQueueSet::iterate_closure_all_threads(CardTableEntryClosure* cl,
103 bool consume,
104 uint worker_i) {
105 assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
106 for(JavaThread* t = Threads::first(); t; t = t->next()) {
107 bool b = t->dirty_card_queue().apply_closure(cl, consume);
108 guarantee(b, "Should not be interrupted.");
109 }
110 bool b = shared_dirty_card_queue()->apply_closure(cl,
124
125 // We get the the number of any par_id that this thread
126 // might have already claimed.
127 uint worker_i = thread->get_claimed_par_id();
128
129 // If worker_i is not UINT_MAX then the thread has already claimed
130 // a par_id. We make note of it using the already_claimed value
131 if (worker_i != UINT_MAX) {
132 already_claimed = true;
133 } else {
134
135 // Otherwise we need to claim a par id
136 worker_i = _free_ids->claim_par_id();
137
138 // And store the par_id value in the thread
139 thread->set_claimed_par_id(worker_i);
140 }
141
142 bool b = false;
143 if (worker_i != UINT_MAX) {
144 b = DirtyCardQueue::apply_closure_to_buffer(_mut_process_closure, buf, 0,
145 _sz, true, worker_i);
146 if (b) Atomic::inc(&_processed_buffers_mut);
147
148 // If we had not claimed an id before entering the method
149 // then we must release the id.
150 if (!already_claimed) {
151
152 // we release the id
153 _free_ids->release_par_id(worker_i);
154
155 // and set the claimed_id in the thread to UINT_MAX
156 thread->set_claimed_par_id(UINT_MAX);
157 }
158 }
159 return b;
160 }
161
162
163 BufferNode*
164 DirtyCardQueueSet::get_completed_buffer(int stop_at) {
165 BufferNode* nd = NULL;
|
53 if (cl == NULL) return true;
54 for (size_t i = index; i < sz; i += oopSize) {
55 int ind = byte_index_to_index((int)i);
56 jbyte* card_ptr = (jbyte*)buf[ind];
57 if (card_ptr != NULL) {
58 // Set the entry to null, so we don't do it again (via the test
59 // above) if we reconsider this buffer.
60 if (consume) buf[ind] = NULL;
61 if (!cl->do_card_ptr(card_ptr, worker_i)) return false;
62 }
63 }
64 return true;
65 }
66
67 #ifdef _MSC_VER // the use of 'this' below gets a warning, make it go away
68 #pragma warning( disable:4355 ) // 'this' : used in base member initializer list
69 #endif // _MSC_VER
70
71 DirtyCardQueueSet::DirtyCardQueueSet(bool notify_when_complete) :
72 PtrQueueSet(notify_when_complete),
73 _shared_dirty_card_queue(this, true /*perm*/),
74 _free_ids(NULL),
75 _processed_buffers_mut(0), _processed_buffers_rs_thread(0)
76 {
77 _all_active = true;
78 }
79
80 // Determines how many mutator threads can process the buffers in parallel.
81 uint DirtyCardQueueSet::num_par_ids() {
82 return (uint)os::processor_count();
83 }
84
85 void DirtyCardQueueSet::initialize(bool should_do_processing, Monitor* cbl_mon, Mutex* fl_lock,
86 int process_completed_threshold,
87 int max_completed_queue,
88 Mutex* lock, PtrQueueSet* fl_owner) {
89 _should_do_processing = should_do_processing;
90 PtrQueueSet::initialize(cbl_mon, fl_lock, process_completed_threshold,
91 max_completed_queue, fl_owner);
92 set_buffer_size(G1UpdateBufferSize);
93 _shared_dirty_card_queue.set_lock(lock);
94 _free_ids = new FreeIdSet((int) num_par_ids(), _cbl_mon);
95 }
96
97 void DirtyCardQueueSet::handle_zero_index_for_thread(JavaThread* t) {
98 t->dirty_card_queue().handle_zero_index();
99 }
100
101 void DirtyCardQueueSet::iterate_closure_all_threads(CardTableEntryClosure* cl,
102 bool consume,
103 uint worker_i) {
104 assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
105 for(JavaThread* t = Threads::first(); t; t = t->next()) {
106 bool b = t->dirty_card_queue().apply_closure(cl, consume);
107 guarantee(b, "Should not be interrupted.");
108 }
109 bool b = shared_dirty_card_queue()->apply_closure(cl,
123
124 // We get the the number of any par_id that this thread
125 // might have already claimed.
126 uint worker_i = thread->get_claimed_par_id();
127
128 // If worker_i is not UINT_MAX then the thread has already claimed
129 // a par_id. We make note of it using the already_claimed value
130 if (worker_i != UINT_MAX) {
131 already_claimed = true;
132 } else {
133
134 // Otherwise we need to claim a par id
135 worker_i = _free_ids->claim_par_id();
136
137 // And store the par_id value in the thread
138 thread->set_claimed_par_id(worker_i);
139 }
140
141 bool b = false;
142 if (worker_i != UINT_MAX) {
143 BufferedRefineCardTableEntryClosure cl;
144 b = DirtyCardQueue::apply_closure_to_buffer(_should_do_processing ? &cl : NULL, buf, 0,
145 _sz, true, worker_i);
146 cl.flush_buffer();
147 if (b) Atomic::inc(&_processed_buffers_mut);
148
149 // If we had not claimed an id before entering the method
150 // then we must release the id.
151 if (!already_claimed) {
152
153 // we release the id
154 _free_ids->release_par_id(worker_i);
155
156 // and set the claimed_id in the thread to UINT_MAX
157 thread->set_claimed_par_id(UINT_MAX);
158 }
159 }
160 return b;
161 }
162
163
164 BufferNode*
165 DirtyCardQueueSet::get_completed_buffer(int stop_at) {
166 BufferNode* nd = NULL;
|