src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp
changeset 54924 ba1eccda5450
parent 54687 df2b3565f343
child 54928 fe4c2de90b59
equal deleted inserted replaced
54923:23837d614c17 54924:ba1eccda5450
    79 { }
    79 { }
    80 
    80 
    81 template<UpdateRefsMode UPDATE_REFS>
    81 template<UpdateRefsMode UPDATE_REFS>
    82 class ShenandoahInitMarkRootsTask : public AbstractGangTask {
    82 class ShenandoahInitMarkRootsTask : public AbstractGangTask {
    83 private:
    83 private:
    84   ShenandoahRootProcessor* _rp;
    84   ShenandoahRootScanner* _rp;
    85   bool _process_refs;
    85   bool _process_refs;
    86 public:
    86 public:
    87   ShenandoahInitMarkRootsTask(ShenandoahRootProcessor* rp, bool process_refs) :
    87   ShenandoahInitMarkRootsTask(ShenandoahRootScanner* rp, bool process_refs) :
    88     AbstractGangTask("Shenandoah init mark roots task"),
    88     AbstractGangTask("Shenandoah init mark roots task"),
    89     _rp(rp),
    89     _rp(rp),
    90     _process_refs(process_refs) {
    90     _process_refs(process_refs) {
    91   }
    91   }
    92 
    92 
   113     //      class unloading.
   113     //      class unloading.
   114     //   b. With unload_classes = false, we have to nominally retain all the references from code
   114     //   b. With unload_classes = false, we have to nominally retain all the references from code
   115     //      cache, because there could be the case of embedded class/oop in the generated code,
   115     //      cache, because there could be the case of embedded class/oop in the generated code,
   116     //      which we will never visit during mark. Without code cache invalidation, as in (a),
   116     //      which we will never visit during mark. Without code cache invalidation, as in (a),
   117     //      we risk executing that code cache blob, and crashing.
   117     //      we risk executing that code cache blob, and crashing.
   118     //   c. With ShenandoahConcurrentScanCodeRoots, we avoid scanning the entire code cache here,
       
   119     //      and instead do that in concurrent phase under the relevant lock. This saves init mark
       
   120     //      pause time.
       
   121 
       
   122     CLDToOopClosure clds_cl(oops, ClassLoaderData::_claim_strong);
       
   123     MarkingCodeBlobClosure blobs_cl(oops, ! CodeBlobToOopClosure::FixRelocations);
       
   124 
       
   125     ResourceMark m;
       
   126     if (heap->unload_classes()) {
   118     if (heap->unload_classes()) {
   127       _rp->process_strong_roots(oops, &clds_cl, &blobs_cl, NULL, worker_id);
   119       _rp->strong_roots_do(worker_id, oops);
   128     } else {
   120     } else {
   129       if (ShenandoahConcurrentScanCodeRoots) {
   121       _rp->roots_do(worker_id, oops);
   130         CodeBlobClosure* code_blobs = NULL;
       
   131 #ifdef ASSERT
       
   132         ShenandoahAssertToSpaceClosure assert_to_space_oops;
       
   133         CodeBlobToOopClosure assert_to_space(&assert_to_space_oops, !CodeBlobToOopClosure::FixRelocations);
       
   134         // If conc code cache evac is disabled, code cache should have only to-space ptrs.
       
   135         // Otherwise, it should have to-space ptrs only if mark does not update refs.
       
   136         if (!heap->has_forwarded_objects()) {
       
   137           code_blobs = &assert_to_space;
       
   138         }
       
   139 #endif
       
   140         _rp->process_all_roots(oops, &clds_cl, code_blobs, NULL, worker_id);
       
   141       } else {
       
   142         _rp->process_all_roots(oops, &clds_cl, &blobs_cl, NULL, worker_id);
       
   143       }
       
   144     }
   122     }
   145   }
   123   }
   146 };
   124 };
   147 
   125 
   148 class ShenandoahUpdateRootsTask : public AbstractGangTask {
   126 class ShenandoahUpdateRootsTask : public AbstractGangTask {
   149 private:
   127 private:
   150   ShenandoahRootProcessor* _rp;
   128   ShenandoahRootUpdater*  _root_updater;
   151   const bool _update_code_cache;
   129 public:
   152 public:
   130   ShenandoahUpdateRootsTask(ShenandoahRootUpdater* root_updater) :
   153   ShenandoahUpdateRootsTask(ShenandoahRootProcessor* rp, bool update_code_cache) :
       
   154     AbstractGangTask("Shenandoah update roots task"),
   131     AbstractGangTask("Shenandoah update roots task"),
   155     _rp(rp),
   132     _root_updater(root_updater) {
   156     _update_code_cache(update_code_cache) {
       
   157   }
   133   }
   158 
   134 
   159   void work(uint worker_id) {
   135   void work(uint worker_id) {
   160     assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at a safepoint");
   136     assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at a safepoint");
   161     ShenandoahParallelWorkerSession worker_session(worker_id);
   137     ShenandoahParallelWorkerSession worker_session(worker_id);
   162 
   138 
   163     ShenandoahHeap* heap = ShenandoahHeap::heap();
   139     ShenandoahHeap* heap = ShenandoahHeap::heap();
   164     ShenandoahUpdateRefsClosure cl;
   140     ShenandoahUpdateRefsClosure cl;
   165     CLDToOopClosure cldCl(&cl, ClassLoaderData::_claim_strong);
   141     AlwaysTrueClosure always_true;
   166 
   142     _root_updater->roots_do<AlwaysTrueClosure, ShenandoahUpdateRefsClosure>(worker_id, &always_true, &cl);
   167     CodeBlobClosure* code_blobs;
       
   168     CodeBlobToOopClosure update_blobs(&cl, CodeBlobToOopClosure::FixRelocations);
       
   169 #ifdef ASSERT
       
   170     ShenandoahAssertToSpaceClosure assert_to_space_oops;
       
   171     CodeBlobToOopClosure assert_to_space(&assert_to_space_oops, !CodeBlobToOopClosure::FixRelocations);
       
   172 #endif
       
   173     if (_update_code_cache) {
       
   174       code_blobs = &update_blobs;
       
   175     } else {
       
   176       code_blobs =
       
   177         DEBUG_ONLY(&assert_to_space)
       
   178         NOT_DEBUG(NULL);
       
   179     }
       
   180     _rp->update_all_roots<AlwaysTrueClosure>(&cl, &cldCl, code_blobs, NULL, worker_id);
       
   181   }
   143   }
   182 };
   144 };
   183 
   145 
   184 class ShenandoahConcurrentMarkingTask : public AbstractGangTask {
   146 class ShenandoahConcurrentMarkingTask : public AbstractGangTask {
   185 private:
   147 private:
   287   WorkGang* workers = heap->workers();
   249   WorkGang* workers = heap->workers();
   288   uint nworkers = workers->active_workers();
   250   uint nworkers = workers->active_workers();
   289 
   251 
   290   assert(nworkers <= task_queues()->size(), "Just check");
   252   assert(nworkers <= task_queues()->size(), "Just check");
   291 
   253 
   292   ShenandoahRootProcessor root_proc(heap, nworkers, root_phase);
   254   ShenandoahRootScanner root_proc(nworkers, root_phase);
   293   TASKQUEUE_STATS_ONLY(task_queues()->reset_taskqueue_stats());
   255   TASKQUEUE_STATS_ONLY(task_queues()->reset_taskqueue_stats());
   294   task_queues()->reserve(nworkers);
   256   task_queues()->reserve(nworkers);
   295 
   257 
   296   if (heap->has_forwarded_objects()) {
   258   if (heap->has_forwarded_objects()) {
   297     ShenandoahInitMarkRootsTask<RESOLVE> mark_roots(&root_proc, _heap->process_references());
   259     ShenandoahInitMarkRootsTask<RESOLVE> mark_roots(&root_proc, _heap->process_references());
   331   DerivedPointerTable::clear();
   293   DerivedPointerTable::clear();
   332 #endif
   294 #endif
   333 
   295 
   334   uint nworkers = _heap->workers()->active_workers();
   296   uint nworkers = _heap->workers()->active_workers();
   335 
   297 
   336   ShenandoahRootProcessor root_proc(_heap, nworkers, root_phase);
   298   ShenandoahRootUpdater root_updater(nworkers, root_phase, update_code_cache);
   337   ShenandoahUpdateRootsTask update_roots(&root_proc, update_code_cache);
   299   ShenandoahUpdateRootsTask update_roots(&root_updater);
   338   _heap->workers()->run_task(&update_roots);
   300   _heap->workers()->run_task(&update_roots);
   339 
   301 
   340 #if defined(COMPILER2) || INCLUDE_JVMCI
   302 #if defined(COMPILER2) || INCLUDE_JVMCI
   341   DerivedPointerTable::update_pointers();
   303   DerivedPointerTable::update_pointers();
   342 #endif
   304 #endif