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