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