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 ZStatTimer : public StackObj { 273 private: 274 const ZStatPhase& _phase; 275 const Ticks _start; 276 277 public: 278 ZStatTimer(const ZStatPhase& phase) : 279 _phase(phase), 280 _start(Ticks::now()) { 281 _phase.register_start(_start); 282 } 283 284 ~ZStatTimer() { 285 const Ticks end = Ticks::now(); 286 _phase.register_end(_start, end); 287 } 288 }; 289 290 // 291 // Stat sample/increment 292 // 293 void ZStatSample(const ZStatSampler& sampler, uint64_t value, bool trace = ZStatisticsForceTrace); 294 void ZStatInc(const ZStatCounter& counter, uint64_t increment = 1, bool trace = ZStatisticsForceTrace); 295 void ZStatInc(const ZStatUnsampledCounter& counter, uint64_t increment = 1); 296 297 // 298 // Stat allocation rate 299 // 300 class ZStatAllocRate : public AllStatic { 301 private: 302 static const ZStatUnsampledCounter _counter; 303 static TruncatedSeq _rate; // B/s 304 static TruncatedSeq _rate_avg; // B/s 305 306 public: 307 static const uint64_t sample_window_sec = 1; // seconds 308 static const uint64_t sample_hz = 10; 309 310 static const ZStatUnsampledCounter& counter(); 311 static uint64_t sample_and_reset(); 312 313 static double avg(); 314 static double avg_sd(); 315 }; 316 317 // 318 // Stat thread 319 // 320 class ZStat : public ConcurrentGCThread { 321 private: 322 static const uint64_t sample_hz = 1; 323 324 ZMetronome _metronome; 325 326 void sample_and_collect(ZStatSamplerHistory* history) const; 327 bool should_print(LogTargetHandle log) const; 328 void print(LogTargetHandle log, const ZStatSamplerHistory* history) const; 329 330 protected: 331 virtual void run_service(); 332 virtual void stop_service(); 333 334 public: 335 ZStat(); 336 }; 337 338 // 339 // Stat cycle 340 // 341 class ZStatCycle : public AllStatic { 342 private: 343 static uint64_t _ncycles; 344 static Ticks _start_of_last; 345 static Ticks _end_of_last; 346 static NumberSeq _normalized_duration; 347 348 public: 349 static void at_start(); 350 static void at_end(double boost_factor); 351 352 static uint64_t ncycles(); 353 static const AbsSeq& normalized_duration(); 354 static double time_since_last(); 355 }; 356 357 // 358 // Stat load 359 // 360 class ZStatLoad : public AllStatic { 361 public: 362 static void print(); 363 }; 364 365 // 366 // Stat mark 367 // 368 class ZStatMark : public AllStatic { 369 private: 370 static size_t _nstripes; 371 static size_t _nproactiveflush; 372 static size_t _nterminateflush; 373 static size_t _ntrycomplete; 374 static size_t _ncontinue; 375 376 public: 377 static void set_at_mark_start(size_t nstripes); 378 static void set_at_mark_end(size_t nproactiveflush, 379 size_t nterminateflush, 380 size_t ntrycomplete, 381 size_t ncontinue); 382 383 static void print(); 384 }; 385 386 // 387 // Stat relocation 388 // 389 class ZStatRelocation : public AllStatic { 390 private: 391 static size_t _relocating; 392 static bool _success; 393 394 public: 395 static void set_at_select_relocation_set(size_t relocating); 396 static void set_at_relocate_end(bool success); 397 398 static void print(); 399 }; 400 401 // 402 // Stat nmethods 403 // 404 class ZStatNMethods : public AllStatic { 405 public: 406 static void print(); 407 }; 408 409 // 410 // Stat metaspace 411 // 412 class ZStatMetaspace : public AllStatic { 413 public: 414 static void print(); 415 }; 416 417 // 418 // Stat references 419 // 420 class ZStatReferences : public AllStatic { 421 private: 422 static struct ZCount { 423 size_t encountered; 424 size_t discovered; 425 size_t enqueued; 426 } _soft, _weak, _final, _phantom; 427 428 static void set(ZCount* count, size_t encountered, size_t discovered, size_t enqueued); 429 static void print(const char* name, const ZCount& ref); 430 431 public: 432 static void set_soft(size_t encountered, size_t discovered, size_t enqueued); 433 static void set_weak(size_t encountered, size_t discovered, size_t enqueued); 434 static void set_final(size_t encountered, size_t discovered, size_t enqueued); 435 static void set_phantom(size_t encountered, size_t discovered, size_t enqueued); 436 437 static void print(); 438 }; 439 440 // 441 // Stat heap 442 // 443 class ZStatHeap : public AllStatic { 444 private: 445 static struct ZAtInitialize { 446 size_t max_capacity; 447 size_t max_reserve; 448 } _at_initialize; 449 450 static struct ZAtMarkStart { 451 size_t capacity; 452 size_t reserve; 453 size_t used; 454 size_t free; 455 } _at_mark_start; 456 457 static struct ZAtMarkEnd { 458 size_t capacity; 459 size_t reserve; 460 size_t allocated; 461 size_t used; 462 size_t free; 463 size_t live; 464 size_t garbage; 465 } _at_mark_end; 466 467 static struct ZAtRelocateStart { 468 size_t capacity; 469 size_t reserve; 470 size_t garbage; 471 size_t allocated; 472 size_t reclaimed; 473 size_t used; 474 size_t free; 475 } _at_relocate_start; 476 477 static struct ZAtRelocateEnd { 478 size_t capacity; 479 size_t capacity_high; 480 size_t capacity_low; 481 size_t reserve; 482 size_t reserve_high; 483 size_t reserve_low; 484 size_t garbage; 485 size_t allocated; 486 size_t reclaimed; 487 size_t used; 488 size_t used_high; 489 size_t used_low; 490 size_t free; 491 size_t free_high; 492 size_t free_low; 493 } _at_relocate_end; 494 495 static size_t available(size_t used); 496 static size_t reserve(size_t used); 497 static size_t free(size_t used); 498 499 public: 500 static void set_at_initialize(size_t max_capacity, 501 size_t max_reserve); 502 static void set_at_mark_start(size_t capacity, 503 size_t used); 504 static void set_at_mark_end(size_t capacity, 505 size_t allocated, 506 size_t used); 507 static void set_at_select_relocation_set(size_t live, 508 size_t garbage, 509 size_t reclaimed); 510 static void set_at_relocate_start(size_t capacity, 511 size_t allocated, 512 size_t used); 513 static void set_at_relocate_end(size_t capacity, 514 size_t allocated, 515 size_t reclaimed, 516 size_t used, 517 size_t used_high, 518 size_t used_low); 519 520 static size_t max_capacity(); 521 static size_t used_at_mark_start(); 522 static size_t used_at_relocate_end(); 523 524 static void print(); 525 }; 526 527 #endif // SHARE_GC_Z_ZSTAT_HPP