1 /*
  2  * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  */
 23 
 24 #include "precompiled.hpp"
 25 #include "gc/shared/gcId.hpp"
 26 #include "gc/shared/gcLocker.hpp"
 27 #include "gc/shared/isGCActiveMark.hpp"
 28 #include "gc/shared/vmGCOperations.hpp"
 29 #include "gc/z/zCollectedHeap.hpp"
 30 #include "gc/z/zDriver.hpp"
 31 #include "gc/z/zHeap.inline.hpp"
 32 #include "gc/z/zMessagePort.inline.hpp"
 33 #include "gc/z/zServiceability.hpp"
 34 #include "gc/z/zStat.hpp"
 35 #include "logging/log.hpp"
 36 #include "runtime/vm_operations.hpp"
 37 #include "runtime/vmThread.hpp"
 38 
 39 static const ZStatPhaseCycle      ZPhaseCycle("Garbage Collection Cycle");
 40 static const ZStatPhasePause      ZPhasePauseMarkStart("Pause Mark Start");
 41 static const ZStatPhaseConcurrent ZPhaseConcurrentMark("Concurrent Mark");
 42 static const ZStatPhaseConcurrent ZPhaseConcurrentMarkContinue("Concurrent Mark Continue");
 43 static const ZStatPhasePause      ZPhasePauseMarkEnd("Pause Mark End");
 44 static const ZStatPhaseConcurrent ZPhaseConcurrentProcessNonStrongReferences("Concurrent Process Non-Strong References");
 45 static const ZStatPhaseConcurrent ZPhaseConcurrentResetRelocationSet("Concurrent Reset Relocation Set");
 46 static const ZStatPhaseConcurrent ZPhaseConcurrentDestroyDetachedPages("Concurrent Destroy Detached Pages");
 47 static const ZStatPhaseConcurrent ZPhaseConcurrentSelectRelocationSet("Concurrent Select Relocation Set");
 48 static const ZStatPhaseConcurrent ZPhaseConcurrentPrepareRelocationSet("Concurrent Prepare Relocation Set");
 49 static const ZStatPhasePause      ZPhasePauseRelocateStart("Pause Relocate Start");
 50 static const ZStatPhaseConcurrent ZPhaseConcurrentRelocated("Concurrent Relocate");
 51 static const ZStatCriticalPhase   ZCriticalPhaseGCLockerStall("GC Locker Stall", false /* verbose */);
 52 static const ZStatSampler         ZSamplerJavaThreads("System", "Java Threads", ZStatUnitThreads);
 53 
 54 class ZOperationClosure : public StackObj {
 55 public:
 56   virtual const char* name() const = 0;
 57 
 58   virtual bool needs_inactive_gc_locker() const {
 59     // An inactive GC locker is needed in operations where we change the good
 60     // mask or move objects. Changing the good mask will invalidate all oops,
 61     // which makes it conceptually the same thing as moving all objects.
 62     return false;
 63   }
 64 
 65   virtual bool do_operation() = 0;
 66 };
 67 
 68 class VM_ZOperation : public VM_Operation {
 69 private:
 70   ZOperationClosure* _cl;
 71   uint               _gc_id;
 72   bool               _gc_locked;
 73   bool               _success;
 74 
 75 public:
 76   VM_ZOperation(ZOperationClosure* cl) :
 77       _cl(cl),
 78       _gc_id(GCId::current()),
 79       _gc_locked(false),
 80       _success(false) {}
 81 
 82   virtual VMOp_Type type() const {
 83     return VMOp_ZOperation;
 84   }
 85 
 86   virtual const char* name() const {
 87     return _cl->name();
 88   }
 89 
 90   virtual bool doit_prologue() {
 91     Heap_lock->lock();
 92     return true;
 93   }
 94 
 95   virtual void doit() {
 96     assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint");
 97 
 98     ZStatSample(ZSamplerJavaThreads, Threads::number_of_threads());
 99 
100     // JVMTI support
101     SvcGCMarker sgcm(SvcGCMarker::CONCURRENT);
102 
103     // Setup GC id
104     GCIdMark gcid(_gc_id);
105 
106     if (_cl->needs_inactive_gc_locker() && GCLocker::check_active_before_gc()) {
107       // GC locker is active, bail out
108       _gc_locked = true;
109     } else {
110       // Execute operation
111       IsGCActiveMark mark;
112       _success = _cl->do_operation();
113     }
114   }
115 
116   virtual void doit_epilogue() {
117     Heap_lock->unlock();
118   }
119 
120   bool gc_locked() {
121     return _gc_locked;
122   }
123 
124   bool success() const {
125     return _success;
126   }
127 };
128 
129 static bool should_clear_soft_references() {
130   // Clear if one or more allocations have stalled
131   const bool stalled = ZHeap::heap()->is_alloc_stalled();
132   if (stalled) {
133     // Clear
134     return true;
135   }
136 
137   // Clear if implied by the GC cause
138   const GCCause::Cause cause = ZCollectedHeap::heap()->gc_cause();
139   if (cause == GCCause::_wb_full_gc ||
140       cause == GCCause::_metadata_GC_clear_soft_refs) {
141     // Clear
142     return true;
143   }
144 
145   // Don't clear
146   return false;
147 }
148 
149 static bool should_boost_worker_threads() {
150   // Boost worker threads if one or more allocations have stalled
151   const bool stalled = ZHeap::heap()->is_alloc_stalled();
152   if (stalled) {
153     // Boost
154     return true;
155   }
156 
157   // Boost worker threads if implied by the GC cause
158   const GCCause::Cause cause = ZCollectedHeap::heap()->gc_cause();
159   if (cause == GCCause::_wb_full_gc ||
160       cause == GCCause::_java_lang_system_gc ||
161       cause == GCCause::_metadata_GC_clear_soft_refs) {
162     // Boost
163     return true;
164   }
165 
166   // Don't boost
167   return false;
168 }
169 
170 class ZMarkStartClosure : public ZOperationClosure {
171 public:
172   virtual const char* name() const {
173     return "ZMarkStart";
174   }
175 
176   virtual bool needs_inactive_gc_locker() const {
177     return true;
178   }
179 
180   virtual bool do_operation() {
181     ZStatTimer timer(ZPhasePauseMarkStart);
182     ZServiceabilityMarkStartTracer tracer;
183 
184     // Set up soft reference policy
185     const bool clear = should_clear_soft_references();
186     ZHeap::heap()->set_soft_reference_policy(clear);
187 
188     // Set up boost mode
189     const bool boost = should_boost_worker_threads();
190     ZHeap::heap()->set_boost_worker_threads(boost);
191 
192     ZCollectedHeap::heap()->increment_total_collections(true /* full */);
193 
194     ZHeap::heap()->mark_start();
195     return true;
196   }
197 };
198 
199 class ZMarkEndClosure : public ZOperationClosure {
200 public:
201   virtual const char* name() const {
202     return "ZMarkEnd";
203   }
204 
205   virtual bool do_operation() {
206     ZStatTimer timer(ZPhasePauseMarkEnd);
207     ZServiceabilityMarkEndTracer tracer;
208 
209     return ZHeap::heap()->mark_end();
210   }
211 };
212 
213 class ZRelocateStartClosure : public ZOperationClosure {
214 public:
215   virtual const char* name() const {
216     return "ZRelocateStart";
217   }
218 
219   virtual bool needs_inactive_gc_locker() const {
220     return true;
221   }
222 
223   virtual bool do_operation() {
224     ZStatTimer timer(ZPhasePauseRelocateStart);
225     ZServiceabilityRelocateStartTracer tracer;
226 
227     ZHeap::heap()->relocate_start();
228     return true;
229   }
230 };
231 
232 ZDriver::ZDriver() :
233     _gc_cycle_port(),
234     _gc_locker_port() {
235   set_name("ZDriver");
236   create_and_start();
237 }
238 
239 bool ZDriver::vm_operation(ZOperationClosure* cl) {
240   for (;;) {
241     VM_ZOperation op(cl);
242     VMThread::execute(&op);
243     if (op.gc_locked()) {
244       // Wait for GC to become unlocked and restart the VM operation
245       ZStatTimer timer(ZCriticalPhaseGCLockerStall);
246       _gc_locker_port.wait();
247       continue;
248     }
249 
250     // Notify VM operation completed
251     _gc_locker_port.ack();
252 
253     return op.success();
254   }
255 }
256 
257 void ZDriver::collect(GCCause::Cause cause) {
258   switch (cause) {
259   case GCCause::_wb_young_gc:
260   case GCCause::_wb_conc_mark:
261   case GCCause::_wb_full_gc:
262   case GCCause::_dcmd_gc_run:
263   case GCCause::_java_lang_system_gc:
264   case GCCause::_full_gc_alot:
265   case GCCause::_scavenge_alot:
266   case GCCause::_jvmti_force_gc:
267   case GCCause::_metadata_GC_clear_soft_refs:
268     // Start synchronous GC
269     _gc_cycle_port.send_sync(cause);
270     break;
271 
272   case GCCause::_z_timer:
273   case GCCause::_z_warmup:
274   case GCCause::_z_allocation_rate:
275   case GCCause::_z_allocation_stall:
276   case GCCause::_z_proactive:
277   case GCCause::_metadata_GC_threshold:
278     // Start asynchronous GC
279     _gc_cycle_port.send_async(cause);
280     break;
281 
282   case GCCause::_gc_locker:
283     // Restart VM operation previously blocked by the GC locker
284     _gc_locker_port.signal();
285     break;
286 
287   default:
288     // Other causes not supported
289     fatal("Unsupported GC cause (%s)", GCCause::to_string(cause));
290     break;
291   }
292 }
293 
294 GCCause::Cause ZDriver::start_gc_cycle() {
295   // Wait for GC request
296   return _gc_cycle_port.receive();
297 }
298 
299 class ZDriverCycleScope : public StackObj {
300 private:
301   GCIdMark      _gc_id;
302   GCCauseSetter _gc_cause_setter;
303   ZStatTimer    _timer;
304 
305 public:
306   ZDriverCycleScope(GCCause::Cause cause) :
307       _gc_id(),
308       _gc_cause_setter(ZCollectedHeap::heap(), cause),
309       _timer(ZPhaseCycle) {
310     // Update statistics
311     ZStatCycle::at_start();
312   }
313 
314   ~ZDriverCycleScope() {
315     // Calculate boost factor
316     const double boost_factor = (double)ZHeap::heap()->nconcurrent_worker_threads() /
317                                 (double)ZHeap::heap()->nconcurrent_no_boost_worker_threads();
318 
319     // Update statistics
320     ZStatCycle::at_end(boost_factor);
321 
322     // Update data used by soft reference policy
323     Universe::update_heap_info_at_gc();
324   }
325 };
326 
327 void ZDriver::run_gc_cycle(GCCause::Cause cause) {
328   ZDriverCycleScope scope(cause);
329 
330   // Phase 1: Pause Mark Start
331   {
332     ZMarkStartClosure cl;
333     vm_operation(&cl);
334   }
335 
336   // Phase 2: Concurrent Mark
337   {
338     ZStatTimer timer(ZPhaseConcurrentMark);
339     ZHeap::heap()->mark();
340   }
341 
342   // Phase 3: Pause Mark End
343   {
344     ZMarkEndClosure cl;
345     while (!vm_operation(&cl)) {
346       // Phase 3.5: Concurrent Mark Continue
347       ZStatTimer timer(ZPhaseConcurrentMarkContinue);
348       ZHeap::heap()->mark();
349     }
350   }
351 
352   // Phase 4: Concurrent Process Non-Strong References
353   {
354     ZStatTimer timer(ZPhaseConcurrentProcessNonStrongReferences);
355     ZHeap::heap()->process_non_strong_references();
356   }
357 
358   // Phase 5: Concurrent Reset Relocation Set
359   {
360     ZStatTimer timer(ZPhaseConcurrentResetRelocationSet);
361     ZHeap::heap()->reset_relocation_set();
362   }
363 
364   // Phase 6: Concurrent Destroy Detached Pages
365   {
366     ZStatTimer timer(ZPhaseConcurrentDestroyDetachedPages);
367     ZHeap::heap()->destroy_detached_pages();
368   }
369 
370   // Phase 7: Concurrent Select Relocation Set
371   {
372     ZStatTimer timer(ZPhaseConcurrentSelectRelocationSet);
373     ZHeap::heap()->select_relocation_set();
374   }
375 
376   // Phase 8: Concurrent Prepare Relocation Set
377   {
378     ZStatTimer timer(ZPhaseConcurrentPrepareRelocationSet);
379     ZHeap::heap()->prepare_relocation_set();
380   }
381 
382   // Phase 9: Pause Relocate Start
383   {
384     ZRelocateStartClosure cl;
385     vm_operation(&cl);
386   }
387 
388   // Phase 10: Concurrent Relocate
389   {
390     ZStatTimer timer(ZPhaseConcurrentRelocated);
391     ZHeap::heap()->relocate();
392   }
393 }
394 
395 void ZDriver::end_gc_cycle() {
396   // Notify GC cycle completed
397   _gc_cycle_port.ack();
398 
399   // Check for out of memory condition
400   ZHeap::heap()->check_out_of_memory();
401 }
402 
403 void ZDriver::run_service() {
404   // Main loop
405   while (!should_terminate()) {
406     const GCCause::Cause cause = start_gc_cycle();
407     if (cause != GCCause::_no_gc) {
408       run_gc_cycle(cause);
409       end_gc_cycle();
410     }
411   }
412 }
413 
414 void ZDriver::stop_service() {
415   _gc_cycle_port.send_async(GCCause::_no_gc);
416 }