108 if (!is_permanent()) {
109 flush();
110 }
111 }
112
113 bool DirtyCardQueue::apply_closure(CardTableEntryClosure* cl,
114 bool consume,
115 uint worker_i) {
116 bool res = true;
117 if (_buf != NULL) {
118 BufferNode* node = BufferNode::make_node_from_buffer(_buf, _index);
119 res = apply_closure_to_buffer(cl, node, _sz, consume, worker_i);
120 if (res && consume) {
121 _index = _sz;
122 }
123 }
124 return res;
125 }
126
127 bool DirtyCardQueue::apply_closure_to_buffer(CardTableEntryClosure* cl,
128 BufferNode* node, size_t sz,
129 bool consume,
130 uint worker_i) {
131 if (cl == NULL) return true;
132 void** buf = BufferNode::make_buffer_from_node(node);
133 size_t limit = byte_index_to_index(sz);
134 for (size_t i = byte_index_to_index(node->index()); i < limit; ++i) {
135 jbyte* card_ptr = static_cast<jbyte*>(buf[i]);
136 assert(card_ptr != NULL, "invariant");
137 if (!cl->do_card_ptr(card_ptr, worker_i)) {
138 if (consume) {
139 size_t new_index = index_to_byte_index(i + 1);
140 assert(new_index <= sz, "invariant");
141 node->set_index(new_index);
142 }
143 return false;
144 }
145 }
146 if (consume) {
147 node->set_index(sz);
148 }
149 return true;
150 }
151
152 DirtyCardQueueSet::DirtyCardQueueSet(bool notify_when_complete) :
153 PtrQueueSet(notify_when_complete),
154 _mut_process_closure(NULL),
155 _shared_dirty_card_queue(this, true /* permanent */),
156 _free_ids(NULL),
157 _processed_buffers_mut(0), _processed_buffers_rs_thread(0)
158 {
159 _all_active = true;
160 }
161
162 // Determines how many mutator threads can process the buffers in parallel.
163 uint DirtyCardQueueSet::num_par_ids() {
164 return (uint)os::processor_count();
165 }
166
167 void DirtyCardQueueSet::initialize(CardTableEntryClosure* cl,
|
108 if (!is_permanent()) {
109 flush();
110 }
111 }
112
113 bool DirtyCardQueue::apply_closure(CardTableEntryClosure* cl,
114 bool consume,
115 uint worker_i) {
116 bool res = true;
117 if (_buf != NULL) {
118 BufferNode* node = BufferNode::make_node_from_buffer(_buf, _index);
119 res = apply_closure_to_buffer(cl, node, _sz, consume, worker_i);
120 if (res && consume) {
121 _index = _sz;
122 }
123 }
124 return res;
125 }
126
127 bool DirtyCardQueue::apply_closure_to_buffer(CardTableEntryClosure* cl,
128 BufferNode* node,
129 size_t buffer_size,
130 bool consume,
131 uint worker_i) {
132 if (cl == NULL) return true;
133 void** buf = BufferNode::make_buffer_from_node(node);
134 size_t limit = byte_index_to_index(buffer_size);
135 for (size_t i = byte_index_to_index(node->index()); i < limit; ++i) {
136 jbyte* card_ptr = static_cast<jbyte*>(buf[i]);
137 assert(card_ptr != NULL, "invariant");
138 if (!cl->do_card_ptr(card_ptr, worker_i)) {
139 if (consume) {
140 size_t new_index = index_to_byte_index(i + 1);
141 assert(new_index <= buffer_size, "invariant");
142 node->set_index(new_index);
143 }
144 return false;
145 }
146 }
147 if (consume) {
148 node->set_index(buffer_size);
149 }
150 return true;
151 }
152
153 DirtyCardQueueSet::DirtyCardQueueSet(bool notify_when_complete) :
154 PtrQueueSet(notify_when_complete),
155 _mut_process_closure(NULL),
156 _shared_dirty_card_queue(this, true /* permanent */),
157 _free_ids(NULL),
158 _processed_buffers_mut(0), _processed_buffers_rs_thread(0)
159 {
160 _all_active = true;
161 }
162
163 // Determines how many mutator threads can process the buffers in parallel.
164 uint DirtyCardQueueSet::num_par_ids() {
165 return (uint)os::processor_count();
166 }
167
168 void DirtyCardQueueSet::initialize(CardTableEntryClosure* cl,
|