src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp
changeset 54338 7a34a3270270
parent 54223 8478c8c48886
child 54344 8cd2af66ac7c
equal deleted inserted replaced
54337:5a9d780eb9dd 54338:7a34a3270270
   118     //      and instead do that in concurrent phase under the relevant lock. This saves init mark
   118     //      and instead do that in concurrent phase under the relevant lock. This saves init mark
   119     //      pause time.
   119     //      pause time.
   120 
   120 
   121     CLDToOopClosure clds_cl(oops, ClassLoaderData::_claim_strong);
   121     CLDToOopClosure clds_cl(oops, ClassLoaderData::_claim_strong);
   122     MarkingCodeBlobClosure blobs_cl(oops, ! CodeBlobToOopClosure::FixRelocations);
   122     MarkingCodeBlobClosure blobs_cl(oops, ! CodeBlobToOopClosure::FixRelocations);
   123     OopClosure* weak_oops = _process_refs ? NULL : oops;
       
   124 
   123 
   125     ResourceMark m;
   124     ResourceMark m;
   126     if (heap->unload_classes()) {
   125     if (heap->unload_classes()) {
   127       _rp->process_strong_roots(oops, weak_oops, &clds_cl, NULL, &blobs_cl, NULL, worker_id);
   126       _rp->process_strong_roots(oops, &clds_cl, NULL, &blobs_cl, NULL, worker_id);
   128     } else {
   127     } else {
   129       if (ShenandoahConcurrentScanCodeRoots) {
   128       if (ShenandoahConcurrentScanCodeRoots) {
   130         CodeBlobClosure* code_blobs = NULL;
   129         CodeBlobClosure* code_blobs = NULL;
   131 #ifdef ASSERT
   130 #ifdef ASSERT
   132         ShenandoahAssertToSpaceClosure assert_to_space_oops;
   131         ShenandoahAssertToSpaceClosure assert_to_space_oops;
   135         // Otherwise, it should have to-space ptrs only if mark does not update refs.
   134         // Otherwise, it should have to-space ptrs only if mark does not update refs.
   136         if (!heap->has_forwarded_objects()) {
   135         if (!heap->has_forwarded_objects()) {
   137           code_blobs = &assert_to_space;
   136           code_blobs = &assert_to_space;
   138         }
   137         }
   139 #endif
   138 #endif
   140         _rp->process_all_roots(oops, weak_oops, &clds_cl, code_blobs, NULL, worker_id);
   139         _rp->process_all_roots(oops, &clds_cl, code_blobs, NULL, worker_id);
   141       } else {
   140       } else {
   142         _rp->process_all_roots(oops, weak_oops, &clds_cl, &blobs_cl, NULL, worker_id);
   141         _rp->process_all_roots(oops, &clds_cl, &blobs_cl, NULL, worker_id);
   143       }
   142       }
   144     }
   143     }
   145   }
   144   }
   146 };
   145 };
   147 
   146 
   175     } else {
   174     } else {
   176       code_blobs =
   175       code_blobs =
   177         DEBUG_ONLY(&assert_to_space)
   176         DEBUG_ONLY(&assert_to_space)
   178         NOT_DEBUG(NULL);
   177         NOT_DEBUG(NULL);
   179     }
   178     }
   180     _rp->process_all_roots(&cl, &cl, &cldCl, code_blobs, NULL, worker_id);
   179     _rp->update_all_roots(&cl, &cldCl, code_blobs, NULL, worker_id);
   181   }
   180   }
   182 };
   181 };
   183 
   182 
   184 class ShenandoahConcurrentMarkingTask : public AbstractGangTask {
   183 class ShenandoahConcurrentMarkingTask : public AbstractGangTask {
   185 private:
   184 private:
   444   // When we're done marking everything, we process weak references.
   443   // When we're done marking everything, we process weak references.
   445   if (_heap->process_references()) {
   444   if (_heap->process_references()) {
   446     weak_refs_work(full_gc);
   445     weak_refs_work(full_gc);
   447   }
   446   }
   448 
   447 
       
   448   weak_roots_work();
       
   449 
   449   // And finally finish class unloading
   450   // And finally finish class unloading
   450   if (_heap->unload_classes()) {
   451   if (_heap->unload_classes()) {
   451     _heap->unload_classes_and_cleanup_tables(full_gc);
   452     _heap->unload_classes_and_cleanup_tables(full_gc);
   452   }
   453   } else if (ShenandoahStringDedup::is_enabled()) {
   453 
   454     ShenandoahIsAliveSelector alive;
       
   455     BoolObjectClosure* is_alive = alive.is_alive_closure();
       
   456     ShenandoahStringDedup::unlink_or_oops_do(is_alive, NULL, false);
       
   457   }
   454   assert(task_queues()->is_empty(), "Should be empty");
   458   assert(task_queues()->is_empty(), "Should be empty");
   455   TASKQUEUE_STATS_ONLY(task_queues()->print_taskqueue_stats());
   459   TASKQUEUE_STATS_ONLY(task_queues()->print_taskqueue_stats());
   456   TASKQUEUE_STATS_ONLY(task_queues()->reset_taskqueue_stats());
   460   TASKQUEUE_STATS_ONLY(task_queues()->reset_taskqueue_stats());
   457 
   461 
   458   // Resize Metaspace
   462   // Resize Metaspace
   553 
   557 
   554 class ShenandoahWeakAssertNotForwardedClosure : public OopClosure {
   558 class ShenandoahWeakAssertNotForwardedClosure : public OopClosure {
   555 private:
   559 private:
   556   template <class T>
   560   template <class T>
   557   inline void do_oop_work(T* p) {
   561   inline void do_oop_work(T* p) {
       
   562 #ifdef ASSERT
   558     T o = RawAccess<>::oop_load(p);
   563     T o = RawAccess<>::oop_load(p);
   559     if (!CompressedOops::is_null(o)) {
   564     if (!CompressedOops::is_null(o)) {
   560       oop obj = CompressedOops::decode_not_null(o);
   565       oop obj = CompressedOops::decode_not_null(o);
   561       shenandoah_assert_not_forwarded(p, obj);
   566       shenandoah_assert_not_forwarded(p, obj);
   562     }
   567     }
       
   568 #endif
   563   }
   569   }
   564 
   570 
   565 public:
   571 public:
   566   ShenandoahWeakAssertNotForwardedClosure() {}
   572   ShenandoahWeakAssertNotForwardedClosure() {}
   567 
   573 
   646   rp->verify_no_references_recorded();
   652   rp->verify_no_references_recorded();
   647   assert(!rp->discovery_enabled(), "Post condition");
   653   assert(!rp->discovery_enabled(), "Post condition");
   648 
   654 
   649 }
   655 }
   650 
   656 
       
   657 // Process leftover weak oops: update them, if needed or assert they do not
       
   658 // need updating otherwise.
       
   659 // Weak processor API requires us to visit the oops, even if we are not doing
       
   660 // anything to them.
       
   661 void ShenandoahConcurrentMark::weak_roots_work() {
       
   662   WorkGang* workers = _heap->workers();
       
   663   ShenandoahIsAliveSelector is_alive;
       
   664 
       
   665   if (_heap->has_forwarded_objects()) {
       
   666     ShenandoahWeakUpdateClosure cl;
       
   667     WeakProcessor::weak_oops_do(workers, is_alive.is_alive_closure(), &cl, 1);
       
   668   } else {
       
   669     ShenandoahWeakAssertNotForwardedClosure cl;
       
   670     WeakProcessor::weak_oops_do(workers, is_alive.is_alive_closure(), &cl, 1);
       
   671   }
       
   672 }
       
   673 
   651 void ShenandoahConcurrentMark::weak_refs_work_doit(bool full_gc) {
   674 void ShenandoahConcurrentMark::weak_refs_work_doit(bool full_gc) {
   652   ReferenceProcessor* rp = _heap->ref_processor();
   675   ReferenceProcessor* rp = _heap->ref_processor();
   653 
   676 
   654   ShenandoahPhaseTimings::Phase phase_process =
   677   ShenandoahPhaseTimings::Phase phase_process =
   655           full_gc ?
   678           full_gc ?
   687 
   710 
   688   {
   711   {
   689     ShenandoahGCPhase phase(phase_process);
   712     ShenandoahGCPhase phase(phase_process);
   690     ShenandoahTerminationTracker phase_term(phase_process_termination);
   713     ShenandoahTerminationTracker phase_term(phase_process_termination);
   691 
   714 
   692     // Process leftover weak oops: update them, if needed (using parallel version),
       
   693     // or assert they do not need updating (using serial version) otherwise.
       
   694     // Weak processor API requires us to visit the oops, even if we are not doing
       
   695     // anything to them.
       
   696     if (_heap->has_forwarded_objects()) {
   715     if (_heap->has_forwarded_objects()) {
   697       ShenandoahCMKeepAliveUpdateClosure keep_alive(get_queue(serial_worker_id));
   716       ShenandoahCMKeepAliveUpdateClosure keep_alive(get_queue(serial_worker_id));
   698       rp->process_discovered_references(is_alive.is_alive_closure(), &keep_alive,
   717       rp->process_discovered_references(is_alive.is_alive_closure(), &keep_alive,
   699                                         &complete_gc, &executor,
   718                                         &complete_gc, &executor,
   700                                         &pt);
   719                                         &pt);
   701 
   720 
   702       ShenandoahWeakUpdateClosure cl;
       
   703       WeakProcessor::weak_oops_do(workers, is_alive.is_alive_closure(), &cl, 1);
       
   704     } else {
   721     } else {
   705       ShenandoahCMKeepAliveClosure keep_alive(get_queue(serial_worker_id));
   722       ShenandoahCMKeepAliveClosure keep_alive(get_queue(serial_worker_id));
   706       rp->process_discovered_references(is_alive.is_alive_closure(), &keep_alive,
   723       rp->process_discovered_references(is_alive.is_alive_closure(), &keep_alive,
   707                                         &complete_gc, &executor,
   724                                         &complete_gc, &executor,
   708                                         &pt);
   725                                         &pt);
   709 
   726 
   710       ShenandoahWeakAssertNotForwardedClosure cl;
       
   711       WeakProcessor::weak_oops_do(is_alive.is_alive_closure(), &cl);
       
   712     }
   727     }
   713 
   728 
   714     pt.print_all_references();
   729     pt.print_all_references();
   715 
   730 
   716     assert(task_queues()->is_empty(), "Should be empty");
   731     assert(task_queues()->is_empty(), "Should be empty");