MemProfData.inc 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. #ifndef LLVM_PROFILEDATA_MEMPROFDATA_INC
  2. #define LLVM_PROFILEDATA_MEMPROFDATA_INC
  3. /*===-- MemProfData.inc - MemProf profiling runtime structures -*- C++ -*-=== *\
  4. |*
  5. |* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  6. |* See https://llvm.org/LICENSE.txt for license information.
  7. |* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  8. |*
  9. \*===----------------------------------------------------------------------===*/
  10. /*
  11. * This is the main file that defines all the data structure, signature,
  12. * constant literals that are shared across profiling runtime library,
  13. * and host tools (reader/writer).
  14. *
  15. * This file has two identical copies. The primary copy lives in LLVM and
  16. * the other one sits in compiler-rt/include/profile directory. To make changes
  17. * in this file, first modify the primary copy and copy it over to compiler-rt.
  18. * Testing of any change in this file can start only after the two copies are
  19. * synced up.
  20. *
  21. \*===----------------------------------------------------------------------===*/
  22. #ifdef _MSC_VER
  23. #define PACKED(...) __pragma(pack(push,1)) __VA_ARGS__ __pragma(pack(pop))
  24. #else
  25. #define PACKED(...) __VA_ARGS__ __attribute__((__packed__))
  26. #endif
  27. // A 64-bit magic number to uniquely identify the raw binary memprof profile file.
  28. #define MEMPROF_RAW_MAGIC_64 \
  29. ((uint64_t)255 << 56 | (uint64_t)'m' << 48 | (uint64_t)'p' << 40 | (uint64_t)'r' << 32 | \
  30. (uint64_t)'o' << 24 | (uint64_t)'f' << 16 | (uint64_t)'r' << 8 | (uint64_t)129)
  31. // The version number of the raw binary format.
  32. #define MEMPROF_RAW_VERSION 1ULL
  33. namespace llvm {
  34. namespace memprof {
  35. // A struct describing the header used for the raw binary memprof profile format.
  36. PACKED(struct Header {
  37. uint64_t Magic;
  38. uint64_t Version;
  39. uint64_t TotalSize;
  40. uint64_t SegmentOffset;
  41. uint64_t MIBOffset;
  42. uint64_t StackOffset;
  43. });
  44. // A struct describing the information necessary to describe a /proc/maps
  45. // segment entry for a particular binary/library identified by its build id.
  46. PACKED(struct SegmentEntry {
  47. uint64_t Start;
  48. uint64_t End;
  49. uint64_t Offset;
  50. // This field is unused until sanitizer procmaps support for build ids for
  51. // Linux-Elf is implemented.
  52. uint8_t BuildId[32] = {0};
  53. SegmentEntry(uint64_t S, uint64_t E, uint64_t O) :
  54. Start(S), End(E), Offset(O) {}
  55. SegmentEntry(const SegmentEntry& S) {
  56. Start = S.Start;
  57. End = S.End;
  58. Offset = S.Offset;
  59. }
  60. SegmentEntry& operator=(const SegmentEntry& S) {
  61. Start = S.Start;
  62. End = S.End;
  63. Offset = S.Offset;
  64. return *this;
  65. }
  66. bool operator==(const SegmentEntry& S) const {
  67. return Start == S.Start &&
  68. End == S.End &&
  69. Offset == S.Offset;
  70. }
  71. });
  72. // A struct representing the heap allocation characteristics of a particular
  73. // runtime context. This struct is shared between the compiler-rt runtime and
  74. // the raw profile reader. The indexed format uses a separate, self-describing
  75. // backwards compatible format.
  76. PACKED(struct MemInfoBlock {
  77. uint32_t alloc_count;
  78. uint64_t total_access_count, min_access_count, max_access_count;
  79. uint64_t total_size;
  80. uint32_t min_size, max_size;
  81. uint32_t alloc_timestamp, dealloc_timestamp;
  82. uint64_t total_lifetime;
  83. uint32_t min_lifetime, max_lifetime;
  84. uint32_t alloc_cpu_id, dealloc_cpu_id;
  85. uint32_t num_migrated_cpu;
  86. // Only compared to prior deallocated object currently.
  87. uint32_t num_lifetime_overlaps;
  88. uint32_t num_same_alloc_cpu;
  89. uint32_t num_same_dealloc_cpu;
  90. uint64_t data_type_id; // TODO: hash of type name
  91. MemInfoBlock() : alloc_count(0) {}
  92. MemInfoBlock(uint32_t size, uint64_t access_count, uint32_t alloc_timestamp,
  93. uint32_t dealloc_timestamp, uint32_t alloc_cpu, uint32_t dealloc_cpu)
  94. : alloc_count(1), total_access_count(access_count),
  95. min_access_count(access_count), max_access_count(access_count),
  96. total_size(size), min_size(size), max_size(size),
  97. alloc_timestamp(alloc_timestamp), dealloc_timestamp(dealloc_timestamp),
  98. total_lifetime(dealloc_timestamp - alloc_timestamp),
  99. min_lifetime(total_lifetime), max_lifetime(total_lifetime),
  100. alloc_cpu_id(alloc_cpu), dealloc_cpu_id(dealloc_cpu),
  101. num_lifetime_overlaps(0), num_same_alloc_cpu(0),
  102. num_same_dealloc_cpu(0) {
  103. num_migrated_cpu = alloc_cpu_id != dealloc_cpu_id;
  104. }
  105. void Merge(const MemInfoBlock &newMIB) {
  106. alloc_count += newMIB.alloc_count;
  107. total_access_count += newMIB.total_access_count;
  108. min_access_count = newMIB.min_access_count < min_access_count ? newMIB.min_access_count : min_access_count;
  109. max_access_count = newMIB.max_access_count < max_access_count ? newMIB.max_access_count : max_access_count;
  110. total_size += newMIB.total_size;
  111. min_size = newMIB.min_size < min_size ? newMIB.min_size : min_size;
  112. max_size = newMIB.max_size < max_size ? newMIB.max_size : max_size;
  113. total_lifetime += newMIB.total_lifetime;
  114. min_lifetime = newMIB.min_lifetime < min_lifetime ? newMIB.min_lifetime : min_lifetime;
  115. max_lifetime = newMIB.max_lifetime > max_lifetime ? newMIB.max_lifetime : max_lifetime;
  116. // We know newMIB was deallocated later, so just need to check if it was
  117. // allocated before last one deallocated.
  118. num_lifetime_overlaps += newMIB.alloc_timestamp < dealloc_timestamp;
  119. alloc_timestamp = newMIB.alloc_timestamp;
  120. dealloc_timestamp = newMIB.dealloc_timestamp;
  121. num_same_alloc_cpu += alloc_cpu_id == newMIB.alloc_cpu_id;
  122. num_same_dealloc_cpu += dealloc_cpu_id == newMIB.dealloc_cpu_id;
  123. alloc_cpu_id = newMIB.alloc_cpu_id;
  124. dealloc_cpu_id = newMIB.dealloc_cpu_id;
  125. }
  126. });
  127. } // namespace memprof
  128. } // namespace llvm
  129. #endif