--- old/src/hotspot/share/gc/z/zCollectedHeap.cpp 2018-03-06 13:23:11.961087108 +0100 +++ new/src/hotspot/share/gc/z/zCollectedHeap.cpp 2018-03-06 13:23:11.803080324 +0100 @@ -228,7 +228,7 @@ } jlong ZCollectedHeap::millis_since_last_gc() { - return ZStatPhaseCycle::time_since_last() / MILLIUNITS; + return ZStatCycle::time_since_last() / MILLIUNITS; } void ZCollectedHeap::gc_threads_do(ThreadClosure* tc) const { --- old/src/hotspot/share/gc/z/zDirector.cpp 2018-03-06 13:23:12.258099861 +0100 +++ new/src/hotspot/share/gc/z/zDirector.cpp 2018-03-06 13:23:12.087092518 +0100 @@ -49,11 +49,11 @@ } bool ZDirector::is_first() const { - return ZStatPhaseCycle::ncycles() == 0; + return ZStatCycle::ncycles() == 0; } bool ZDirector::is_warm() const { - return ZStatPhaseCycle::ncycles() >= 3; + return ZStatCycle::ncycles() >= 3; } bool ZDirector::rule_timer() const { @@ -63,7 +63,7 @@ } // Perform GC if timer has expired. - const double time_since_last_gc = ZStatPhaseCycle::time_since_last(); + const double time_since_last_gc = ZStatCycle::time_since_last(); const double time_until_gc = ZCollectionInterval - time_since_last_gc; log_debug(gc, director)("Rule: Timer, Interval: %us, TimeUntilGC: %.3lfs", @@ -83,7 +83,7 @@ // duration, which is needed by the other rules. const size_t max_capacity = ZHeap::heap()->max_capacity(); const size_t used = ZHeap::heap()->used(); - const double used_threshold_percent = (ZStatPhaseCycle::ncycles() + 1) * 0.1; + const double used_threshold_percent = (ZStatCycle::ncycles() + 1) * 0.1; const size_t used_threshold = max_capacity * used_threshold_percent; log_debug(gc, director)("Rule: Warmup %.0f%%, Used: " SIZE_FORMAT "MB, UsedThreshold: " SIZE_FORMAT "MB", @@ -124,7 +124,7 @@ // Calculate max duration of a GC cycle. The duration of GC is a moving // average, we add ~3.3 sigma to account for the GC duration variance. - const AbsSeq& duration_of_gc = ZStatPhaseCycle::duration(); + const AbsSeq& duration_of_gc = ZStatCycle::duration(); const double max_duration_of_gc = duration_of_gc.davg() + (duration_of_gc.dsd() * one_in_1000); // Calculate time until GC given the time until OOM and max duration of GC. @@ -158,7 +158,7 @@ const size_t used_increase_threshold = ZHeap::heap()->max_capacity() * 0.10; // 10% const size_t used_threshold = used_after_last_gc + used_increase_threshold; const size_t used = ZHeap::heap()->used(); - const double time_since_last_gc = ZStatPhaseCycle::time_since_last(); + const double time_since_last_gc = ZStatCycle::time_since_last(); const double time_since_last_gc_threshold = 5 * 60; // 5 minutes if (used < used_threshold && time_since_last_gc < time_since_last_gc_threshold) { // Don't even consider doing a proactive GC @@ -167,7 +167,7 @@ const double assumed_throughput_drop_during_gc = 0.50; // 50% const double acceptable_throughput_drop = 0.01; // 1% - const AbsSeq& duration_of_gc = ZStatPhaseCycle::duration(); + const AbsSeq& duration_of_gc = ZStatCycle::duration(); const double max_duration_of_gc = duration_of_gc.davg() + (duration_of_gc.dsd() * one_in_1000); const double acceptable_gc_interval = max_duration_of_gc * ((assumed_throughput_drop_during_gc / acceptable_throughput_drop) - 1.0); const double time_until_gc = acceptable_gc_interval - time_since_last_gc; --- old/src/hotspot/share/gc/z/zDriver.cpp 2018-03-06 13:23:12.556112656 +0100 +++ new/src/hotspot/share/gc/z/zDriver.cpp 2018-03-06 13:23:12.388105442 +0100 @@ -293,9 +293,22 @@ _gc_cause_setter(ZCollectedHeap::heap(), cause), _soft_ref_policy(cause), _timer(ZPhaseCycle) { + // Update statistics + ZStatCycle::at_start(); + + // Set boost mode const bool boost = should_boost_worker_threads(cause); ZHeap::heap()->set_boost_worker_threads(boost); } + + ~ZDriverCycleScope() { + // Calculate boost factor + const double boost_factor = (double)ZHeap::heap()->nconcurrent_worker_threads() / + (double)ZHeap::heap()->nconcurrent_no_boost_worker_threads(); + + // Update statistics + ZStatCycle::at_end(boost_factor); + } }; void ZDriver::run_gc_cycle(GCCause::Cause cause) { --- old/src/hotspot/share/gc/z/zHeap.cpp 2018-03-06 13:23:12.839124807 +0100 +++ new/src/hotspot/share/gc/z/zHeap.cpp 2018-03-06 13:23:12.672117637 +0100 @@ -194,6 +194,14 @@ return _pagetable.addr(); } +uint ZHeap::nconcurrent_worker_threads() const { + return _workers.nconcurrent(); +} + +uint ZHeap::nconcurrent_no_boost_worker_threads() const { + return _workers.nconcurrent_no_boost(); +} + void ZHeap::set_boost_worker_threads(bool boost) { _workers.set_boost(boost); } --- old/src/hotspot/share/gc/z/zHeap.hpp 2018-03-06 13:23:13.146137989 +0100 +++ new/src/hotspot/share/gc/z/zHeap.hpp 2018-03-06 13:23:12.975130647 +0100 @@ -105,6 +105,8 @@ ZPageTableEntry* pagetable_addr() const; // Workers + uint nconcurrent_worker_threads() const; + uint nconcurrent_no_boost_worker_threads() const; void set_boost_worker_threads(bool boost); void worker_threads_do(ThreadClosure* tc) const; void print_worker_threads_on(outputStream* st) const; --- old/src/hotspot/share/gc/z/zStat.cpp 2018-03-06 13:23:13.442150699 +0100 +++ new/src/hotspot/share/gc/z/zStat.cpp 2018-03-06 13:23:13.273143442 +0100 @@ -605,32 +605,9 @@ return _sampler.name(); } -uint64_t ZStatPhaseCycle::_ncycles = 0; -Ticks ZStatPhaseCycle::_end_of_last; -NumberSeq ZStatPhaseCycle::_duration(0.3 /* alpha */); - ZStatPhaseCycle::ZStatPhaseCycle(const char* name) : ZStatPhase("Collector", name) {} -uint64_t ZStatPhaseCycle::ncycles() { - return _ncycles; -} - -const AbsSeq& ZStatPhaseCycle::duration() { - return _duration; -} - -double ZStatPhaseCycle::time_since_last() { - if (_ncycles == 0) { - // Return time since VM start-up - return os::elapsedTime(); - } - - const Ticks now = Ticks::now(); - const Tickspan time_since_last = now - _end_of_last; - return TicksToTimeHelper::seconds(time_since_last); -} - void ZStatPhaseCycle::register_start(const Ticks& start) const { timer()->register_gc_start(start); @@ -657,10 +634,6 @@ const Tickspan duration = end - start; ZStatSample(_sampler, duration.value()); - _duration.add(TicksToTimeHelper::seconds(duration)); - _end_of_last = end; - _ncycles++; - ZStatLoad::print(); ZStatMMU::print(); ZStatMark::print(); @@ -1034,6 +1007,49 @@ }; // +// Stat cycle +// +uint64_t ZStatCycle::_ncycles = 0; +Ticks ZStatCycle::_start_of_last; +Ticks ZStatCycle::_end_of_last; +NumberSeq ZStatCycle::_duration(0.3 /* alpha */); + +void ZStatCycle::at_start() { + _start_of_last = Ticks::now(); +} + +void ZStatCycle::at_end(double boost_factor) { + _end_of_last = Ticks::now(); + _ncycles++; + + // Calculate cycle duration. The duration is normalized using the boost + // factor to avoid artificial deflation of the duration when boost mode + // is enabled. + const double duration = TicksToTimeHelper::seconds(_end_of_last - _start_of_last); + const double normalized_duration = duration * boost_factor; + _duration.add(normalized_duration); +} + +uint64_t ZStatCycle::ncycles() { + return _ncycles; +} + +const AbsSeq& ZStatCycle::duration() { + return _duration; +} + +double ZStatCycle::time_since_last() { + if (_ncycles == 0) { + // Return time since VM start-up + return os::elapsedTime(); + } + + const Ticks now = Ticks::now(); + const Tickspan time_since_last = now - _end_of_last; + return TicksToTimeHelper::seconds(time_since_last); +} + +// // Stat load // void ZStatLoad::print() { --- old/src/hotspot/share/gc/z/zStat.hpp 2018-03-06 13:23:13.757164224 +0100 +++ new/src/hotspot/share/gc/z/zStat.hpp 2018-03-06 13:23:13.588156967 +0100 @@ -218,18 +218,9 @@ }; class ZStatPhaseCycle : public ZStatPhase { -private: - static uint64_t _ncycles; - static Ticks _end_of_last; - static NumberSeq _duration; - public: ZStatPhaseCycle(const char* name); - static uint64_t ncycles(); - static const AbsSeq& duration(); - static double time_since_last(); - virtual void register_start(const Ticks& start) const; virtual void register_end(const Ticks& start, const Ticks& end) const; }; @@ -345,6 +336,25 @@ }; // +// Stat cycle +// +class ZStatCycle : public AllStatic { +private: + static uint64_t _ncycles; + static Ticks _start_of_last; + static Ticks _end_of_last; + static NumberSeq _duration; + +public: + static void at_start(); + static void at_end(double boost_factor); + + static uint64_t ncycles(); + static const AbsSeq& duration(); + static double time_since_last(); +}; + +// // Stat load // class ZStatLoad : public AllStatic { --- old/src/hotspot/share/gc/z/zWorkers.hpp 2018-03-06 13:23:14.067177535 +0100 +++ new/src/hotspot/share/gc/z/zWorkers.hpp 2018-03-06 13:23:13.899170321 +0100 @@ -45,7 +45,9 @@ ZWorkers(); uint nparallel() const; + uint nparallel_no_boost() const; uint nconcurrent() const; + uint nconcurrent_no_boost() const; uint nworkers() const; void set_boost(bool boost); --- old/src/hotspot/share/gc/z/zWorkers.inline.hpp 2018-03-06 13:23:14.360190115 +0100 +++ new/src/hotspot/share/gc/z/zWorkers.inline.hpp 2018-03-06 13:23:14.190182816 +0100 @@ -28,11 +28,19 @@ #include "utilities/globalDefinitions.hpp" inline uint ZWorkers::nparallel() const { - return _boost ? nworkers() : ParallelGCThreads; + return _boost ? nworkers() : nparallel_no_boost(); +} + +inline uint ZWorkers::nparallel_no_boost() const { + return ParallelGCThreads; } inline uint ZWorkers::nconcurrent() const { - return _boost ? nworkers() : ConcGCThreads; + return _boost ? nworkers() : nconcurrent_no_boost(); +} + +inline uint ZWorkers::nconcurrent_no_boost() const { + return ConcGCThreads; } inline uint ZWorkers::nworkers() const {