36 #include "gc/shenandoah/shenandoahBarrierSet.hpp" |
36 #include "gc/shenandoah/shenandoahBarrierSet.hpp" |
37 #include "gc/shenandoah/shenandoahClosures.inline.hpp" |
37 #include "gc/shenandoah/shenandoahClosures.inline.hpp" |
38 #include "gc/shenandoah/shenandoahCollectionSet.hpp" |
38 #include "gc/shenandoah/shenandoahCollectionSet.hpp" |
39 #include "gc/shenandoah/shenandoahCollectorPolicy.hpp" |
39 #include "gc/shenandoah/shenandoahCollectorPolicy.hpp" |
40 #include "gc/shenandoah/shenandoahConcurrentMark.inline.hpp" |
40 #include "gc/shenandoah/shenandoahConcurrentMark.inline.hpp" |
|
41 #include "gc/shenandoah/shenandoahConcurrentRoots.hpp" |
41 #include "gc/shenandoah/shenandoahControlThread.hpp" |
42 #include "gc/shenandoah/shenandoahControlThread.hpp" |
42 #include "gc/shenandoah/shenandoahFreeSet.hpp" |
43 #include "gc/shenandoah/shenandoahFreeSet.hpp" |
43 #include "gc/shenandoah/shenandoahPhaseTimings.hpp" |
44 #include "gc/shenandoah/shenandoahPhaseTimings.hpp" |
44 #include "gc/shenandoah/shenandoahHeap.inline.hpp" |
45 #include "gc/shenandoah/shenandoahHeap.inline.hpp" |
45 #include "gc/shenandoah/shenandoahHeapRegion.hpp" |
46 #include "gc/shenandoah/shenandoahHeapRegion.hpp" |
1069 void ShenandoahHeap::evacuate_and_update_roots() { |
1070 void ShenandoahHeap::evacuate_and_update_roots() { |
1070 #if COMPILER2_OR_JVMCI |
1071 #if COMPILER2_OR_JVMCI |
1071 DerivedPointerTable::clear(); |
1072 DerivedPointerTable::clear(); |
1072 #endif |
1073 #endif |
1073 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"); |
1074 |
|
1075 { |
1075 { |
1076 ShenandoahRootEvacuator rp(workers()->active_workers(), ShenandoahPhaseTimings::init_evac); |
1076 // Include concurrent roots if current cycle can not process those roots concurrently |
|
1077 ShenandoahRootEvacuator rp(workers()->active_workers(), |
|
1078 ShenandoahPhaseTimings::init_evac, |
|
1079 !ShenandoahConcurrentRoots::should_do_concurrent_roots()); |
1077 ShenandoahEvacuateUpdateRootsTask roots_task(&rp); |
1080 ShenandoahEvacuateUpdateRootsTask roots_task(&rp); |
1078 workers()->run_task(&roots_task); |
1081 workers()->run_task(&roots_task); |
1079 } |
1082 } |
1080 |
1083 |
1081 #if COMPILER2_OR_JVMCI |
1084 #if COMPILER2_OR_JVMCI |
1515 if (ShenandoahPacing) { |
1518 if (ShenandoahPacing) { |
1516 pacer()->setup_for_evac(); |
1519 pacer()->setup_for_evac(); |
1517 } |
1520 } |
1518 |
1521 |
1519 if (ShenandoahVerify) { |
1522 if (ShenandoahVerify) { |
1520 verifier()->verify_roots_no_forwarded(); |
1523 if (ShenandoahConcurrentRoots::should_do_concurrent_roots()) { |
|
1524 verifier()->verify_roots_no_forwarded_except(ShenandoahRootVerifier::JNIHandleRoots); |
|
1525 } else { |
|
1526 verifier()->verify_roots_no_forwarded(); |
|
1527 } |
1521 verifier()->verify_during_evacuation(); |
1528 verifier()->verify_during_evacuation(); |
1522 } |
1529 } |
1523 } else { |
1530 } else { |
1524 if (ShenandoahVerify) { |
1531 if (ShenandoahVerify) { |
1525 verifier()->verify_after_concmark(); |
1532 verifier()->verify_after_concmark(); |
1574 update_heap_references(true); |
1581 update_heap_references(true); |
1575 } |
1582 } |
1576 |
1583 |
1577 void ShenandoahHeap::op_cleanup() { |
1584 void ShenandoahHeap::op_cleanup() { |
1578 free_set()->recycle_trash(); |
1585 free_set()->recycle_trash(); |
|
1586 } |
|
1587 |
|
1588 class ShenandoahConcurrentRootsEvacUpdateTask : public AbstractGangTask { |
|
1589 private: |
|
1590 ShenandoahJNIHandleRoots<true /*concurrent*/> _jni_roots; |
|
1591 |
|
1592 public: |
|
1593 ShenandoahConcurrentRootsEvacUpdateTask() : |
|
1594 AbstractGangTask("Shenandoah Evacuate/Update Concurrent Roots Task") { |
|
1595 } |
|
1596 |
|
1597 void work(uint worker_id) { |
|
1598 ShenandoahEvacOOMScope oom; |
|
1599 ShenandoahEvacuateUpdateRootsClosure cl; |
|
1600 _jni_roots.oops_do<ShenandoahEvacuateUpdateRootsClosure>(&cl); |
|
1601 } |
|
1602 }; |
|
1603 |
|
1604 void ShenandoahHeap::op_roots() { |
|
1605 if (is_evacuation_in_progress() && |
|
1606 ShenandoahConcurrentRoots::should_do_concurrent_roots()) { |
|
1607 ShenandoahConcurrentRootsEvacUpdateTask task; |
|
1608 workers()->run_task(&task); |
|
1609 } |
1579 } |
1610 } |
1580 |
1611 |
1581 void ShenandoahHeap::op_reset() { |
1612 void ShenandoahHeap::op_reset() { |
1582 reset_mark_bitmap(); |
1613 reset_mark_bitmap(); |
1583 } |
1614 } |
2557 "concurrent reference update"); |
2588 "concurrent reference update"); |
2558 |
2589 |
2559 try_inject_alloc_failure(); |
2590 try_inject_alloc_failure(); |
2560 op_updaterefs(); |
2591 op_updaterefs(); |
2561 } |
2592 } |
|
2593 |
|
2594 void ShenandoahHeap::entry_roots() { |
|
2595 ShenandoahGCPhase phase(ShenandoahPhaseTimings::conc_roots); |
|
2596 |
|
2597 static const char* msg = "Concurrent roots processing"; |
|
2598 GCTraceTime(Info, gc) time(msg, NULL, GCCause::_no_gc, true); |
|
2599 EventMark em("%s", msg); |
|
2600 |
|
2601 ShenandoahWorkerScope scope(workers(), |
|
2602 ShenandoahWorkerPolicy::calc_workers_for_conc_root_processing(), |
|
2603 "concurrent root processing"); |
|
2604 |
|
2605 try_inject_alloc_failure(); |
|
2606 op_roots(); |
|
2607 } |
|
2608 |
2562 void ShenandoahHeap::entry_cleanup() { |
2609 void ShenandoahHeap::entry_cleanup() { |
2563 ShenandoahGCPhase phase(ShenandoahPhaseTimings::conc_cleanup); |
2610 ShenandoahGCPhase phase(ShenandoahPhaseTimings::conc_cleanup); |
2564 |
2611 |
2565 static const char* msg = "Concurrent cleanup"; |
2612 static const char* msg = "Concurrent cleanup"; |
2566 GCTraceTime(Info, gc) time(msg, NULL, GCCause::_no_gc, true); |
2613 GCTraceTime(Info, gc) time(msg, NULL, GCCause::_no_gc, true); |