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