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(true /* initial */);
 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(false /* initial */);
 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 }