40 } |
40 } |
41 |
41 |
42 void VM_G1IncCollectionPause::doit() { |
42 void VM_G1IncCollectionPause::doit() { |
43 JvmtiGCForAllocationMarker jgcm; |
43 JvmtiGCForAllocationMarker jgcm; |
44 G1CollectedHeap* g1h = G1CollectedHeap::heap(); |
44 G1CollectedHeap* g1h = G1CollectedHeap::heap(); |
|
45 assert(!_should_initiate_conc_mark || |
|
46 ((_gc_cause == GCCause::_gc_locker && GCLockerInvokesConcurrent) || |
|
47 (_gc_cause == GCCause::_java_lang_system_gc && ExplicitGCInvokesConcurrent)), |
|
48 "only a GC locker or a System.gc() induced GC should start a cycle"); |
|
49 |
45 GCCauseSetter x(g1h, _gc_cause); |
50 GCCauseSetter x(g1h, _gc_cause); |
46 g1h->do_collection_pause_at_safepoint(); |
51 if (_should_initiate_conc_mark) { |
|
52 // It's safer to read full_collections_completed() here, given |
|
53 // that noone else will be updating it concurrently. Since we'll |
|
54 // only need it if we're initiating a marking cycle, no point in |
|
55 // setting it earlier. |
|
56 _full_collections_completed_before = g1h->full_collections_completed(); |
|
57 |
|
58 // At this point we are supposed to start a concurrent cycle. We |
|
59 // will do so if one is not already in progress. |
|
60 bool res = g1h->g1_policy()->force_initial_mark_if_outside_cycle(); |
|
61 } |
|
62 g1h->do_collection_pause_at_safepoint(_target_pause_time_ms); |
|
63 } |
|
64 |
|
65 void VM_G1IncCollectionPause::doit_epilogue() { |
|
66 VM_GC_Operation::doit_epilogue(); |
|
67 |
|
68 // If the pause was initiated by a System.gc() and |
|
69 // +ExplicitGCInvokesConcurrent, we have to wait here for the cycle |
|
70 // that just started (or maybe one that was already in progress) to |
|
71 // finish. |
|
72 if (_gc_cause == GCCause::_java_lang_system_gc && |
|
73 _should_initiate_conc_mark) { |
|
74 assert(ExplicitGCInvokesConcurrent, |
|
75 "the only way to be here is if ExplicitGCInvokesConcurrent is set"); |
|
76 |
|
77 G1CollectedHeap* g1h = G1CollectedHeap::heap(); |
|
78 |
|
79 // In the doit() method we saved g1h->full_collections_completed() |
|
80 // in the _full_collections_completed_before field. We have to |
|
81 // wait until we observe that g1h->full_collections_completed() |
|
82 // has increased by at least one. This can happen if a) we started |
|
83 // a cycle and it completes, b) a cycle already in progress |
|
84 // completes, or c) a Full GC happens. |
|
85 |
|
86 // If the condition has already been reached, there's no point in |
|
87 // actually taking the lock and doing the wait. |
|
88 if (g1h->full_collections_completed() <= |
|
89 _full_collections_completed_before) { |
|
90 // The following is largely copied from CMS |
|
91 |
|
92 Thread* thr = Thread::current(); |
|
93 assert(thr->is_Java_thread(), "invariant"); |
|
94 JavaThread* jt = (JavaThread*)thr; |
|
95 ThreadToNativeFromVM native(jt); |
|
96 |
|
97 MutexLockerEx x(FullGCCount_lock, Mutex::_no_safepoint_check_flag); |
|
98 while (g1h->full_collections_completed() <= |
|
99 _full_collections_completed_before) { |
|
100 FullGCCount_lock->wait(Mutex::_no_safepoint_check_flag); |
|
101 } |
|
102 } |
|
103 } |
47 } |
104 } |
48 |
105 |
49 void VM_CGC_Operation::doit() { |
106 void VM_CGC_Operation::doit() { |
50 gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps); |
107 gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps); |
51 TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty); |
108 TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty); |