src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp
changeset 59296 9186be5c78ba
parent 59290 97d13893ec3c
equal deleted inserted replaced
59295:8b6cc0bb93d0 59296:9186be5c78ba
  1074   assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Only iterate roots while world is stopped");
  1074   assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Only iterate roots while world is stopped");
  1075   {
  1075   {
  1076     // Include concurrent roots if current cycle can not process those roots concurrently
  1076     // Include concurrent roots if current cycle can not process those roots concurrently
  1077     ShenandoahRootEvacuator rp(workers()->active_workers(),
  1077     ShenandoahRootEvacuator rp(workers()->active_workers(),
  1078                                ShenandoahPhaseTimings::init_evac,
  1078                                ShenandoahPhaseTimings::init_evac,
  1079                                !ShenandoahConcurrentRoots::should_do_concurrent_roots());
  1079                                !ShenandoahConcurrentRoots::should_do_concurrent_roots(),
       
  1080                                !ShenandoahConcurrentRoots::should_do_concurrent_class_unloading());
  1080     ShenandoahEvacuateUpdateRootsTask roots_task(&rp);
  1081     ShenandoahEvacuateUpdateRootsTask roots_task(&rp);
  1081     workers()->run_task(&roots_task);
  1082     workers()->run_task(&roots_task);
  1082   }
  1083   }
  1083 
  1084 
  1084 #if COMPILER2_OR_JVMCI
  1085 #if COMPILER2_OR_JVMCI
  1546       set_evacuation_in_progress(true);
  1547       set_evacuation_in_progress(true);
  1547       // From here on, we need to update references.
  1548       // From here on, we need to update references.
  1548       set_has_forwarded_objects(true);
  1549       set_has_forwarded_objects(true);
  1549 
  1550 
  1550       if (!is_degenerated_gc_in_progress()) {
  1551       if (!is_degenerated_gc_in_progress()) {
       
  1552         prepare_concurrent_roots();
       
  1553         prepare_concurrent_unloading();
  1551         evacuate_and_update_roots();
  1554         evacuate_and_update_roots();
  1552       }
  1555       }
  1553 
  1556 
  1554       if (ShenandoahPacing) {
  1557       if (ShenandoahPacing) {
  1555         pacer()->setup_for_evac();
  1558         pacer()->setup_for_evac();
  1556       }
  1559       }
  1557 
  1560 
  1558       if (ShenandoahVerify) {
  1561       if (ShenandoahVerify) {
       
  1562         ShenandoahRootVerifier::RootTypes types = ShenandoahRootVerifier::None;
  1559         if (ShenandoahConcurrentRoots::should_do_concurrent_roots()) {
  1563         if (ShenandoahConcurrentRoots::should_do_concurrent_roots()) {
  1560           ShenandoahRootVerifier::RootTypes types = ShenandoahRootVerifier::combine(ShenandoahRootVerifier::JNIHandleRoots, ShenandoahRootVerifier::WeakRoots);
  1564           types = ShenandoahRootVerifier::combine(ShenandoahRootVerifier::JNIHandleRoots, ShenandoahRootVerifier::WeakRoots);
  1561           types = ShenandoahRootVerifier::combine(types, ShenandoahRootVerifier::CLDGRoots);
  1565           types = ShenandoahRootVerifier::combine(types, ShenandoahRootVerifier::CLDGRoots);
  1562           verifier()->verify_roots_no_forwarded_except(types);
       
  1563         } else {
       
  1564           verifier()->verify_roots_no_forwarded();
       
  1565         }
  1566         }
       
  1567 
       
  1568         if (ShenandoahConcurrentRoots::should_do_concurrent_class_unloading()) {
       
  1569           types = ShenandoahRootVerifier::combine(types, ShenandoahRootVerifier::CodeRoots);
       
  1570         }
       
  1571         verifier()->verify_roots_no_forwarded_except(types);
  1566         verifier()->verify_during_evacuation();
  1572         verifier()->verify_during_evacuation();
  1567       }
  1573       }
  1568     } else {
  1574     } else {
  1569       if (ShenandoahVerify) {
  1575       if (ShenandoahVerify) {
  1570         verifier()->verify_after_concmark();
  1576         verifier()->verify_after_concmark();
  1656     }
  1662     }
  1657   }
  1663   }
  1658 };
  1664 };
  1659 
  1665 
  1660 void ShenandoahHeap::op_roots() {
  1666 void ShenandoahHeap::op_roots() {
  1661   if (is_evacuation_in_progress() &&
  1667   if (is_evacuation_in_progress()) {
  1662       ShenandoahConcurrentRoots::should_do_concurrent_roots()) {
  1668     if (ShenandoahConcurrentRoots::should_do_concurrent_class_unloading()) {
  1663     ShenandoahConcurrentRootsEvacUpdateTask task;
  1669       _unloader.unload();
  1664     workers()->run_task(&task);
  1670     }
  1665   }
  1671 
       
  1672     if (ShenandoahConcurrentRoots::should_do_concurrent_roots()) {
       
  1673       ShenandoahConcurrentRootsEvacUpdateTask task;
       
  1674       workers()->run_task(&task);
       
  1675     }
       
  1676   }
       
  1677 
       
  1678   set_concurrent_root_in_progress(false);
  1666 }
  1679 }
  1667 
  1680 
  1668 void ShenandoahHeap::op_reset() {
  1681 void ShenandoahHeap::op_reset() {
  1669   reset_mark_bitmap();
  1682   reset_mark_bitmap();
  1670 }
  1683 }
  1918 void ShenandoahHeap::set_evacuation_in_progress(bool in_progress) {
  1931 void ShenandoahHeap::set_evacuation_in_progress(bool in_progress) {
  1919   assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Only call this at safepoint");
  1932   assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Only call this at safepoint");
  1920   set_gc_state_mask(EVACUATION, in_progress);
  1933   set_gc_state_mask(EVACUATION, in_progress);
  1921 }
  1934 }
  1922 
  1935 
       
  1936 void ShenandoahHeap::set_concurrent_root_in_progress(bool in_progress) {
       
  1937   assert(ShenandoahConcurrentRoots::can_do_concurrent_roots(), "Why set the flag?");
       
  1938   if (in_progress) {
       
  1939     _concurrent_root_in_progress.set();
       
  1940   } else {
       
  1941     _concurrent_root_in_progress.unset();
       
  1942   }
       
  1943 }
       
  1944 
  1923 void ShenandoahHeap::ref_processing_init() {
  1945 void ShenandoahHeap::ref_processing_init() {
  1924   assert(_max_workers > 0, "Sanity");
  1946   assert(_max_workers > 0, "Sanity");
  1925 
  1947 
  1926   _ref_processor =
  1948   _ref_processor =
  1927     new ReferenceProcessor(&_subject_to_discovery,  // is_subject_to_discovery
  1949     new ReferenceProcessor(&_subject_to_discovery,  // is_subject_to_discovery
  2026   // Resize and verify metaspace
  2048   // Resize and verify metaspace
  2027   MetaspaceGC::compute_new_size();
  2049   MetaspaceGC::compute_new_size();
  2028   MetaspaceUtils::verify_metrics();
  2050   MetaspaceUtils::verify_metrics();
  2029 }
  2051 }
  2030 
  2052 
  2031 // Process leftover weak oops: update them, if needed or assert they do not
  2053 // Weak roots are either pre-evacuated (final mark) or updated (final updaterefs),
  2032 // need updating otherwise.
  2054 // so they should not have forwarded oops.
  2033 // Weak processor API requires us to visit the oops, even if we are not doing
  2055 // However, we do need to "null" dead oops in the roots, if can not be done
  2034 // anything to them.
  2056 // in concurrent cycles.
  2035 void ShenandoahHeap::stw_process_weak_roots(bool full_gc) {
  2057 void ShenandoahHeap::stw_process_weak_roots(bool full_gc) {
  2036   ShenandoahGCPhase root_phase(full_gc ?
  2058   ShenandoahGCPhase root_phase(full_gc ?
  2037                                ShenandoahPhaseTimings::full_gc_purge :
  2059                                ShenandoahPhaseTimings::full_gc_purge :
  2038                                ShenandoahPhaseTimings::purge);
  2060                                ShenandoahPhaseTimings::purge);
  2039   uint num_workers = _workers->active_workers();
  2061   uint num_workers = _workers->active_workers();
  2071 }
  2093 }
  2072 
  2094 
  2073 void ShenandoahHeap::parallel_cleaning(bool full_gc) {
  2095 void ShenandoahHeap::parallel_cleaning(bool full_gc) {
  2074   assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint");
  2096   assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint");
  2075   stw_process_weak_roots(full_gc);
  2097   stw_process_weak_roots(full_gc);
  2076   stw_unload_classes(full_gc);
  2098   if (!ShenandoahConcurrentRoots::should_do_concurrent_class_unloading()) {
       
  2099     stw_unload_classes(full_gc);
       
  2100   }
  2077 }
  2101 }
  2078 
  2102 
  2079 void ShenandoahHeap::set_has_forwarded_objects(bool cond) {
  2103 void ShenandoahHeap::set_has_forwarded_objects(bool cond) {
  2080   if (is_traversal_mode()) {
  2104   if (is_traversal_mode()) {
  2081     set_gc_state_mask(HAS_FORWARDED | UPDATEREFS, cond);
  2105     set_gc_state_mask(HAS_FORWARDED | UPDATEREFS, cond);
  2139 void ShenandoahHeap::set_update_refs_in_progress(bool in_progress) {
  2163 void ShenandoahHeap::set_update_refs_in_progress(bool in_progress) {
  2140   set_gc_state_mask(UPDATEREFS, in_progress);
  2164   set_gc_state_mask(UPDATEREFS, in_progress);
  2141 }
  2165 }
  2142 
  2166 
  2143 void ShenandoahHeap::register_nmethod(nmethod* nm) {
  2167 void ShenandoahHeap::register_nmethod(nmethod* nm) {
  2144   ShenandoahCodeRoots::add_nmethod(nm);
  2168   ShenandoahCodeRoots::register_nmethod(nm);
  2145 }
  2169 }
  2146 
  2170 
  2147 void ShenandoahHeap::unregister_nmethod(nmethod* nm) {
  2171 void ShenandoahHeap::unregister_nmethod(nmethod* nm) {
  2148   ShenandoahCodeRoots::remove_nmethod(nm);
  2172   ShenandoahCodeRoots::unregister_nmethod(nm);
       
  2173 }
       
  2174 
       
  2175 void ShenandoahHeap::flush_nmethod(nmethod* nm) {
       
  2176   ShenandoahCodeRoots::flush_nmethod(nm);
  2149 }
  2177 }
  2150 
  2178 
  2151 oop ShenandoahHeap::pin_object(JavaThread* thr, oop o) {
  2179 oop ShenandoahHeap::pin_object(JavaThread* thr, oop o) {
  2152   heap_region_containing(o)->record_pin();
  2180   heap_region_containing(o)->record_pin();
  2153   return o;
  2181   return o;
  2188 }
  2216 }
  2189 #endif
  2217 #endif
  2190 
  2218 
  2191 GCTimer* ShenandoahHeap::gc_timer() const {
  2219 GCTimer* ShenandoahHeap::gc_timer() const {
  2192   return _gc_timer;
  2220   return _gc_timer;
       
  2221 }
       
  2222 
       
  2223 void ShenandoahHeap::prepare_concurrent_roots() {
       
  2224   assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint");
       
  2225   if (ShenandoahConcurrentRoots::should_do_concurrent_roots()) {
       
  2226     set_concurrent_root_in_progress(true);
       
  2227   }
       
  2228 }
       
  2229 
       
  2230 void ShenandoahHeap::prepare_concurrent_unloading() {
       
  2231   assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint");
       
  2232   if (ShenandoahConcurrentRoots::should_do_concurrent_class_unloading()) {
       
  2233     ShenandoahCodeRoots::prepare_concurrent_unloading();
       
  2234     _unloader.prepare();
       
  2235   }
       
  2236 }
       
  2237 
       
  2238 void ShenandoahHeap::finish_concurrent_unloading() {
       
  2239   assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint");
       
  2240   if (ShenandoahConcurrentRoots::should_do_concurrent_class_unloading()) {
       
  2241     _unloader.finish();
       
  2242   }
  2193 }
  2243 }
  2194 
  2244 
  2195 #ifdef ASSERT
  2245 #ifdef ASSERT
  2196 void ShenandoahHeap::assert_gc_workers(uint nworkers) {
  2246 void ShenandoahHeap::assert_gc_workers(uint nworkers) {
  2197   assert(nworkers > 0 && nworkers <= max_workers(), "Sanity");
  2247   assert(nworkers > 0 && nworkers <= max_workers(), "Sanity");
  2313 }
  2363 }
  2314 
  2364 
  2315 void ShenandoahHeap::op_final_updaterefs() {
  2365 void ShenandoahHeap::op_final_updaterefs() {
  2316   assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "must be at safepoint");
  2366   assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "must be at safepoint");
  2317 
  2367 
       
  2368   finish_concurrent_unloading();
       
  2369 
  2318   // Check if there is left-over work, and finish it
  2370   // Check if there is left-over work, and finish it
  2319   if (_update_refs_iterator.has_next()) {
  2371   if (_update_refs_iterator.has_next()) {
  2320     ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_update_refs_finish_work);
  2372     ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_update_refs_finish_work);
  2321 
  2373 
  2322     // Finish updating references where we left off.
  2374     // Finish updating references where we left off.
  2330     clear_cancelled_gc();
  2382     clear_cancelled_gc();
  2331   }
  2383   }
  2332   assert(!cancelled_gc(), "Should have been done right before");
  2384   assert(!cancelled_gc(), "Should have been done right before");
  2333 
  2385 
  2334   if (ShenandoahVerify && !is_degenerated_gc_in_progress()) {
  2386   if (ShenandoahVerify && !is_degenerated_gc_in_progress()) {
  2335     verifier()->verify_roots_no_forwarded_except(ShenandoahRootVerifier::ThreadRoots);
  2387     verifier()->verify_roots_in_to_space_except(ShenandoahRootVerifier::ThreadRoots);
  2336   }
  2388   }
  2337 
  2389 
  2338   if (is_degenerated_gc_in_progress()) {
  2390   if (is_degenerated_gc_in_progress()) {
  2339     concurrent_mark()->update_roots(ShenandoahPhaseTimings::degen_gc_update_roots);
  2391     concurrent_mark()->update_roots(ShenandoahPhaseTimings::degen_gc_update_roots);
  2340   } else {
  2392   } else {