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