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