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 #ifndef SHARE_GC_Z_ZSTAT_HPP
  25 #define SHARE_GC_Z_ZSTAT_HPP
  26 
  27 #include "gc/shared/concurrentGCThread.hpp"
  28 #include "gc/shared/gcTimer.hpp"
  29 #include "gc/z/zMetronome.hpp"
  30 #include "logging/logHandle.hpp"
  31 #include "memory/allocation.hpp"
  32 #include "utilities/numberSeq.hpp"
  33 #include "utilities/ticks.hpp"
  34 
  35 class ZPage;
  36 class ZStatSampler;
  37 class ZStatSamplerHistory;
  38 struct ZStatCounterData;
  39 struct ZStatSamplerData;
  40 
  41 //
  42 // Stat unit printers
  43 //
  44 typedef void (*ZStatUnitPrinter)(LogTargetHandle log, const ZStatSampler&, const ZStatSamplerHistory&);
  45 
  46 void ZStatUnitTime(LogTargetHandle log, const ZStatSampler& sampler, const ZStatSamplerHistory& history);
  47 void ZStatUnitBytes(LogTargetHandle log, const ZStatSampler& sampler, const ZStatSamplerHistory& history);
  48 void ZStatUnitThreads(LogTargetHandle log, const ZStatSampler& sampler, const ZStatSamplerHistory& history);
  49 void ZStatUnitBytesPerSecond(LogTargetHandle log, const ZStatSampler& sampler, const ZStatSamplerHistory& history);
  50 void ZStatUnitOpsPerSecond(LogTargetHandle log, const ZStatSampler& sampler, const ZStatSamplerHistory& history);
  51 
  52 //
  53 // Stat value
  54 //
  55 class ZStatValue {
  56 private:
  57   static uintptr_t _base;
  58   static uint32_t  _cpu_offset;
  59 
  60   const char* const _group;
  61   const char* const _name;
  62   const uint32_t    _id;
  63   const uint32_t    _offset;
  64 
  65 protected:
  66   ZStatValue(const char* group,
  67              const char* name,
  68              uint32_t id,
  69              uint32_t size);
  70 
  71   template <typename T> T* get_cpu_local(uint32_t cpu) const;
  72 
  73 public:
  74   static void initialize();
  75 
  76   const char* group() const;
  77   const char* name() const;
  78   uint32_t id() const;
  79 };
  80 
  81 //
  82 // Stat iterable value
  83 //
  84 template <typename T>
  85 class ZStatIterableValue : public ZStatValue {
  86 private:
  87   static uint32_t _count;
  88   static T*       _first;
  89 
  90   T* _next;
  91 
  92   T* insert() const;
  93 
  94 protected:
  95   ZStatIterableValue(const char* group,
  96                      const char* name,
  97                      uint32_t size);
  98 
  99 public:
 100   static uint32_t count() {
 101     return _count;
 102   }
 103 
 104   static T* first() {
 105     return _first;
 106   }
 107 
 108   T* next() const {
 109     return _next;
 110   }
 111 };
 112 
 113 //
 114 // Stat sampler
 115 //
 116 class ZStatSampler : public ZStatIterableValue<ZStatSampler> {
 117 private:
 118   const ZStatUnitPrinter _printer;
 119 
 120 public:
 121   ZStatSampler(const char* group,
 122                const char* name,
 123                ZStatUnitPrinter printer);
 124 
 125   ZStatSamplerData* get() const;
 126   ZStatSamplerData collect_and_reset() const;
 127 
 128   ZStatUnitPrinter printer() const;
 129 };
 130 
 131 //
 132 // Stat counter
 133 //
 134 class ZStatCounter : public ZStatIterableValue<ZStatCounter> {
 135 private:
 136   const ZStatSampler _sampler;
 137 
 138 public:
 139   ZStatCounter(const char* group,
 140                const char* name,
 141                ZStatUnitPrinter printer);
 142 
 143   ZStatCounterData* get() const;
 144   void sample_and_reset() const;
 145 };
 146 
 147 //
 148 // Stat unsampled counter
 149 //
 150 class ZStatUnsampledCounter : public ZStatIterableValue<ZStatUnsampledCounter> {
 151 public:
 152   ZStatUnsampledCounter(const char* name);
 153 
 154   ZStatCounterData* get() const;
 155   ZStatCounterData collect_and_reset() const;
 156 };
 157 
 158 //
 159 // Stat MMU (Minimum Mutator Utilization)
 160 //
 161 class ZStatMMUPause {
 162 private:
 163   double _start;
 164   double _end;
 165 
 166 public:
 167   ZStatMMUPause();
 168   ZStatMMUPause(const Ticks& start, const Ticks& end);
 169 
 170   double end() const;
 171   double overlap(double start, double end) const;
 172 };
 173 
 174 class ZStatMMU {
 175 private:
 176   static size_t        _next;
 177   static size_t        _npauses;
 178   static ZStatMMUPause _pauses[200]; // Record the last 200 pauses
 179 
 180   static double _mmu_2ms;
 181   static double _mmu_5ms;
 182   static double _mmu_10ms;
 183   static double _mmu_20ms;
 184   static double _mmu_50ms;
 185   static double _mmu_100ms;
 186 
 187   static const ZStatMMUPause& pause(size_t index);
 188   static double calculate_mmu(double time_slice);
 189 
 190 public:
 191   static void register_pause(const Ticks& start, const Ticks& end);
 192 
 193   static void print();
 194 };
 195 
 196 //
 197 // Stat phases
 198 //
 199 class ZStatPhase {
 200 private:
 201   static ConcurrentGCTimer _timer;
 202 
 203 protected:
 204   const ZStatSampler _sampler;
 205 
 206   ZStatPhase(const char* group, const char* name);
 207 
 208   void log_start(LogTargetHandle log, bool thread = false) const;
 209   void log_end(LogTargetHandle log, const Tickspan& duration, bool thread = false) const;
 210 
 211 public:
 212   static ConcurrentGCTimer* timer();
 213 
 214   const char* name() const;
 215 
 216   virtual void register_start(const Ticks& start) const = 0;
 217   virtual void register_end(const Ticks& start, const Ticks& end) const = 0;
 218 };
 219 
 220 class ZStatPhaseCycle : public ZStatPhase {
 221 public:
 222   ZStatPhaseCycle(const char* name);
 223 
 224   virtual void register_start(const Ticks& start) const;
 225   virtual void register_end(const Ticks& start, const Ticks& end) const;
 226 };
 227 
 228 class ZStatPhasePause : public ZStatPhase {
 229 private:
 230   static Tickspan _max; // Max pause time
 231 
 232 public:
 233   ZStatPhasePause(const char* name);
 234 
 235   static const Tickspan& max();
 236 
 237   virtual void register_start(const Ticks& start) const;
 238   virtual void register_end(const Ticks& start, const Ticks& end) const;
 239 };
 240 
 241 class ZStatPhaseConcurrent : public ZStatPhase {
 242 public:
 243   ZStatPhaseConcurrent(const char* name);
 244 
 245   virtual void register_start(const Ticks& start) const;
 246   virtual void register_end(const Ticks& start, const Ticks& end) const;
 247 };
 248 
 249 class ZStatSubPhase : public ZStatPhase {
 250 public:
 251   ZStatSubPhase(const char* name);
 252 
 253   virtual void register_start(const Ticks& start) const;
 254   virtual void register_end(const Ticks& start, const Ticks& end) const;
 255 };
 256 
 257 class ZStatCriticalPhase : public ZStatPhase {
 258 private:
 259   const ZStatCounter _counter;
 260   const bool         _verbose;
 261 
 262 public:
 263   ZStatCriticalPhase(const char* name, bool verbose = true);
 264 
 265   virtual void register_start(const Ticks& start) const;
 266   virtual void register_end(const Ticks& start, const Ticks& end) const;
 267 };
 268 
 269 //
 270 // Stat timer
 271 //
 272 class ZStatTimerDisable : public StackObj {
 273 private:
 274   static __thread uint32_t _active;
 275 
 276 public:
 277   ZStatTimerDisable() {
 278     _active++;
 279   }
 280 
 281   ~ZStatTimerDisable() {
 282     _active--;
 283   }
 284 
 285   static bool is_active() {
 286     return _active > 0;
 287   }
 288 };
 289 
 290 class ZStatTimer : public StackObj {
 291 private:
 292   const bool        _enabled;
 293   const ZStatPhase& _phase;
 294   const Ticks       _start;
 295 
 296 public:
 297   ZStatTimer(const ZStatPhase& phase) :
 298       _enabled(!ZStatTimerDisable::is_active()),
 299       _phase(phase),
 300       _start(Ticks::now()) {
 301     if (_enabled) {
 302       _phase.register_start(_start);
 303     }
 304   }
 305 
 306   ~ZStatTimer() {
 307     if (_enabled) {
 308       const Ticks end = Ticks::now();
 309       _phase.register_end(_start, end);
 310     }
 311   }
 312 };
 313 
 314 //
 315 // Stat sample/increment
 316 //
 317 void ZStatSample(const ZStatSampler& sampler, uint64_t value, bool trace = ZStatisticsForceTrace);
 318 void ZStatInc(const ZStatCounter& counter, uint64_t increment = 1, bool trace = ZStatisticsForceTrace);
 319 void ZStatInc(const ZStatUnsampledCounter& counter, uint64_t increment = 1);
 320 
 321 //
 322 // Stat allocation rate
 323 //
 324 class ZStatAllocRate : public AllStatic {
 325 private:
 326   static const ZStatUnsampledCounter _counter;
 327   static TruncatedSeq                _rate;     // B/s
 328   static TruncatedSeq                _rate_avg; // B/s
 329 
 330 public:
 331   static const uint64_t sample_window_sec = 1; // seconds
 332   static const uint64_t sample_hz         = 10;
 333 
 334   static const ZStatUnsampledCounter& counter();
 335   static uint64_t sample_and_reset();
 336 
 337   static double avg();
 338   static double avg_sd();
 339 };
 340 
 341 //
 342 // Stat thread
 343 //
 344 class ZStat : public ConcurrentGCThread {
 345 private:
 346   static const uint64_t sample_hz = 1;
 347 
 348   ZMetronome _metronome;
 349 
 350   void sample_and_collect(ZStatSamplerHistory* history) const;
 351   bool should_print(LogTargetHandle log) const;
 352   void print(LogTargetHandle log, const ZStatSamplerHistory* history) const;
 353 
 354 protected:
 355   virtual void run_service();
 356   virtual void stop_service();
 357 
 358 public:
 359   ZStat();
 360 };
 361 
 362 //
 363 // Stat cycle
 364 //
 365 class ZStatCycle : public AllStatic {
 366 private:
 367   static uint64_t  _ncycles;
 368   static Ticks     _start_of_last;
 369   static Ticks     _end_of_last;
 370   static NumberSeq _normalized_duration;
 371 
 372 public:
 373   static void at_start();
 374   static void at_end(double boost_factor);
 375 
 376   static uint64_t ncycles();
 377   static const AbsSeq& normalized_duration();
 378   static double time_since_last();
 379 };
 380 
 381 //
 382 // Stat load
 383 //
 384 class ZStatLoad : public AllStatic {
 385 public:
 386   static void print();
 387 };
 388 
 389 //
 390 // Stat mark
 391 //
 392 class ZStatMark : public AllStatic {
 393 private:
 394   static size_t _nstripes;
 395   static size_t _nproactiveflush;
 396   static size_t _nterminateflush;
 397   static size_t _ntrycomplete;
 398   static size_t _ncontinue;
 399 
 400 public:
 401   static void set_at_mark_start(size_t nstripes);
 402   static void set_at_mark_end(size_t nproactiveflush,
 403                               size_t nterminateflush,
 404                               size_t ntrycomplete,
 405                               size_t ncontinue);
 406 
 407   static void print();
 408 };
 409 
 410 //
 411 // Stat relocation
 412 //
 413 class ZStatRelocation : public AllStatic {
 414 private:
 415   static size_t _relocating;
 416   static bool   _success;
 417 
 418 public:
 419   static void set_at_select_relocation_set(size_t relocating);
 420   static void set_at_relocate_end(bool success);
 421 
 422   static void print();
 423 };
 424 
 425 //
 426 // Stat nmethods
 427 //
 428 class ZStatNMethods : public AllStatic {
 429 public:
 430   static void print();
 431 };
 432 
 433 //
 434 // Stat metaspace
 435 //
 436 class ZStatMetaspace : public AllStatic {
 437 public:
 438   static void print();
 439 };
 440 
 441 //
 442 // Stat references
 443 //
 444 class ZStatReferences : public AllStatic {
 445 private:
 446   static struct ZCount {
 447     size_t encountered;
 448     size_t discovered;
 449     size_t enqueued;
 450   } _soft, _weak, _final, _phantom;
 451 
 452   static void set(ZCount* count, size_t encountered, size_t discovered, size_t enqueued);
 453   static void print(const char* name, const ZCount& ref);
 454 
 455 public:
 456   static void set_soft(size_t encountered, size_t discovered, size_t enqueued);
 457   static void set_weak(size_t encountered, size_t discovered, size_t enqueued);
 458   static void set_final(size_t encountered, size_t discovered, size_t enqueued);
 459   static void set_phantom(size_t encountered, size_t discovered, size_t enqueued);
 460 
 461   static void print();
 462 };
 463 
 464 //
 465 // Stat heap
 466 //
 467 class ZStatHeap : public AllStatic {
 468 private:
 469   static struct ZAtInitialize {
 470     size_t min_capacity;
 471     size_t max_capacity;
 472     size_t max_reserve;
 473   } _at_initialize;
 474 
 475   static struct ZAtMarkStart {
 476     size_t soft_max_capacity;
 477     size_t capacity;
 478     size_t reserve;
 479     size_t used;
 480     size_t free;
 481   } _at_mark_start;
 482 
 483   static struct ZAtMarkEnd {
 484     size_t capacity;
 485     size_t reserve;
 486     size_t allocated;
 487     size_t used;
 488     size_t free;
 489     size_t live;
 490     size_t garbage;
 491   } _at_mark_end;
 492 
 493   static struct ZAtRelocateStart {
 494     size_t capacity;
 495     size_t reserve;
 496     size_t garbage;
 497     size_t allocated;
 498     size_t reclaimed;
 499     size_t used;
 500     size_t free;
 501   } _at_relocate_start;
 502 
 503   static struct ZAtRelocateEnd {
 504     size_t capacity;
 505     size_t capacity_high;
 506     size_t capacity_low;
 507     size_t reserve;
 508     size_t reserve_high;
 509     size_t reserve_low;
 510     size_t garbage;
 511     size_t allocated;
 512     size_t reclaimed;
 513     size_t used;
 514     size_t used_high;
 515     size_t used_low;
 516     size_t free;
 517     size_t free_high;
 518     size_t free_low;
 519   } _at_relocate_end;
 520 
 521   static size_t available(size_t used);
 522   static size_t reserve(size_t used);
 523   static size_t free(size_t used);
 524 
 525 public:
 526   static void set_at_initialize(size_t min_capacity,
 527                                 size_t max_capacity,
 528                                 size_t max_reserve);
 529   static void set_at_mark_start(size_t soft_max_capacity,
 530                                 size_t capacity,
 531                                 size_t used);
 532   static void set_at_mark_end(size_t capacity,
 533                               size_t allocated,
 534                               size_t used);
 535   static void set_at_select_relocation_set(size_t live,
 536                                            size_t garbage,
 537                                            size_t reclaimed);
 538   static void set_at_relocate_start(size_t capacity,
 539                                     size_t allocated,
 540                                     size_t used);
 541   static void set_at_relocate_end(size_t capacity,
 542                                   size_t allocated,
 543                                   size_t reclaimed,
 544                                   size_t used,
 545                                   size_t used_high,
 546                                   size_t used_low);
 547 
 548   static size_t max_capacity();
 549   static size_t used_at_mark_start();
 550   static size_t used_at_relocate_end();
 551 
 552   static void print();
 553 };
 554 
 555 #endif // SHARE_GC_Z_ZSTAT_HPP