123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- #ifndef MEMPROF_DATA_INC
- #define MEMPROF_DATA_INC
- /*===-- MemProfData.inc - MemProf profiling runtime structures -*- C++ -*-=== *\
- |*
- |* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- |* See https://llvm.org/LICENSE.txt for license information.
- |* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- |*
- \*===----------------------------------------------------------------------===*/
- /*
- * This is the main file that defines all the data structure, signature,
- * constant literals that are shared across profiling runtime library,
- * and host tools (reader/writer).
- *
- * This file has two identical copies. The primary copy lives in LLVM and
- * the other one sits in compiler-rt/include/profile directory. To make changes
- * in this file, first modify the primary copy and copy it over to compiler-rt.
- * Testing of any change in this file can start only after the two copies are
- * synced up.
- *
- \*===----------------------------------------------------------------------===*/
- #ifdef _MSC_VER
- #define PACKED(...) __pragma(pack(push,1)) __VA_ARGS__ __pragma(pack(pop))
- #else
- #define PACKED(...) __VA_ARGS__ __attribute__((__packed__))
- #endif
- // A 64-bit magic number to uniquely identify the raw binary memprof profile file.
- #define MEMPROF_RAW_MAGIC_64 \
- ((uint64_t)255 << 56 | (uint64_t)'m' << 48 | (uint64_t)'p' << 40 | (uint64_t)'r' << 32 | \
- (uint64_t)'o' << 24 | (uint64_t)'f' << 16 | (uint64_t)'r' << 8 | (uint64_t)129)
- // The version number of the raw binary format.
- #define MEMPROF_RAW_VERSION 2ULL
- namespace llvm {
- namespace memprof {
- // A struct describing the header used for the raw binary memprof profile format.
- PACKED(struct Header {
- uint64_t Magic;
- uint64_t Version;
- uint64_t TotalSize;
- uint64_t SegmentOffset;
- uint64_t MIBOffset;
- uint64_t StackOffset;
- });
- // A struct describing the information necessary to describe a /proc/maps
- // segment entry for a particular binary/library identified by its build id.
- PACKED(struct SegmentEntry {
- uint64_t Start;
- uint64_t End;
- uint64_t Offset;
- // This field is unused until sanitizer procmaps support for build ids for
- // Linux-Elf is implemented.
- uint8_t BuildId[32] = {0};
- SegmentEntry(uint64_t S, uint64_t E, uint64_t O) :
- Start(S), End(E), Offset(O) {}
- SegmentEntry(const SegmentEntry& S) {
- Start = S.Start;
- End = S.End;
- Offset = S.Offset;
- }
- SegmentEntry& operator=(const SegmentEntry& S) {
- Start = S.Start;
- End = S.End;
- Offset = S.Offset;
- return *this;
- }
- bool operator==(const SegmentEntry& S) const {
- return Start == S.Start &&
- End == S.End &&
- Offset == S.Offset;
- }
- });
- // Packed struct definition for MSVC. We can't use the PACKED macro defined in
- // MemProfData.inc since it would mean we are embedding a directive (the
- // #include for MIBEntryDef) into the macros which is undefined behaviour.
- #ifdef _MSC_VER
- __pragma(pack(push,1))
- #endif
- // A struct representing the heap allocation characteristics of a particular
- // runtime context. This struct is shared between the compiler-rt runtime and
- // the raw profile reader. The indexed format uses a separate, self-describing
- // backwards compatible format.
- struct MemInfoBlock{
- #define MIBEntryDef(NameTag, Name, Type) Type Name;
- #include "MIBEntryDef.inc"
- #undef MIBEntryDef
- bool operator==(const MemInfoBlock& Other) const {
- bool IsEqual = true;
- #define MIBEntryDef(NameTag, Name, Type) \
- IsEqual = (IsEqual && Name == Other.Name);
- #include "MIBEntryDef.inc"
- #undef MIBEntryDef
- return IsEqual;
- }
- MemInfoBlock() {
- #define MIBEntryDef(NameTag, Name, Type) Name = Type();
- #include "MIBEntryDef.inc"
- #undef MIBEntryDef
- }
- MemInfoBlock(uint32_t Size, uint64_t AccessCount, uint32_t AllocTs,
- uint32_t DeallocTs, uint32_t AllocCpu, uint32_t DeallocCpu)
- : MemInfoBlock() {
- AllocCount = 1U;
- TotalAccessCount = AccessCount;
- MinAccessCount = AccessCount;
- MaxAccessCount = AccessCount;
- TotalSize = Size;
- MinSize = Size;
- MaxSize = Size;
- AllocTimestamp = AllocTs;
- DeallocTimestamp = DeallocTs;
- TotalLifetime = DeallocTimestamp - AllocTimestamp;
- MinLifetime = TotalLifetime;
- MaxLifetime = TotalLifetime;
- // Access density is accesses per byte. Multiply by 100 to include the
- // fractional part.
- TotalAccessDensity = AccessCount * 100 / Size;
- MinAccessDensity = TotalAccessDensity;
- MaxAccessDensity = TotalAccessDensity;
- // Lifetime access density is the access density per second of lifetime.
- // Multiply by 1000 to convert denominator lifetime to seconds (using a
- // minimum lifetime of 1ms to avoid divide by 0. Do the multiplication first
- // to reduce truncations to 0.
- TotalLifetimeAccessDensity =
- TotalAccessDensity * 1000 / (TotalLifetime ? TotalLifetime : 1);
- MinLifetimeAccessDensity = TotalLifetimeAccessDensity;
- MaxLifetimeAccessDensity = TotalLifetimeAccessDensity;
- AllocCpuId = AllocCpu;
- DeallocCpuId = DeallocCpu;
- NumMigratedCpu = AllocCpuId != DeallocCpuId;
- }
- void Merge(const MemInfoBlock &newMIB) {
- AllocCount += newMIB.AllocCount;
- TotalAccessCount += newMIB.TotalAccessCount;
- MinAccessCount = newMIB.MinAccessCount < MinAccessCount ? newMIB.MinAccessCount : MinAccessCount;
- MaxAccessCount = newMIB.MaxAccessCount > MaxAccessCount ? newMIB.MaxAccessCount : MaxAccessCount;
- TotalSize += newMIB.TotalSize;
- MinSize = newMIB.MinSize < MinSize ? newMIB.MinSize : MinSize;
- MaxSize = newMIB.MaxSize > MaxSize ? newMIB.MaxSize : MaxSize;
- TotalLifetime += newMIB.TotalLifetime;
- MinLifetime = newMIB.MinLifetime < MinLifetime ? newMIB.MinLifetime : MinLifetime;
- MaxLifetime = newMIB.MaxLifetime > MaxLifetime ? newMIB.MaxLifetime : MaxLifetime;
- TotalAccessDensity += newMIB.TotalAccessDensity;
- MinAccessDensity = newMIB.MinAccessDensity < MinAccessDensity
- ? newMIB.MinAccessDensity
- : MinAccessDensity;
- MaxAccessDensity = newMIB.MaxAccessDensity > MaxAccessDensity
- ? newMIB.MaxAccessDensity
- : MaxAccessDensity;
- TotalLifetimeAccessDensity += newMIB.TotalLifetimeAccessDensity;
- MinLifetimeAccessDensity =
- newMIB.MinLifetimeAccessDensity < MinLifetimeAccessDensity
- ? newMIB.MinLifetimeAccessDensity
- : MinLifetimeAccessDensity;
- MaxLifetimeAccessDensity =
- newMIB.MaxLifetimeAccessDensity > MaxLifetimeAccessDensity
- ? newMIB.MaxLifetimeAccessDensity
- : MaxLifetimeAccessDensity;
- // We know newMIB was deallocated later, so just need to check if it was
- // allocated before last one deallocated.
- NumLifetimeOverlaps += newMIB.AllocTimestamp < DeallocTimestamp;
- AllocTimestamp = newMIB.AllocTimestamp;
- DeallocTimestamp = newMIB.DeallocTimestamp;
- NumSameAllocCpu += AllocCpuId == newMIB.AllocCpuId;
- NumSameDeallocCpu += DeallocCpuId == newMIB.DeallocCpuId;
- AllocCpuId = newMIB.AllocCpuId;
- DeallocCpuId = newMIB.DeallocCpuId;
- }
- #ifdef _MSC_VER
- } __pragma(pack(pop));
- #else
- } __attribute__((__packed__));
- #endif
- } // namespace memprof
- } // namespace llvm
- #endif
|