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