31 #include "runtime/mutexLocker.hpp" |
31 #include "runtime/mutexLocker.hpp" |
32 #include "runtime/safepoint.hpp" |
32 #include "runtime/safepoint.hpp" |
33 #include "runtime/thread.hpp" |
33 #include "runtime/thread.hpp" |
34 #include "runtime/vmThread.hpp" |
34 #include "runtime/vmThread.hpp" |
35 |
35 |
|
36 ObjPtrQueue::ObjPtrQueue(SATBMarkQueueSet* qset, bool permanent) : |
|
37 // SATB queues are only active during marking cycles. We create |
|
38 // them with their active field set to false. If a thread is |
|
39 // created during a cycle and its SATB queue needs to be activated |
|
40 // before the thread starts running, we'll need to set its active |
|
41 // field to true. This is done in JavaThread::initialize_queues(). |
|
42 PtrQueue(qset, permanent, false /* active */) |
|
43 { } |
|
44 |
36 void ObjPtrQueue::flush() { |
45 void ObjPtrQueue::flush() { |
37 // Filter now to possibly save work later. If filtering empties the |
46 // Filter now to possibly save work later. If filtering empties the |
38 // buffer then flush_impl can deallocate the buffer. |
47 // buffer then flush_impl can deallocate the buffer. |
39 filter(); |
48 filter(); |
40 flush_impl(); |
49 flush_impl(); |
97 // are compacted toward the top of the buffer. |
106 // are compacted toward the top of the buffer. |
98 |
107 |
99 void ObjPtrQueue::filter() { |
108 void ObjPtrQueue::filter() { |
100 G1CollectedHeap* g1h = G1CollectedHeap::heap(); |
109 G1CollectedHeap* g1h = G1CollectedHeap::heap(); |
101 void** buf = _buf; |
110 void** buf = _buf; |
102 size_t sz = _sz; |
|
103 |
111 |
104 if (buf == NULL) { |
112 if (buf == NULL) { |
105 // nothing to do |
113 // nothing to do |
106 return; |
114 return; |
107 } |
115 } |
108 |
116 |
109 // Used for sanity checking at the end of the loop. |
117 // Used for sanity checking at the end of the loop. |
110 debug_only(size_t entries = 0; size_t retained = 0;) |
118 DEBUG_ONLY(size_t entries = 0; size_t retained = 0;) |
111 |
119 |
112 size_t i = sz; |
120 assert(_index <= _sz, "invariant"); |
113 size_t new_index = sz; |
121 void** limit = &buf[byte_index_to_index(_index)]; |
114 |
122 void** src = &buf[byte_index_to_index(_sz)]; |
115 while (i > _index) { |
123 void** dst = src; |
116 assert(i > 0, "we should have at least one more entry to process"); |
124 |
117 i -= oopSize; |
125 while (limit < src) { |
118 debug_only(entries += 1;) |
126 DEBUG_ONLY(entries += 1;) |
119 void** p = &buf[byte_index_to_index((int) i)]; |
127 --src; |
120 void* entry = *p; |
128 void* entry = *src; |
121 // NULL the entry so that unused parts of the buffer contain NULLs |
129 // NULL the entry so that unused parts of the buffer contain NULLs |
122 // at the end. If we are going to retain it we will copy it to its |
130 // at the end. If we are going to retain it we will copy it to its |
123 // final place. If we have retained all entries we have visited so |
131 // final place. If we have retained all entries we have visited so |
124 // far, we'll just end up copying it to the same place. |
132 // far, we'll just end up copying it to the same place. |
125 *p = NULL; |
133 *src = NULL; |
126 |
134 |
127 if (requires_marking(entry, g1h) && !g1h->isMarkedNext((oop)entry)) { |
135 if (requires_marking(entry, g1h) && !g1h->isMarkedNext((oop)entry)) { |
128 assert(new_index > 0, "we should not have already filled up the buffer"); |
136 --dst; |
129 new_index -= oopSize; |
137 assert(*dst == NULL, "filtering destination should be clear"); |
130 assert(new_index >= i, |
138 *dst = entry; |
131 "new_index should never be below i, as we always compact 'up'"); |
139 DEBUG_ONLY(retained += 1;); |
132 void** new_p = &buf[byte_index_to_index((int) new_index)]; |
140 } |
133 assert(new_p >= p, "the destination location should never be below " |
141 } |
134 "the source as we always compact 'up'"); |
142 size_t new_index = pointer_delta(dst, buf, 1); |
135 assert(*new_p == NULL, |
|
136 "we should have already cleared the destination location"); |
|
137 *new_p = entry; |
|
138 debug_only(retained += 1;) |
|
139 } |
|
140 } |
|
141 |
143 |
142 #ifdef ASSERT |
144 #ifdef ASSERT |
143 size_t entries_calc = (sz - _index) / oopSize; |
145 size_t entries_calc = (_sz - _index) / sizeof(void*); |
144 assert(entries == entries_calc, "the number of entries we counted " |
146 assert(entries == entries_calc, "the number of entries we counted " |
145 "should match the number of entries we calculated"); |
147 "should match the number of entries we calculated"); |
146 size_t retained_calc = (sz - new_index) / oopSize; |
148 size_t retained_calc = (_sz - new_index) / sizeof(void*); |
147 assert(retained == retained_calc, "the number of retained entries we counted " |
149 assert(retained == retained_calc, "the number of retained entries we counted " |
148 "should match the number of retained entries we calculated"); |
150 "should match the number of retained entries we calculated"); |
149 #endif // ASSERT |
151 #endif // ASSERT |
150 |
152 |
151 _index = new_index; |
153 _index = new_index; |
168 assert(_index == 0, "pre-condition"); |
170 assert(_index == 0, "pre-condition"); |
169 assert(_buf != NULL, "pre-condition"); |
171 assert(_buf != NULL, "pre-condition"); |
170 |
172 |
171 filter(); |
173 filter(); |
172 |
174 |
173 size_t sz = _sz; |
175 size_t percent_used = ((_sz - _index) * 100) / _sz; |
174 size_t all_entries = sz / oopSize; |
176 bool should_enqueue = percent_used > G1SATBBufferEnqueueingThresholdPercent; |
175 size_t retained_entries = (sz - _index) / oopSize; |
|
176 size_t perc = retained_entries * 100 / all_entries; |
|
177 bool should_enqueue = perc > (size_t) G1SATBBufferEnqueueingThresholdPercent; |
|
178 return should_enqueue; |
177 return should_enqueue; |
179 } |
178 } |
180 |
179 |
181 void ObjPtrQueue::apply_closure_and_empty(SATBBufferClosure* cl) { |
180 void ObjPtrQueue::apply_closure_and_empty(SATBBufferClosure* cl) { |
182 assert(SafepointSynchronize::is_at_safepoint(), |
181 assert(SafepointSynchronize::is_at_safepoint(), |
183 "SATB queues must only be processed at safepoints"); |
182 "SATB queues must only be processed at safepoints"); |
184 if (_buf != NULL) { |
183 if (_buf != NULL) { |
185 assert(_index % sizeof(void*) == 0, "invariant"); |
184 assert(_index % sizeof(void*) == 0, "invariant"); |
186 assert(_sz % sizeof(void*) == 0, "invariant"); |
185 assert(_sz % sizeof(void*) == 0, "invariant"); |
187 assert(_index <= _sz, "invariant"); |
186 assert(_index <= _sz, "invariant"); |
188 cl->do_buffer(_buf + byte_index_to_index((int)_index), |
187 cl->do_buffer(_buf + byte_index_to_index(_index), |
189 byte_index_to_index((int)(_sz - _index))); |
188 byte_index_to_index(_sz - _index)); |
190 _index = _sz; |
189 _index = _sz; |
191 } |
190 } |
192 } |
191 } |
193 |
192 |
194 #ifndef PRODUCT |
193 #ifndef PRODUCT |
206 } |
205 } |
207 #endif // PRODUCT |
206 #endif // PRODUCT |
208 |
207 |
209 SATBMarkQueueSet::SATBMarkQueueSet() : |
208 SATBMarkQueueSet::SATBMarkQueueSet() : |
210 PtrQueueSet(), |
209 PtrQueueSet(), |
211 _shared_satb_queue(this, true /*perm*/) { } |
210 _shared_satb_queue(this, true /* permanent */) { } |
212 |
211 |
213 void SATBMarkQueueSet::initialize(Monitor* cbl_mon, Mutex* fl_lock, |
212 void SATBMarkQueueSet::initialize(Monitor* cbl_mon, Mutex* fl_lock, |
214 int process_completed_threshold, |
213 int process_completed_threshold, |
215 Mutex* lock) { |
214 Mutex* lock) { |
216 PtrQueueSet::initialize(cbl_mon, fl_lock, process_completed_threshold, -1); |
215 PtrQueueSet::initialize(cbl_mon, fl_lock, process_completed_threshold, -1); |
293 void **buf = BufferNode::make_buffer_from_node(nd); |
292 void **buf = BufferNode::make_buffer_from_node(nd); |
294 // Skip over NULL entries at beginning (e.g. push end) of buffer. |
293 // Skip over NULL entries at beginning (e.g. push end) of buffer. |
295 // Filtering can result in non-full completed buffers; see |
294 // Filtering can result in non-full completed buffers; see |
296 // should_enqueue_buffer. |
295 // should_enqueue_buffer. |
297 assert(_sz % sizeof(void*) == 0, "invariant"); |
296 assert(_sz % sizeof(void*) == 0, "invariant"); |
298 size_t limit = ObjPtrQueue::byte_index_to_index((int)_sz); |
297 size_t limit = ObjPtrQueue::byte_index_to_index(_sz); |
299 for (size_t i = 0; i < limit; ++i) { |
298 for (size_t i = 0; i < limit; ++i) { |
300 if (buf[i] != NULL) { |
299 if (buf[i] != NULL) { |
301 // Found the end of the block of NULLs; process the remainder. |
300 // Found the end of the block of NULLs; process the remainder. |
302 cl->do_buffer(buf + i, limit - i); |
301 cl->do_buffer(buf + i, limit - i); |
303 break; |
302 break; |