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