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::OTHER);
 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 class ZMarkStartClosure : public ZOperationClosure {
 130 public:
 131   virtual const char* name() const {
 132     return "ZMarkStart";
 133   }
 134 
 135   virtual bool needs_inactive_gc_locker() const {
 136     return true;
 137   }
 138 
 139   virtual bool do_operation() {
 140     ZStatTimer timer(ZPhasePauseMarkStart);
 141     ZServiceabilityMarkStartTracer tracer;
 142 
 143     ZCollectedHeap::heap()->increment_total_collections(true /* full */);
 144 
 145     ZHeap::heap()->mark_start();
 146     return true;
 147   }
 148 };
 149 
 150 class ZMarkEndClosure : public ZOperationClosure {
 151 public:
 152   virtual const char* name() const {
 153     return "ZMarkEnd";
 154   }
 155 
 156   virtual bool do_operation() {
 157     ZStatTimer timer(ZPhasePauseMarkEnd);
 158     ZServiceabilityMarkEndTracer tracer;
 159 
 160     return ZHeap::heap()->mark_end();
 161   }
 162 };
 163 
 164 class ZRelocateStartClosure : public ZOperationClosure {
 165 public:
 166   virtual const char* name() const {
 167     return "ZRelocateStart";
 168   }
 169 
 170   virtual bool needs_inactive_gc_locker() const {
 171     return true;
 172   }
 173 
 174   virtual bool do_operation() {
 175     ZStatTimer timer(ZPhasePauseRelocateStart);
 176     ZServiceabilityRelocateStartTracer tracer;
 177 
 178     ZHeap::heap()->relocate_start();
 179     return true;
 180   }
 181 };
 182 
 183 ZDriver::ZDriver() :
 184     _gc_cycle_port(),
 185     _gc_locker_port() {
 186   set_name("ZDriver");
 187   create_and_start();
 188 }
 189 
 190 bool ZDriver::vm_operation(ZOperationClosure* cl) {
 191   for (;;) {
 192     VM_ZOperation op(cl);
 193     VMThread::execute(&op);
 194     if (op.gc_locked()) {
 195       // Wait for GC to become unlocked and restart the VM operation
 196       ZStatTimer timer(ZCriticalPhaseGCLockerStall);
 197       _gc_locker_port.wait();
 198       continue;
 199     }
 200 
 201     // Notify VM operation completed
 202     _gc_locker_port.ack();
 203 
 204     return op.success();
 205   }
 206 }
 207 
 208 void ZDriver::collect(GCCause::Cause cause) {
 209   switch (cause) {
 210   case GCCause::_wb_young_gc:
 211   case GCCause::_wb_conc_mark:
 212   case GCCause::_wb_full_gc:
 213   case GCCause::_dcmd_gc_run:
 214   case GCCause::_java_lang_system_gc:
 215   case GCCause::_full_gc_alot:
 216   case GCCause::_scavenge_alot:
 217   case GCCause::_jvmti_force_gc:
 218   case GCCause::_metadata_GC_clear_soft_refs:
 219     // Start synchronous GC
 220     _gc_cycle_port.send_sync(cause);
 221     break;
 222 
 223   case GCCause::_z_timer:
 224   case GCCause::_z_warmup:
 225   case GCCause::_z_allocation_rate:
 226   case GCCause::_z_allocation_stall:
 227   case GCCause::_z_proactive:
 228   case GCCause::_metadata_GC_threshold:
 229     // Start asynchronous GC
 230     _gc_cycle_port.send_async(cause);
 231     break;
 232 
 233   case GCCause::_gc_locker:
 234     // Restart VM operation previously blocked by the GC locker
 235     _gc_locker_port.signal();
 236     break;
 237 
 238   default:
 239     // Other causes not supported
 240     fatal("Unsupported GC cause (%s)", GCCause::to_string(cause));
 241     break;
 242   }
 243 }
 244 
 245 GCCause::Cause ZDriver::start_gc_cycle() {
 246   // Wait for GC request
 247   return _gc_cycle_port.receive();
 248 }
 249 
 250 class ZSoftReferencePolicyScope : public StackObj {
 251 private:
 252   bool should_clear_soft_reference(GCCause::Cause cause) const {
 253     const bool clear = ZCollectedHeap::heap()->soft_ref_policy()->should_clear_all_soft_refs();
 254 
 255     // Clear all soft reference if the policy says so, or if
 256     // the GC cause indicates that we're running low on memory.
 257     return clear ||
 258            cause == GCCause::_z_allocation_stall ||
 259            cause == GCCause::_metadata_GC_clear_soft_refs;
 260   }
 261 
 262   void clear_should_clear_soft_reference() const {
 263     ZCollectedHeap::heap()->soft_ref_policy()->set_should_clear_all_soft_refs(false);
 264   }
 265 
 266 public:
 267   ZSoftReferencePolicyScope(GCCause::Cause cause) {
 268     const bool clear = should_clear_soft_reference(cause);
 269     ZHeap::heap()->set_soft_reference_policy(clear);
 270     clear_should_clear_soft_reference();
 271   }
 272 
 273   ~ZSoftReferencePolicyScope() {
 274     Universe::update_heap_info_at_gc();
 275   }
 276 };
 277 
 278 class ZDriverCycleScope : public StackObj {
 279 private:
 280   GCIdMark                  _gc_id;
 281   GCCauseSetter             _gc_cause_setter;
 282   ZSoftReferencePolicyScope _soft_ref_policy;
 283   ZStatTimer                _timer;
 284 
 285   bool should_boost_worker_threads(GCCause::Cause cause) const {
 286     return cause == GCCause::_java_lang_system_gc ||
 287            cause == GCCause::_z_allocation_stall;
 288   }
 289 
 290 public:
 291   ZDriverCycleScope(GCCause::Cause cause) :
 292       _gc_id(),
 293       _gc_cause_setter(ZCollectedHeap::heap(), cause),
 294       _soft_ref_policy(cause),
 295       _timer(ZPhaseCycle) {
 296     // Update statistics
 297     ZStatCycle::at_start();
 298 
 299     // Set boost mode
 300     const bool boost = should_boost_worker_threads(cause);
 301     ZHeap::heap()->set_boost_worker_threads(boost);
 302   }
 303 
 304   ~ZDriverCycleScope() {
 305     // Calculate boost factor
 306     const double boost_factor = (double)ZHeap::heap()->nconcurrent_worker_threads() /
 307                                 (double)ZHeap::heap()->nconcurrent_no_boost_worker_threads();
 308 
 309     // Update statistics
 310     ZStatCycle::at_end(boost_factor);
 311   }
 312 };
 313 
 314 void ZDriver::run_gc_cycle(GCCause::Cause cause) {
 315   ZDriverCycleScope scope(cause);
 316 
 317   // Phase 1: Pause Mark Start
 318   {
 319     ZMarkStartClosure cl;
 320     vm_operation(&cl);
 321   }
 322 
 323   // Phase 2: Concurrent Mark
 324   {
 325     ZStatTimer timer(ZPhaseConcurrentMark);
 326     ZHeap::heap()->mark();
 327   }
 328 
 329   // Phase 3: Pause Mark End
 330   {
 331     ZMarkEndClosure cl;
 332     while (!vm_operation(&cl)) {
 333       // Phase 3.5: Concurrent Mark Continue
 334       ZStatTimer timer(ZPhaseConcurrentMarkContinue);
 335       ZHeap::heap()->mark();
 336     }
 337   }
 338 
 339   // Phase 4: Concurrent Process Non-Strong References
 340   {
 341     ZStatTimer timer(ZPhaseConcurrentProcessNonStrongReferences);
 342     ZHeap::heap()->process_non_strong_references();
 343   }
 344 
 345   // Phase 5: Concurrent Reset Relocation Set
 346   {
 347     ZStatTimer timer(ZPhaseConcurrentResetRelocationSet);
 348     ZHeap::heap()->reset_relocation_set();
 349   }
 350 
 351   // Phase 6: Concurrent Destroy Detached Pages
 352   {
 353     ZStatTimer timer(ZPhaseConcurrentDestroyDetachedPages);
 354     ZHeap::heap()->destroy_detached_pages();
 355   }
 356 
 357   // Phase 7: Concurrent Select Relocation Set
 358   {
 359     ZStatTimer timer(ZPhaseConcurrentSelectRelocationSet);
 360     ZHeap::heap()->select_relocation_set();
 361   }
 362 
 363   // Phase 8: Prepare Relocation Set
 364   {
 365     ZStatTimer timer(ZPhaseConcurrentPrepareRelocationSet);
 366     ZHeap::heap()->prepare_relocation_set();
 367   }
 368 
 369   // Phase 9: Pause Relocate Start
 370   {
 371     ZRelocateStartClosure cl;
 372     vm_operation(&cl);
 373   }
 374 
 375   // Phase 10: Concurrent Relocate
 376   {
 377     ZStatTimer timer(ZPhaseConcurrentRelocated);
 378     ZHeap::heap()->relocate();
 379   }
 380 }
 381 
 382 void ZDriver::end_gc_cycle() {
 383   // Notify GC cycle completed
 384   _gc_cycle_port.ack();
 385 
 386   // Check for out of memory condition
 387   ZHeap::heap()->check_out_of_memory();
 388 }
 389 
 390 void ZDriver::run_service() {
 391   // Main loop
 392   while (!should_terminate()) {
 393     const GCCause::Cause cause = start_gc_cycle();
 394     if (cause != GCCause::_no_gc) {
 395       run_gc_cycle(cause);
 396       end_gc_cycle();
 397     }
 398   }
 399 }
 400 
 401 void ZDriver::stop_service() {
 402   _gc_cycle_port.send_async(GCCause::_no_gc);
 403 }