64 * next attempt without processing.
65 *
66 * Late threads would return immediately if iterator is finished.
67 */
68
69 if (_finished) {
70 return;
71 }
72
73 int stride = 256; // educated guess
74 int stride_mask = stride - 1;
75 assert (is_power_of_2(stride), "sanity");
76
77 int count = 0;
78 bool process_block = true;
79
80 for (CodeBlob *cb = CodeCache::first_blob(_heap); cb != NULL; cb = CodeCache::next_blob(_heap, cb)) {
81 int current = count++;
82 if ((current & stride_mask) == 0) {
83 process_block = (current >= _claimed_idx) &&
84 (Atomic::cmpxchg(current + stride, &_claimed_idx, current) == current);
85 }
86 if (process_block) {
87 if (cb->is_alive()) {
88 f->do_code_blob(cb);
89 #ifdef ASSERT
90 if (cb->is_nmethod())
91 Universe::heap()->verify_nmethod((nmethod*)cb);
92 #endif
93 }
94 }
95 }
96
97 _finished = true;
98 }
99
100 class ShenandoahNMethodOopDetector : public OopClosure {
101 private:
102 ResourceMark rm; // For growable array allocation below.
103 GrowableArray<oop*> _oops;
104
247 }
248
249 void ShenandoahAllCodeRootsIterator::possibly_parallel_blobs_do(CodeBlobClosure *f) {
250 ShenandoahCodeRootsIterator::dispatch_parallel_blobs_do<false>(f);
251 }
252
253 void ShenandoahCsetCodeRootsIterator::possibly_parallel_blobs_do(CodeBlobClosure *f) {
254 ShenandoahCodeRootsIterator::dispatch_parallel_blobs_do<true>(f);
255 }
256
257 template <bool CSET_FILTER>
258 void ShenandoahCodeRootsIterator::fast_parallel_blobs_do(CodeBlobClosure *f) {
259 assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint");
260
261 size_t stride = 256; // educated guess
262
263 GrowableArray<ShenandoahNMethod*>* list = ShenandoahCodeRoots::_recorded_nms;
264
265 size_t max = (size_t)list->length();
266 while (_claimed < max) {
267 size_t cur = Atomic::add(stride, &_claimed) - stride;
268 size_t start = cur;
269 size_t end = MIN2(cur + stride, max);
270 if (start >= max) break;
271
272 for (size_t idx = start; idx < end; idx++) {
273 ShenandoahNMethod* nmr = list->at((int) idx);
274 nmr->assert_alive_and_correct();
275
276 if (CSET_FILTER && !nmr->has_cset_oops(_heap)) {
277 continue;
278 }
279
280 f->do_code_blob(nmr->nm());
281 }
282 }
283 }
284
285 ShenandoahNMethod::ShenandoahNMethod(nmethod* nm, GrowableArray<oop*>* oops) {
286 _nm = nm;
287 _oops = NEW_C_HEAP_ARRAY(oop*, oops->length(), mtGC);
|
64 * next attempt without processing.
65 *
66 * Late threads would return immediately if iterator is finished.
67 */
68
69 if (_finished) {
70 return;
71 }
72
73 int stride = 256; // educated guess
74 int stride_mask = stride - 1;
75 assert (is_power_of_2(stride), "sanity");
76
77 int count = 0;
78 bool process_block = true;
79
80 for (CodeBlob *cb = CodeCache::first_blob(_heap); cb != NULL; cb = CodeCache::next_blob(_heap, cb)) {
81 int current = count++;
82 if ((current & stride_mask) == 0) {
83 process_block = (current >= _claimed_idx) &&
84 (Atomic::cmpxchg(&_claimed_idx, current, current + stride) == current);
85 }
86 if (process_block) {
87 if (cb->is_alive()) {
88 f->do_code_blob(cb);
89 #ifdef ASSERT
90 if (cb->is_nmethod())
91 Universe::heap()->verify_nmethod((nmethod*)cb);
92 #endif
93 }
94 }
95 }
96
97 _finished = true;
98 }
99
100 class ShenandoahNMethodOopDetector : public OopClosure {
101 private:
102 ResourceMark rm; // For growable array allocation below.
103 GrowableArray<oop*> _oops;
104
247 }
248
249 void ShenandoahAllCodeRootsIterator::possibly_parallel_blobs_do(CodeBlobClosure *f) {
250 ShenandoahCodeRootsIterator::dispatch_parallel_blobs_do<false>(f);
251 }
252
253 void ShenandoahCsetCodeRootsIterator::possibly_parallel_blobs_do(CodeBlobClosure *f) {
254 ShenandoahCodeRootsIterator::dispatch_parallel_blobs_do<true>(f);
255 }
256
257 template <bool CSET_FILTER>
258 void ShenandoahCodeRootsIterator::fast_parallel_blobs_do(CodeBlobClosure *f) {
259 assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint");
260
261 size_t stride = 256; // educated guess
262
263 GrowableArray<ShenandoahNMethod*>* list = ShenandoahCodeRoots::_recorded_nms;
264
265 size_t max = (size_t)list->length();
266 while (_claimed < max) {
267 size_t cur = Atomic::add(&_claimed, stride) - stride;
268 size_t start = cur;
269 size_t end = MIN2(cur + stride, max);
270 if (start >= max) break;
271
272 for (size_t idx = start; idx < end; idx++) {
273 ShenandoahNMethod* nmr = list->at((int) idx);
274 nmr->assert_alive_and_correct();
275
276 if (CSET_FILTER && !nmr->has_cset_oops(_heap)) {
277 continue;
278 }
279
280 f->do_code_blob(nmr->nm());
281 }
282 }
283 }
284
285 ShenandoahNMethod::ShenandoahNMethod(nmethod* nm, GrowableArray<oop*>* oops) {
286 _nm = nm;
287 _oops = NEW_C_HEAP_ARRAY(oop*, oops->length(), mtGC);
|