8 * This code is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11 * version 2 for more details (a copy is included in the LICENSE file that
12 * accompanied this code).
13 *
14 * You should have received a copy of the GNU General Public License version
15 * 2 along with this work; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19 * or visit www.oracle.com if you need additional information or have any
20 * questions.
21 *
22 */
23
24 #include "gc/shared/gcTraceTime.inline.hpp"
25 #include "gc/shenandoah/shenandoahConcurrentThread.hpp"
26 #include "gc/shenandoah/shenandoahCollectorPolicy.hpp"
27 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
28 #include "gc/shenandoah/shenandoahJNICritical.hpp"
29 #include "gc/shenandoah/shenandoahMonitoringSupport.hpp"
30 #include "gc/shenandoah/vm_operations_shenandoah.hpp"
31 #include "memory/iterator.hpp"
32 #include "memory/universe.hpp"
33 #include "runtime/vmThread.hpp"
34
35 ShenandoahConcurrentThread::ShenandoahConcurrentThread() :
36 ConcurrentGCThread(),
37 _full_gc_lock(Mutex::leaf, "ShenandoahFullGC_lock", true, Monitor::_safepoint_check_always),
38 _do_full_gc(false)
39 {
40 create_and_start();
41 }
42
43 ShenandoahConcurrentThread::~ShenandoahConcurrentThread() {
44 // This is here so that super is called.
45 }
46
47 void ShenandoahConcurrentThread::run_service() {
48
49 while (! ReferencePendingListLocker::is_initialized()) {
50 os::naked_yield();
51 }
52
53 ShenandoahHeap* heap = ShenandoahHeap::heap();
54
55 GCTimer* gc_timer = heap->gc_timer();
56
57 while (! should_terminate()) {
58 if (_do_full_gc) {
59 {
60 if (_full_gc_cause == GCCause::_allocation_failure) {
61 heap->shenandoahPolicy()->record_allocation_failure_gc();
62 } else {
63 heap->shenandoahPolicy()->record_user_requested_gc();
64 }
65
66 TraceCollectorStats tcs(heap->monitoring_support()->full_collection_counters());
67 TraceMemoryManagerStats tmms(true, _full_gc_cause);
68 VM_ShenandoahFullGC full_gc(_full_gc_cause);
69 heap->jni_critical()->execute_in_vm_thread(&full_gc);
70 }
71 MonitorLockerEx ml(&_full_gc_lock);
72 _do_full_gc = false;
73 ml.notify_all();
74 } else if (heap->shenandoahPolicy()->should_start_concurrent_mark(heap->used(),
75 heap->capacity()))
76 {
77
78 gc_timer->register_gc_start();
79
80 heap->shenandoahPolicy()->increase_cycle_counter();
81
82 TraceCollectorStats tcs(heap->monitoring_support()->concurrent_collection_counters());
83 TraceMemoryManagerStats tmms(false, GCCause::_no_cause_specified);
84 if (ShenandoahGCVerbose)
85 tty->print("Capacity = "SIZE_FORMAT" Used = "SIZE_FORMAT" doing initMark\n", heap->capacity(), heap->used());
86
87 if (ShenandoahGCVerbose) tty->print("Starting a mark");
88
89 {
90 TraceCollectorStats tcs(heap->monitoring_support()->stw_collection_counters());
91 VM_ShenandoahInitMark initMark;
92 heap->shenandoahPolicy()->record_phase_start(ShenandoahCollectorPolicy::init_mark_gross);
93 VMThread::execute(&initMark);
94 heap->shenandoahPolicy()->record_phase_end(ShenandoahCollectorPolicy::init_mark_gross);
95 }
96 {
97 GCTraceTime(Info, gc, phases) time("Concurrent marking", gc_timer, GCCause::_no_gc, true);
98 TraceCollectorStats tcs(heap->monitoring_support()->concurrent_collection_counters());
99 ShenandoahHeap::heap()->concurrentMark()->mark_from_roots();
100 }
101
102 {
103 TraceCollectorStats tcs(heap->monitoring_support()->stw_collection_counters());
104 VM_ShenandoahStartEvacuation finishMark;
105 heap->shenandoahPolicy()->record_phase_start(ShenandoahCollectorPolicy::final_mark_gross);
106 heap->jni_critical()->execute_in_vm_thread(&finishMark);
107 heap->shenandoahPolicy()->record_phase_end(ShenandoahCollectorPolicy::final_mark_gross);
108 }
109
110 if (! should_terminate()) {
111 GCTraceTime(Info, gc, phases) time("Concurrent evacuation", gc_timer, GCCause::_no_gc, true);
112 TraceCollectorStats tcs(heap->monitoring_support()->concurrent_collection_counters());
113 heap->do_evacuation();
114 }
115
116 if (heap->is_evacuation_in_progress()) {
117 heap->set_evacuation_in_progress(false);
118 }
119 heap->shenandoahPolicy()->record_phase_start(ShenandoahCollectorPolicy::reset_bitmaps);
120 heap->reset_mark_bitmap();
121 heap->shenandoahPolicy()->record_phase_end(ShenandoahCollectorPolicy::reset_bitmaps);
122
123 gc_timer->register_gc_end();
124 } else {
125 Thread::current()->_ParkEvent->park(10) ;
126 // yield();
|
8 * This code is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11 * version 2 for more details (a copy is included in the LICENSE file that
12 * accompanied this code).
13 *
14 * You should have received a copy of the GNU General Public License version
15 * 2 along with this work; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19 * or visit www.oracle.com if you need additional information or have any
20 * questions.
21 *
22 */
23
24 #include "gc/shared/gcTraceTime.inline.hpp"
25 #include "gc/shenandoah/shenandoahConcurrentThread.hpp"
26 #include "gc/shenandoah/shenandoahCollectorPolicy.hpp"
27 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
28 #include "gc/shenandoah/shenandoahMonitoringSupport.hpp"
29 #include "gc/shenandoah/vm_operations_shenandoah.hpp"
30 #include "memory/iterator.hpp"
31 #include "memory/universe.hpp"
32 #include "runtime/vmThread.hpp"
33
34 ShenandoahConcurrentThread::ShenandoahConcurrentThread() :
35 ConcurrentGCThread(),
36 _full_gc_lock(Mutex::leaf, "ShenandoahFullGC_lock", true, Monitor::_safepoint_check_always),
37 _do_full_gc(false)
38 {
39 create_and_start();
40 }
41
42 ShenandoahConcurrentThread::~ShenandoahConcurrentThread() {
43 // This is here so that super is called.
44 }
45
46 void ShenandoahConcurrentThread::run_service() {
47
48 while (! ReferencePendingListLocker::is_initialized()) {
49 os::naked_yield();
50 }
51
52 ShenandoahHeap* heap = ShenandoahHeap::heap();
53
54 GCTimer* gc_timer = heap->gc_timer();
55
56 while (! should_terminate()) {
57 if (_do_full_gc) {
58 {
59 if (_full_gc_cause == GCCause::_allocation_failure) {
60 heap->shenandoahPolicy()->record_allocation_failure_gc();
61 } else {
62 heap->shenandoahPolicy()->record_user_requested_gc();
63 }
64
65 TraceCollectorStats tcs(heap->monitoring_support()->full_collection_counters());
66 TraceMemoryManagerStats tmms(true, _full_gc_cause);
67 VM_ShenandoahFullGC full_gc(_full_gc_cause);
68 VMThread::execute(&full_gc);
69 }
70 MonitorLockerEx ml(&_full_gc_lock);
71 _do_full_gc = false;
72 ml.notify_all();
73 } else if (heap->shenandoahPolicy()->should_start_concurrent_mark(heap->used(),
74 heap->capacity()))
75 {
76
77 gc_timer->register_gc_start();
78
79 heap->shenandoahPolicy()->increase_cycle_counter();
80
81 TraceCollectorStats tcs(heap->monitoring_support()->concurrent_collection_counters());
82 TraceMemoryManagerStats tmms(false, GCCause::_no_cause_specified);
83 if (ShenandoahGCVerbose)
84 tty->print("Capacity = "SIZE_FORMAT" Used = "SIZE_FORMAT" doing initMark\n", heap->capacity(), heap->used());
85
86 if (ShenandoahGCVerbose) tty->print("Starting a mark");
87
88 {
89 TraceCollectorStats tcs(heap->monitoring_support()->stw_collection_counters());
90 VM_ShenandoahInitMark initMark;
91 heap->shenandoahPolicy()->record_phase_start(ShenandoahCollectorPolicy::init_mark_gross);
92 VMThread::execute(&initMark);
93 heap->shenandoahPolicy()->record_phase_end(ShenandoahCollectorPolicy::init_mark_gross);
94 }
95 {
96 GCTraceTime(Info, gc, phases) time("Concurrent marking", gc_timer, GCCause::_no_gc, true);
97 TraceCollectorStats tcs(heap->monitoring_support()->concurrent_collection_counters());
98 ShenandoahHeap::heap()->concurrentMark()->mark_from_roots();
99 }
100
101 {
102 TraceCollectorStats tcs(heap->monitoring_support()->stw_collection_counters());
103 VM_ShenandoahStartEvacuation finishMark;
104 heap->shenandoahPolicy()->record_phase_start(ShenandoahCollectorPolicy::final_mark_gross);
105 VMThread::execute(&finishMark);
106 heap->shenandoahPolicy()->record_phase_end(ShenandoahCollectorPolicy::final_mark_gross);
107 }
108
109 if (! should_terminate()) {
110 GCTraceTime(Info, gc, phases) time("Concurrent evacuation", gc_timer, GCCause::_no_gc, true);
111 TraceCollectorStats tcs(heap->monitoring_support()->concurrent_collection_counters());
112 heap->do_evacuation();
113 }
114
115 if (heap->is_evacuation_in_progress()) {
116 heap->set_evacuation_in_progress(false);
117 }
118 heap->shenandoahPolicy()->record_phase_start(ShenandoahCollectorPolicy::reset_bitmaps);
119 heap->reset_mark_bitmap();
120 heap->shenandoahPolicy()->record_phase_end(ShenandoahCollectorPolicy::reset_bitmaps);
121
122 gc_timer->register_gc_end();
123 } else {
124 Thread::current()->_ParkEvent->park(10) ;
125 // yield();
|