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