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