< prev index next >

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

Print this page
rev 57380 : 8234974: Shenandoah: Do concurrent roots even when no evacuation is necessary


 525 void ShenandoahHeap::print_on(outputStream* st) const {
 526   st->print_cr("Shenandoah Heap");
 527   st->print_cr(" " SIZE_FORMAT "%s total, " SIZE_FORMAT "%s committed, " SIZE_FORMAT "%s used",
 528                byte_size_in_proper_unit(max_capacity()), proper_unit_for_byte_size(max_capacity()),
 529                byte_size_in_proper_unit(committed()),    proper_unit_for_byte_size(committed()),
 530                byte_size_in_proper_unit(used()),         proper_unit_for_byte_size(used()));
 531   st->print_cr(" " SIZE_FORMAT " x " SIZE_FORMAT"%s regions",
 532                num_regions(),
 533                byte_size_in_proper_unit(ShenandoahHeapRegion::region_size_bytes()),
 534                proper_unit_for_byte_size(ShenandoahHeapRegion::region_size_bytes()));
 535 
 536   st->print("Status: ");
 537   if (has_forwarded_objects())               st->print("has forwarded objects, ");
 538   if (is_concurrent_mark_in_progress())      st->print("marking, ");
 539   if (is_evacuation_in_progress())           st->print("evacuating, ");
 540   if (is_update_refs_in_progress())          st->print("updating refs, ");
 541   if (is_concurrent_traversal_in_progress()) st->print("traversal, ");
 542   if (is_degenerated_gc_in_progress())       st->print("degenerated gc, ");
 543   if (is_full_gc_in_progress())              st->print("full gc, ");
 544   if (is_full_gc_move_in_progress())         st->print("full gc move, ");

 545 
 546   if (cancelled_gc()) {
 547     st->print("cancelled");
 548   } else {
 549     st->print("not cancelled");
 550   }
 551   st->cr();
 552 
 553   st->print_cr("Reserved region:");
 554   st->print_cr(" - [" PTR_FORMAT ", " PTR_FORMAT ") ",
 555                p2i(reserved_region().start()),
 556                p2i(reserved_region().end()));
 557 
 558   ShenandoahCollectionSet* cset = collection_set();
 559   st->print_cr("Collection set:");
 560   if (cset != NULL) {
 561     st->print_cr(" - map (vanilla): " PTR_FORMAT, p2i(cset->map_address()));
 562     st->print_cr(" - map (biased):  " PTR_FORMAT, p2i(cset->biased_map_address()));
 563   } else {
 564     st->print_cr(" (NULL)");


1523     }
1524 
1525     // Trash the collection set left over from previous cycle, if any.
1526     {
1527       ShenandoahGCPhase phase(ShenandoahPhaseTimings::trash_cset);
1528       trash_cset_regions();
1529     }
1530 
1531     {
1532       ShenandoahGCPhase phase(ShenandoahPhaseTimings::prepare_evac);
1533 
1534       ShenandoahHeapLocker locker(lock());
1535       _collection_set->clear();
1536       _free_set->clear();
1537 
1538       heuristics()->choose_collection_set(_collection_set);
1539 
1540       _free_set->rebuild();
1541     }
1542 





1543     // If collection set has candidates, start evacuation.
1544     // Otherwise, bypass the rest of the cycle.
1545     if (!collection_set()->is_empty()) {
1546       ShenandoahGCPhase init_evac(ShenandoahPhaseTimings::init_evac);
1547 
1548       if (ShenandoahVerify) {
1549         verifier()->verify_before_evacuation();
1550       }
1551 
1552       set_evacuation_in_progress(true);
1553       // From here on, we need to update references.
1554       set_has_forwarded_objects(true);
1555 
1556       if (!is_degenerated_gc_in_progress()) {
1557         prepare_concurrent_roots();
1558         prepare_concurrent_unloading();

1559         evacuate_and_update_roots();
1560       }
1561 
1562       if (ShenandoahPacing) {
1563         pacer()->setup_for_evac();
1564       }
1565 
1566       if (ShenandoahVerify) {
1567         ShenandoahRootVerifier::RootTypes types = ShenandoahRootVerifier::None;
1568         if (ShenandoahConcurrentRoots::should_do_concurrent_roots()) {
1569           types = ShenandoahRootVerifier::combine(ShenandoahRootVerifier::JNIHandleRoots, ShenandoahRootVerifier::WeakRoots);
1570           types = ShenandoahRootVerifier::combine(types, ShenandoahRootVerifier::CLDGRoots);
1571         }
1572 
1573         if (ShenandoahConcurrentRoots::should_do_concurrent_class_unloading()) {
1574           types = ShenandoahRootVerifier::combine(types, ShenandoahRootVerifier::CodeRoots);
1575         }
1576         verifier()->verify_roots_no_forwarded_except(types);
1577         verifier()->verify_during_evacuation();
1578       }


1652 
1653   void work(uint worker_id) {
1654     ShenandoahEvacOOMScope oom;
1655     {
1656       // jni_roots and weak_roots are OopStorage backed roots, concurrent iteration
1657       // may race against OopStorage::release() calls.
1658       ShenandoahEvacUpdateOopStorageRootsClosure cl;
1659       _vm_roots.oops_do<ShenandoahEvacUpdateOopStorageRootsClosure>(&cl);
1660       _weak_roots.oops_do<ShenandoahEvacUpdateOopStorageRootsClosure>(&cl);
1661     }
1662 
1663     {
1664       ShenandoahEvacuateUpdateRootsClosure cl;
1665       CLDToOopClosure clds(&cl, ClassLoaderData::_claim_strong);
1666       _cld_roots.cld_do(&clds);
1667     }
1668   }
1669 };
1670 
1671 void ShenandoahHeap::op_roots() {
1672   if (is_evacuation_in_progress()) {
1673     if (ShenandoahConcurrentRoots::should_do_concurrent_class_unloading()) {
1674       _unloader.unload();
1675     }
1676 
1677     if (ShenandoahConcurrentRoots::should_do_concurrent_roots()) {
1678       ShenandoahConcurrentRootsEvacUpdateTask task;
1679       workers()->run_task(&task);
1680     }
1681   }
1682 
1683   set_concurrent_root_in_progress(false);
1684 }
1685 
1686 void ShenandoahHeap::op_reset() {
1687   reset_mark_bitmap();
1688 }
1689 
1690 void ShenandoahHeap::op_preclean() {
1691   concurrent_mark()->preclean_weak_refs();
1692 }


2218     assert((r->is_pinned() && r->pin_count() > 0) || (!r->is_pinned() && r->pin_count() == 0),
2219            "Region " SIZE_FORMAT " pinning status is inconsistent", i);
2220   }
2221 }
2222 #endif
2223 
2224 GCTimer* ShenandoahHeap::gc_timer() const {
2225   return _gc_timer;
2226 }
2227 
2228 void ShenandoahHeap::prepare_concurrent_roots() {
2229   assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint");
2230   if (ShenandoahConcurrentRoots::should_do_concurrent_roots()) {
2231     set_concurrent_root_in_progress(true);
2232   }
2233 }
2234 
2235 void ShenandoahHeap::prepare_concurrent_unloading() {
2236   assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint");
2237   if (ShenandoahConcurrentRoots::should_do_concurrent_class_unloading()) {
2238     ShenandoahCodeRoots::prepare_concurrent_unloading();
2239     _unloader.prepare();
2240   }
2241 }
2242 
2243 void ShenandoahHeap::finish_concurrent_unloading() {
2244   assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint");
2245   if (ShenandoahConcurrentRoots::should_do_concurrent_class_unloading()) {
2246     _unloader.finish();
2247   }
2248 }
2249 
2250 #ifdef ASSERT
2251 void ShenandoahHeap::assert_gc_workers(uint nworkers) {
2252   assert(nworkers > 0 && nworkers <= max_workers(), "Sanity");
2253 
2254   if (ShenandoahSafepoint::is_at_shenandoah_safepoint()) {
2255     if (UseDynamicNumberOfGCThreads ||
2256         (FLAG_IS_DEFAULT(ParallelGCThreads) && ForceDynamicNumberOfGCThreads)) {
2257       assert(nworkers <= ParallelGCThreads, "Cannot use more than it has");
2258     } else {




 525 void ShenandoahHeap::print_on(outputStream* st) const {
 526   st->print_cr("Shenandoah Heap");
 527   st->print_cr(" " SIZE_FORMAT "%s total, " SIZE_FORMAT "%s committed, " SIZE_FORMAT "%s used",
 528                byte_size_in_proper_unit(max_capacity()), proper_unit_for_byte_size(max_capacity()),
 529                byte_size_in_proper_unit(committed()),    proper_unit_for_byte_size(committed()),
 530                byte_size_in_proper_unit(used()),         proper_unit_for_byte_size(used()));
 531   st->print_cr(" " SIZE_FORMAT " x " SIZE_FORMAT"%s regions",
 532                num_regions(),
 533                byte_size_in_proper_unit(ShenandoahHeapRegion::region_size_bytes()),
 534                proper_unit_for_byte_size(ShenandoahHeapRegion::region_size_bytes()));
 535 
 536   st->print("Status: ");
 537   if (has_forwarded_objects())               st->print("has forwarded objects, ");
 538   if (is_concurrent_mark_in_progress())      st->print("marking, ");
 539   if (is_evacuation_in_progress())           st->print("evacuating, ");
 540   if (is_update_refs_in_progress())          st->print("updating refs, ");
 541   if (is_concurrent_traversal_in_progress()) st->print("traversal, ");
 542   if (is_degenerated_gc_in_progress())       st->print("degenerated gc, ");
 543   if (is_full_gc_in_progress())              st->print("full gc, ");
 544   if (is_full_gc_move_in_progress())         st->print("full gc move, ");
 545   if (is_concurrent_root_in_progress())      st->print("concurrent roots, ");
 546 
 547   if (cancelled_gc()) {
 548     st->print("cancelled");
 549   } else {
 550     st->print("not cancelled");
 551   }
 552   st->cr();
 553 
 554   st->print_cr("Reserved region:");
 555   st->print_cr(" - [" PTR_FORMAT ", " PTR_FORMAT ") ",
 556                p2i(reserved_region().start()),
 557                p2i(reserved_region().end()));
 558 
 559   ShenandoahCollectionSet* cset = collection_set();
 560   st->print_cr("Collection set:");
 561   if (cset != NULL) {
 562     st->print_cr(" - map (vanilla): " PTR_FORMAT, p2i(cset->map_address()));
 563     st->print_cr(" - map (biased):  " PTR_FORMAT, p2i(cset->biased_map_address()));
 564   } else {
 565     st->print_cr(" (NULL)");


1524     }
1525 
1526     // Trash the collection set left over from previous cycle, if any.
1527     {
1528       ShenandoahGCPhase phase(ShenandoahPhaseTimings::trash_cset);
1529       trash_cset_regions();
1530     }
1531 
1532     {
1533       ShenandoahGCPhase phase(ShenandoahPhaseTimings::prepare_evac);
1534 
1535       ShenandoahHeapLocker locker(lock());
1536       _collection_set->clear();
1537       _free_set->clear();
1538 
1539       heuristics()->choose_collection_set(_collection_set);
1540 
1541       _free_set->rebuild();
1542     }
1543 
1544     if (!is_degenerated_gc_in_progress()) {
1545       prepare_concurrent_roots();
1546       prepare_concurrent_unloading();
1547     }
1548 
1549     // If collection set has candidates, start evacuation.
1550     // Otherwise, bypass the rest of the cycle.
1551     if (!collection_set()->is_empty()) {
1552       ShenandoahGCPhase init_evac(ShenandoahPhaseTimings::init_evac);
1553 
1554       if (ShenandoahVerify) {
1555         verifier()->verify_before_evacuation();
1556       }
1557 
1558       set_evacuation_in_progress(true);
1559       // From here on, we need to update references.
1560       set_has_forwarded_objects(true);
1561 
1562       if (!is_degenerated_gc_in_progress()) {
1563         if (ShenandoahConcurrentRoots::should_do_concurrent_class_unloading()) {
1564           ShenandoahCodeRoots::arm_nmethods();
1565         }
1566         evacuate_and_update_roots();
1567       }
1568 
1569       if (ShenandoahPacing) {
1570         pacer()->setup_for_evac();
1571       }
1572 
1573       if (ShenandoahVerify) {
1574         ShenandoahRootVerifier::RootTypes types = ShenandoahRootVerifier::None;
1575         if (ShenandoahConcurrentRoots::should_do_concurrent_roots()) {
1576           types = ShenandoahRootVerifier::combine(ShenandoahRootVerifier::JNIHandleRoots, ShenandoahRootVerifier::WeakRoots);
1577           types = ShenandoahRootVerifier::combine(types, ShenandoahRootVerifier::CLDGRoots);
1578         }
1579 
1580         if (ShenandoahConcurrentRoots::should_do_concurrent_class_unloading()) {
1581           types = ShenandoahRootVerifier::combine(types, ShenandoahRootVerifier::CodeRoots);
1582         }
1583         verifier()->verify_roots_no_forwarded_except(types);
1584         verifier()->verify_during_evacuation();
1585       }


1659 
1660   void work(uint worker_id) {
1661     ShenandoahEvacOOMScope oom;
1662     {
1663       // jni_roots and weak_roots are OopStorage backed roots, concurrent iteration
1664       // may race against OopStorage::release() calls.
1665       ShenandoahEvacUpdateOopStorageRootsClosure cl;
1666       _vm_roots.oops_do<ShenandoahEvacUpdateOopStorageRootsClosure>(&cl);
1667       _weak_roots.oops_do<ShenandoahEvacUpdateOopStorageRootsClosure>(&cl);
1668     }
1669 
1670     {
1671       ShenandoahEvacuateUpdateRootsClosure cl;
1672       CLDToOopClosure clds(&cl, ClassLoaderData::_claim_strong);
1673       _cld_roots.cld_do(&clds);
1674     }
1675   }
1676 };
1677 
1678 void ShenandoahHeap::op_roots() {
1679   if (is_concurrent_root_in_progress()) {
1680     if (ShenandoahConcurrentRoots::should_do_concurrent_class_unloading()) {
1681       _unloader.unload();
1682     }
1683 
1684     if (ShenandoahConcurrentRoots::should_do_concurrent_roots()) {
1685       ShenandoahConcurrentRootsEvacUpdateTask task;
1686       workers()->run_task(&task);
1687     }
1688   }
1689 
1690   set_concurrent_root_in_progress(false);
1691 }
1692 
1693 void ShenandoahHeap::op_reset() {
1694   reset_mark_bitmap();
1695 }
1696 
1697 void ShenandoahHeap::op_preclean() {
1698   concurrent_mark()->preclean_weak_refs();
1699 }


2225     assert((r->is_pinned() && r->pin_count() > 0) || (!r->is_pinned() && r->pin_count() == 0),
2226            "Region " SIZE_FORMAT " pinning status is inconsistent", i);
2227   }
2228 }
2229 #endif
2230 
2231 GCTimer* ShenandoahHeap::gc_timer() const {
2232   return _gc_timer;
2233 }
2234 
2235 void ShenandoahHeap::prepare_concurrent_roots() {
2236   assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint");
2237   if (ShenandoahConcurrentRoots::should_do_concurrent_roots()) {
2238     set_concurrent_root_in_progress(true);
2239   }
2240 }
2241 
2242 void ShenandoahHeap::prepare_concurrent_unloading() {
2243   assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint");
2244   if (ShenandoahConcurrentRoots::should_do_concurrent_class_unloading()) {

2245     _unloader.prepare();
2246   }
2247 }
2248 
2249 void ShenandoahHeap::finish_concurrent_unloading() {
2250   assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint");
2251   if (ShenandoahConcurrentRoots::should_do_concurrent_class_unloading()) {
2252     _unloader.finish();
2253   }
2254 }
2255 
2256 #ifdef ASSERT
2257 void ShenandoahHeap::assert_gc_workers(uint nworkers) {
2258   assert(nworkers > 0 && nworkers <= max_workers(), "Sanity");
2259 
2260   if (ShenandoahSafepoint::is_at_shenandoah_safepoint()) {
2261     if (UseDynamicNumberOfGCThreads ||
2262         (FLAG_IS_DEFAULT(ParallelGCThreads) && ForceDynamicNumberOfGCThreads)) {
2263       assert(nworkers <= ParallelGCThreads, "Cannot use more than it has");
2264     } else {


< prev index next >