< prev index next >

src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp

Print this page




  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);


< prev index next >