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