--- a/src/hotspot/share/gc/z/zDriver.cpp Tue Jan 29 10:23:38 2019 +0100
+++ b/src/hotspot/share/gc/z/zDriver.cpp Tue Jan 29 10:23:38 2019 +0100
@@ -44,7 +44,6 @@
static const ZStatPhaseConcurrent ZPhaseConcurrentProcessNonStrongReferences("Concurrent Process Non-Strong References");
static const ZStatPhaseConcurrent ZPhaseConcurrentResetRelocationSet("Concurrent Reset Relocation Set");
static const ZStatPhaseConcurrent ZPhaseConcurrentDestroyDetachedPages("Concurrent Destroy Detached Pages");
-static const ZStatPhasePause ZPhasePauseVerify("Pause Verify");
static const ZStatPhaseConcurrent ZPhaseConcurrentSelectRelocationSet("Concurrent Select Relocation Set");
static const ZStatPhaseConcurrent ZPhaseConcurrentPrepareRelocationSet("Concurrent Prepare Relocation Set");
static const ZStatPhasePause ZPhasePauseRelocateStart("Pause Relocate Start");
@@ -52,41 +51,26 @@
static const ZStatCriticalPhase ZCriticalPhaseGCLockerStall("GC Locker Stall", false /* verbose */);
static const ZStatSampler ZSamplerJavaThreads("System", "Java Threads", ZStatUnitThreads);
-class ZOperationClosure : public StackObj {
+class VM_ZOperation : public VM_Operation {
+private:
+ const uint _gc_id;
+ bool _gc_locked;
+ bool _success;
+
public:
- virtual const char* name() const = 0;
+ VM_ZOperation() :
+ _gc_id(GCId::current()),
+ _gc_locked(false),
+ _success(false) {}
virtual bool needs_inactive_gc_locker() const {
- // An inactive GC locker is needed in operations where we change the good
- // mask or move objects. Changing the good mask will invalidate all oops,
+ // An inactive GC locker is needed in operations where we change the bad
+ // mask or move objects. Changing the bad mask will invalidate all oops,
// which makes it conceptually the same thing as moving all objects.
return false;
}
virtual bool do_operation() = 0;
-};
-
-class VM_ZOperation : public VM_Operation {
-private:
- ZOperationClosure* _cl;
- uint _gc_id;
- bool _gc_locked;
- bool _success;
-
-public:
- VM_ZOperation(ZOperationClosure* cl) :
- _cl(cl),
- _gc_id(GCId::current()),
- _gc_locked(false),
- _success(false) {}
-
- virtual VMOp_Type type() const {
- return VMOp_ZOperation;
- }
-
- virtual const char* name() const {
- return _cl->name();
- }
virtual bool doit_prologue() {
Heap_lock->lock();
@@ -94,28 +78,28 @@
}
virtual void doit() {
- assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint");
-
- ZStatSample(ZSamplerJavaThreads, Threads::number_of_threads());
-
- // Setup GC id
- GCIdMark gcid(_gc_id);
+ // Abort if GC locker state is incompatible
+ if (needs_inactive_gc_locker() && GCLocker::check_active_before_gc()) {
+ _gc_locked = true;
+ return;
+ }
- if (_cl->needs_inactive_gc_locker() && GCLocker::check_active_before_gc()) {
- // GC locker is active, bail out
- _gc_locked = true;
- } else {
- // Execute operation
- IsGCActiveMark mark;
- _success = _cl->do_operation();
- }
+ // Setup GC id and active marker
+ GCIdMark gc_id_mark(_gc_id);
+ IsGCActiveMark gc_active_mark;
+
+ // Execute operation
+ _success = do_operation();
+
+ // Update statistics
+ ZStatSample(ZSamplerJavaThreads, Threads::number_of_threads());
}
virtual void doit_epilogue() {
Heap_lock->unlock();
}
- bool gc_locked() {
+ bool gc_locked() const {
return _gc_locked;
}
@@ -165,10 +149,10 @@
return false;
}
-class ZMarkStartClosure : public ZOperationClosure {
+class VM_ZMarkStart : public VM_ZOperation {
public:
- virtual const char* name() const {
- return "ZMarkStart";
+ virtual VMOp_Type type() const {
+ return VMOp_ZMarkStart;
}
virtual bool needs_inactive_gc_locker() const {
@@ -194,37 +178,23 @@
}
};
-class ZMarkEndClosure : public ZOperationClosure {
+class VM_ZMarkEnd : public VM_ZOperation {
public:
- virtual const char* name() const {
- return "ZMarkEnd";
+ virtual VMOp_Type type() const {
+ return VMOp_ZMarkEnd;
}
virtual bool do_operation() {
ZStatTimer timer(ZPhasePauseMarkEnd);
ZServiceabilityMarkEndTracer tracer;
-
return ZHeap::heap()->mark_end();
}
};
-class ZVerifyClosure : public ZOperationClosure {
+class VM_ZRelocateStart : public VM_ZOperation {
public:
- virtual const char* name() const {
- return "ZVerify";
- }
-
- virtual bool do_operation() {
- ZStatTimer timer(ZPhasePauseVerify);
- Universe::verify();
- return true;
- }
-};
-
-class ZRelocateStartClosure : public ZOperationClosure {
-public:
- virtual const char* name() const {
- return "ZRelocateStart";
+ virtual VMOp_Type type() const {
+ return VMOp_ZRelocateStart;
}
virtual bool needs_inactive_gc_locker() const {
@@ -234,7 +204,6 @@
virtual bool do_operation() {
ZStatTimer timer(ZPhasePauseRelocateStart);
ZServiceabilityRelocateStartTracer tracer;
-
ZHeap::heap()->relocate_start();
return true;
}
@@ -247,24 +216,6 @@
create_and_start();
}
-bool ZDriver::vm_operation(ZOperationClosure* cl) {
- for (;;) {
- VM_ZOperation op(cl);
- VMThread::execute(&op);
- if (op.gc_locked()) {
- // Wait for GC to become unlocked and restart the VM operation
- ZStatTimer timer(ZCriticalPhaseGCLockerStall);
- _gc_locker_port.wait();
- continue;
- }
-
- // Notify VM operation completed
- _gc_locker_port.ack();
-
- return op.success();
- }
-}
-
void ZDriver::collect(GCCause::Cause cause) {
switch (cause) {
case GCCause::_wb_young_gc:
@@ -302,19 +253,96 @@
}
}
-GCCause::Cause ZDriver::start_gc_cycle() {
- // Wait for GC request
- return _gc_cycle_port.receive();
+template <typename T>
+bool ZDriver::pause() {
+ for (;;) {
+ T op;
+ VMThread::execute(&op);
+ if (op.gc_locked()) {
+ // Wait for GC to become unlocked and restart the VM operation
+ ZStatTimer timer(ZCriticalPhaseGCLockerStall);
+ _gc_locker_port.wait();
+ continue;
+ }
+
+ // Notify VM operation completed
+ _gc_locker_port.ack();
+
+ return op.success();
+ }
+}
+
+void ZDriver::pause_mark_start() {
+ pause<VM_ZMarkStart>();
+}
+
+void ZDriver::concurrent_mark() {
+ ZStatTimer timer(ZPhaseConcurrentMark);
+ ZHeap::heap()->mark(true /* initial */);
+}
+
+bool ZDriver::pause_mark_end() {
+ return pause<VM_ZMarkEnd>();
+}
+
+void ZDriver::concurrent_mark_continue() {
+ ZStatTimer timer(ZPhaseConcurrentMarkContinue);
+ ZHeap::heap()->mark(false /* initial */);
+}
+
+void ZDriver::concurrent_process_non_strong_references() {
+ ZStatTimer timer(ZPhaseConcurrentProcessNonStrongReferences);
+ ZHeap::heap()->process_non_strong_references();
}
-class ZDriverCycleScope : public StackObj {
+void ZDriver::concurrent_reset_relocation_set() {
+ ZStatTimer timer(ZPhaseConcurrentResetRelocationSet);
+ ZHeap::heap()->reset_relocation_set();
+}
+
+void ZDriver::concurrent_destroy_detached_pages() {
+ ZStatTimer timer(ZPhaseConcurrentDestroyDetachedPages);
+ ZHeap::heap()->destroy_detached_pages();
+}
+
+void ZDriver::pause_verify() {
+ if (VerifyBeforeGC || VerifyDuringGC || VerifyAfterGC) {
+ VM_Verify op;
+ VMThread::execute(&op);
+ }
+}
+
+void ZDriver::concurrent_select_relocation_set() {
+ ZStatTimer timer(ZPhaseConcurrentSelectRelocationSet);
+ ZHeap::heap()->select_relocation_set();
+}
+
+void ZDriver::concurrent_prepare_relocation_set() {
+ ZStatTimer timer(ZPhaseConcurrentPrepareRelocationSet);
+ ZHeap::heap()->prepare_relocation_set();
+}
+
+void ZDriver::pause_relocate_start() {
+ pause<VM_ZRelocateStart>();
+}
+
+void ZDriver::concurrent_relocate() {
+ ZStatTimer timer(ZPhaseConcurrentRelocated);
+ ZHeap::heap()->relocate();
+}
+
+void ZDriver::check_out_of_memory() {
+ ZHeap::heap()->check_out_of_memory();
+}
+
+class ZDriverGCScope : public StackObj {
private:
GCIdMark _gc_id;
GCCauseSetter _gc_cause_setter;
ZStatTimer _timer;
public:
- ZDriverCycleScope(GCCause::Cause cause) :
+ ZDriverGCScope(GCCause::Cause cause) :
_gc_id(),
_gc_cause_setter(ZCollectedHeap::heap(), cause),
_timer(ZPhaseCycle) {
@@ -322,7 +350,7 @@
ZStatCycle::at_start();
}
- ~ZDriverCycleScope() {
+ ~ZDriverGCScope() {
// Calculate boost factor
const double boost_factor = (double)ZHeap::heap()->nconcurrent_worker_threads() /
(double)ZHeap::heap()->nconcurrent_no_boost_worker_threads();
@@ -335,96 +363,63 @@
}
};
-void ZDriver::run_gc_cycle(GCCause::Cause cause) {
- ZDriverCycleScope scope(cause);
+void ZDriver::gc(GCCause::Cause cause) {
+ ZDriverGCScope scope(cause);
// Phase 1: Pause Mark Start
- {
- ZMarkStartClosure cl;
- vm_operation(&cl);
- }
+ pause_mark_start();
// Phase 2: Concurrent Mark
- {
- ZStatTimer timer(ZPhaseConcurrentMark);
- ZHeap::heap()->mark(true /* initial */);
- }
+ concurrent_mark();
// Phase 3: Pause Mark End
- {
- ZMarkEndClosure cl;
- while (!vm_operation(&cl)) {
- // Phase 3.5: Concurrent Mark Continue
- ZStatTimer timer(ZPhaseConcurrentMarkContinue);
- ZHeap::heap()->mark(false /* initial */);
- }
+ while (!pause_mark_end()) {
+ // Phase 3.5: Concurrent Mark Continue
+ concurrent_mark_continue();
}
// Phase 4: Concurrent Process Non-Strong References
- {
- ZStatTimer timer(ZPhaseConcurrentProcessNonStrongReferences);
- ZHeap::heap()->process_non_strong_references();
- }
+ concurrent_process_non_strong_references();
// Phase 5: Concurrent Reset Relocation Set
- {
- ZStatTimer timer(ZPhaseConcurrentResetRelocationSet);
- ZHeap::heap()->reset_relocation_set();
- }
+ concurrent_reset_relocation_set();
// Phase 6: Concurrent Destroy Detached Pages
- {
- ZStatTimer timer(ZPhaseConcurrentDestroyDetachedPages);
- ZHeap::heap()->destroy_detached_pages();
- }
+ concurrent_destroy_detached_pages();
// Phase 7: Pause Verify
- if (VerifyBeforeGC || VerifyDuringGC || VerifyAfterGC) {
- ZVerifyClosure cl;
- vm_operation(&cl);
- }
+ pause_verify();
// Phase 8: Concurrent Select Relocation Set
- {
- ZStatTimer timer(ZPhaseConcurrentSelectRelocationSet);
- ZHeap::heap()->select_relocation_set();
- }
+ concurrent_select_relocation_set();
// Phase 9: Concurrent Prepare Relocation Set
- {
- ZStatTimer timer(ZPhaseConcurrentPrepareRelocationSet);
- ZHeap::heap()->prepare_relocation_set();
- }
+ concurrent_prepare_relocation_set();
// Phase 10: Pause Relocate Start
- {
- ZRelocateStartClosure cl;
- vm_operation(&cl);
- }
+ pause_relocate_start();
// Phase 11: Concurrent Relocate
- {
- ZStatTimer timer(ZPhaseConcurrentRelocated);
- ZHeap::heap()->relocate();
- }
-}
-
-void ZDriver::end_gc_cycle() {
- // Notify GC cycle completed
- _gc_cycle_port.ack();
-
- // Check for out of memory condition
- ZHeap::heap()->check_out_of_memory();
+ concurrent_relocate();
}
void ZDriver::run_service() {
// Main loop
while (!should_terminate()) {
- const GCCause::Cause cause = start_gc_cycle();
- if (cause != GCCause::_no_gc) {
- run_gc_cycle(cause);
- end_gc_cycle();
+ // Wait for GC request
+ const GCCause::Cause cause = _gc_cycle_port.receive();
+ if (cause == GCCause::_no_gc) {
+ continue;
}
+
+ // Run GC
+ gc(cause);
+
+ // Notify GC completed
+ _gc_cycle_port.ack();
+
+ // Check for out of memory condition
+ check_out_of_memory();
}
}