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 {
|