src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp
branchdatagramsocketimpl-branch
changeset 58678 9cf78a70fa4f
parent 55029 fc66237d5eae
child 58679 9c3209ff7550
equal deleted inserted replaced
58677:13588c901957 58678:9cf78a70fa4f
    24 #include "precompiled.hpp"
    24 #include "precompiled.hpp"
    25 #include "code/codeCache.hpp"
    25 #include "code/codeCache.hpp"
    26 #include "code/nmethod.hpp"
    26 #include "code/nmethod.hpp"
    27 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
    27 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
    28 #include "gc/shenandoah/shenandoahCodeRoots.hpp"
    28 #include "gc/shenandoah/shenandoahCodeRoots.hpp"
       
    29 #include "gc/shenandoah/shenandoahUtils.hpp"
    29 #include "memory/resourceArea.hpp"
    30 #include "memory/resourceArea.hpp"
    30 #include "memory/universe.hpp"
    31 #include "memory/universe.hpp"
    31 
    32 
    32 ShenandoahParallelCodeCacheIterator::ShenandoahParallelCodeCacheIterator(const GrowableArray<CodeHeap*>* heaps) {
    33 ShenandoahParallelCodeCacheIterator::ShenandoahParallelCodeCacheIterator(const GrowableArray<CodeHeap*>* heaps) {
    33   _length = heaps->length();
    34   _length = heaps->length();
   119     return !_oops.is_empty();
   120     return !_oops.is_empty();
   120   }
   121   }
   121 };
   122 };
   122 
   123 
   123 GrowableArray<ShenandoahNMethod*>* ShenandoahCodeRoots::_recorded_nms;
   124 GrowableArray<ShenandoahNMethod*>* ShenandoahCodeRoots::_recorded_nms;
       
   125 ShenandoahLock                     ShenandoahCodeRoots::_recorded_nms_lock;
   124 
   126 
   125 void ShenandoahCodeRoots::initialize() {
   127 void ShenandoahCodeRoots::initialize() {
   126   _recorded_nms = new (ResourceObj::C_HEAP, mtGC) GrowableArray<ShenandoahNMethod*>(100, true, mtGC);
   128   _recorded_nms = new (ResourceObj::C_HEAP, mtGC) GrowableArray<ShenandoahNMethod*>(100, true, mtGC);
   127 }
   129 }
   128 
   130 
   129 void ShenandoahCodeRoots::add_nmethod(nmethod* nm) {
   131 void ShenandoahCodeRoots::add_nmethod(nmethod* nm) {
   130   assert(CodeCache_lock->owned_by_self(), "Must own CodeCache_lock");
       
   131   switch (ShenandoahCodeRootsStyle) {
   132   switch (ShenandoahCodeRootsStyle) {
   132     case 0:
   133     case 0:
   133     case 1:
   134     case 1:
   134       break;
   135       break;
   135     case 2: {
   136     case 2: {
       
   137       assert_locked_or_safepoint(CodeCache_lock);
       
   138       ShenandoahLocker locker(CodeCache_lock->owned_by_self() ? NULL : &_recorded_nms_lock);
       
   139 
   136       ShenandoahNMethodOopDetector detector;
   140       ShenandoahNMethodOopDetector detector;
   137       nm->oops_do(&detector);
   141       nm->oops_do(&detector);
   138 
   142 
   139       if (detector.has_oops()) {
   143       if (detector.has_oops()) {
   140         ShenandoahNMethod* nmr = new ShenandoahNMethod(nm, detector.oops());
   144         ShenandoahNMethod* nmr = new ShenandoahNMethod(nm, detector.oops());
   154       ShouldNotReachHere();
   158       ShouldNotReachHere();
   155   }
   159   }
   156 };
   160 };
   157 
   161 
   158 void ShenandoahCodeRoots::remove_nmethod(nmethod* nm) {
   162 void ShenandoahCodeRoots::remove_nmethod(nmethod* nm) {
   159   assert(CodeCache_lock->owned_by_self(), "Must own CodeCache_lock");
       
   160   switch (ShenandoahCodeRootsStyle) {
   163   switch (ShenandoahCodeRootsStyle) {
   161     case 0:
   164     case 0:
   162     case 1: {
   165     case 1: {
   163       break;
   166       break;
   164     }
   167     }
   165     case 2: {
   168     case 2: {
       
   169       assert_locked_or_safepoint(CodeCache_lock);
       
   170       ShenandoahLocker locker(CodeCache_lock->owned_by_self() ? NULL : &_recorded_nms_lock);
       
   171 
   166       ShenandoahNMethodOopDetector detector;
   172       ShenandoahNMethodOopDetector detector;
   167       nm->oops_do(&detector, /* allow_zombie = */ true);
   173       nm->oops_do(&detector, /* allow_dead = */ true);
   168 
   174 
   169       if (detector.has_oops()) {
   175       if (detector.has_oops()) {
   170         int idx = _recorded_nms->find(nm, ShenandoahNMethod::find_with_nmethod);
   176         int idx = _recorded_nms->find(nm, ShenandoahNMethod::find_with_nmethod);
   171         assert(idx != -1, "nmethod " PTR_FORMAT " should be registered", p2i(nm));
   177         assert(idx != -1, "nmethod " PTR_FORMAT " should be registered", p2i(nm));
   172         ShenandoahNMethod* old = _recorded_nms->at(idx);
   178         ShenandoahNMethod* old = _recorded_nms->at(idx);
   192     case 1: {
   198     case 1: {
   193       // No need to do anything here
   199       // No need to do anything here
   194       break;
   200       break;
   195     }
   201     }
   196     case 2: {
   202     case 2: {
   197       CodeCache_lock->lock();
   203       CodeCache_lock->lock_without_safepoint_check();
   198       break;
   204       break;
   199     }
   205     }
   200     default:
   206     default:
   201       ShouldNotReachHere();
   207       ShouldNotReachHere();
   202   }
   208   }
   308   ShenandoahHeap* heap = ShenandoahHeap::heap();
   314   ShenandoahHeap* heap = ShenandoahHeap::heap();
   309   for (int c = 0; c < _oops_count; c++) {
   315   for (int c = 0; c < _oops_count; c++) {
   310     oop *loc = _oops[c];
   316     oop *loc = _oops[c];
   311     assert(_nm->code_contains((address) loc) || _nm->oops_contains(loc), "nmethod should contain the oop*");
   317     assert(_nm->code_contains((address) loc) || _nm->oops_contains(loc), "nmethod should contain the oop*");
   312     oop o = RawAccess<>::oop_load(loc);
   318     oop o = RawAccess<>::oop_load(loc);
   313     shenandoah_assert_correct_except(loc, o, o == NULL || heap->is_full_gc_move_in_progress());
   319     shenandoah_assert_correct_except(loc, o,
       
   320              o == NULL ||
       
   321              heap->is_full_gc_move_in_progress() ||
       
   322              (VMThread::vm_operation() != NULL) && (VMThread::vm_operation()->type() == VM_Operation::VMOp_HeapWalkOperation)
       
   323     );
   314   }
   324   }
   315 }
   325 }
   316 
   326 
   317 void ShenandoahNMethod::assert_same_oops(GrowableArray<oop*>* oops) {
   327 void ShenandoahNMethod::assert_same_oops(GrowableArray<oop*>* oops) {
   318   assert(_oops_count == oops->length(), "should have the same number of oop*");
   328   assert(_oops_count == oops->length(), "should have the same number of oop*");