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