MemProfData.inc 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. #ifndef MEMPROF_DATA_INC
  2. #define MEMPROF_DATA_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 2ULL
  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. // Packed struct definition for MSVC. We can't use the PACKED macro defined in
  73. // MemProfData.inc since it would mean we are embedding a directive (the
  74. // #include for MIBEntryDef) into the macros which is undefined behaviour.
  75. #ifdef _MSC_VER
  76. __pragma(pack(push,1))
  77. #endif
  78. // A struct representing the heap allocation characteristics of a particular
  79. // runtime context. This struct is shared between the compiler-rt runtime and
  80. // the raw profile reader. The indexed format uses a separate, self-describing
  81. // backwards compatible format.
  82. struct MemInfoBlock{
  83. #define MIBEntryDef(NameTag, Name, Type) Type Name;
  84. #include "MIBEntryDef.inc"
  85. #undef MIBEntryDef
  86. bool operator==(const MemInfoBlock& Other) const {
  87. bool IsEqual = true;
  88. #define MIBEntryDef(NameTag, Name, Type) \
  89. IsEqual = (IsEqual && Name == Other.Name);
  90. #include "MIBEntryDef.inc"
  91. #undef MIBEntryDef
  92. return IsEqual;
  93. }
  94. MemInfoBlock() {
  95. #define MIBEntryDef(NameTag, Name, Type) Name = Type();
  96. #include "MIBEntryDef.inc"
  97. #undef MIBEntryDef
  98. }
  99. MemInfoBlock(uint32_t Size, uint64_t AccessCount, uint32_t AllocTs,
  100. uint32_t DeallocTs, uint32_t AllocCpu, uint32_t DeallocCpu)
  101. : MemInfoBlock() {
  102. AllocCount = 1U;
  103. TotalAccessCount = AccessCount;
  104. MinAccessCount = AccessCount;
  105. MaxAccessCount = AccessCount;
  106. TotalSize = Size;
  107. MinSize = Size;
  108. MaxSize = Size;
  109. AllocTimestamp = AllocTs;
  110. DeallocTimestamp = DeallocTs;
  111. TotalLifetime = DeallocTimestamp - AllocTimestamp;
  112. MinLifetime = TotalLifetime;
  113. MaxLifetime = TotalLifetime;
  114. // Access density is accesses per byte. Multiply by 100 to include the
  115. // fractional part.
  116. TotalAccessDensity = AccessCount * 100 / Size;
  117. MinAccessDensity = TotalAccessDensity;
  118. MaxAccessDensity = TotalAccessDensity;
  119. // Lifetime access density is the access density per second of lifetime.
  120. // Multiply by 1000 to convert denominator lifetime to seconds (using a
  121. // minimum lifetime of 1ms to avoid divide by 0. Do the multiplication first
  122. // to reduce truncations to 0.
  123. TotalLifetimeAccessDensity =
  124. TotalAccessDensity * 1000 / (TotalLifetime ? TotalLifetime : 1);
  125. MinLifetimeAccessDensity = TotalLifetimeAccessDensity;
  126. MaxLifetimeAccessDensity = TotalLifetimeAccessDensity;
  127. AllocCpuId = AllocCpu;
  128. DeallocCpuId = DeallocCpu;
  129. NumMigratedCpu = AllocCpuId != DeallocCpuId;
  130. }
  131. void Merge(const MemInfoBlock &newMIB) {
  132. AllocCount += newMIB.AllocCount;
  133. TotalAccessCount += newMIB.TotalAccessCount;
  134. MinAccessCount = newMIB.MinAccessCount < MinAccessCount ? newMIB.MinAccessCount : MinAccessCount;
  135. MaxAccessCount = newMIB.MaxAccessCount > MaxAccessCount ? newMIB.MaxAccessCount : MaxAccessCount;
  136. TotalSize += newMIB.TotalSize;
  137. MinSize = newMIB.MinSize < MinSize ? newMIB.MinSize : MinSize;
  138. MaxSize = newMIB.MaxSize > MaxSize ? newMIB.MaxSize : MaxSize;
  139. TotalLifetime += newMIB.TotalLifetime;
  140. MinLifetime = newMIB.MinLifetime < MinLifetime ? newMIB.MinLifetime : MinLifetime;
  141. MaxLifetime = newMIB.MaxLifetime > MaxLifetime ? newMIB.MaxLifetime : MaxLifetime;
  142. TotalAccessDensity += newMIB.TotalAccessDensity;
  143. MinAccessDensity = newMIB.MinAccessDensity < MinAccessDensity
  144. ? newMIB.MinAccessDensity
  145. : MinAccessDensity;
  146. MaxAccessDensity = newMIB.MaxAccessDensity > MaxAccessDensity
  147. ? newMIB.MaxAccessDensity
  148. : MaxAccessDensity;
  149. TotalLifetimeAccessDensity += newMIB.TotalLifetimeAccessDensity;
  150. MinLifetimeAccessDensity =
  151. newMIB.MinLifetimeAccessDensity < MinLifetimeAccessDensity
  152. ? newMIB.MinLifetimeAccessDensity
  153. : MinLifetimeAccessDensity;
  154. MaxLifetimeAccessDensity =
  155. newMIB.MaxLifetimeAccessDensity > MaxLifetimeAccessDensity
  156. ? newMIB.MaxLifetimeAccessDensity
  157. : MaxLifetimeAccessDensity;
  158. // We know newMIB was deallocated later, so just need to check if it was
  159. // allocated before last one deallocated.
  160. NumLifetimeOverlaps += newMIB.AllocTimestamp < DeallocTimestamp;
  161. AllocTimestamp = newMIB.AllocTimestamp;
  162. DeallocTimestamp = newMIB.DeallocTimestamp;
  163. NumSameAllocCpu += AllocCpuId == newMIB.AllocCpuId;
  164. NumSameDeallocCpu += DeallocCpuId == newMIB.DeallocCpuId;
  165. AllocCpuId = newMIB.AllocCpuId;
  166. DeallocCpuId = newMIB.DeallocCpuId;
  167. }
  168. #ifdef _MSC_VER
  169. } __pragma(pack(pop));
  170. #else
  171. } __attribute__((__packed__));
  172. #endif
  173. } // namespace memprof
  174. } // namespace llvm
  175. #endif