Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/llvm/ProfileData/MemProfData.inc is written in an unsupported language. File is not indexed.

0001 #ifndef MEMPROF_DATA_INC
0002 #define MEMPROF_DATA_INC
0003 /*===-- MemProfData.inc - MemProf profiling runtime structures -*- C++ -*-=== *\
0004 |*
0005 |* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0006 |* See https://llvm.org/LICENSE.txt for license information.
0007 |* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0008 |*
0009 \*===----------------------------------------------------------------------===*/
0010 /*
0011  * This is the main file that defines all the data structure, signature,
0012  * constant literals that are shared across profiling runtime library,
0013  * and host tools (reader/writer).
0014  *
0015  * This file has two identical copies. The primary copy lives in LLVM and
0016  * the other one sits in compiler-rt/include/profile directory. To make changes
0017  * in this file, first modify the primary copy and copy it over to compiler-rt.
0018  * Testing of any change in this file can start only after the two copies are
0019  * synced up.
0020  *
0021 \*===----------------------------------------------------------------------===*/
0022 #include <string.h>
0023 
0024 #ifdef _MSC_VER
0025 #define PACKED(...) __pragma(pack(push,1)) __VA_ARGS__ __pragma(pack(pop))
0026 #else
0027 #define PACKED(...) __VA_ARGS__ __attribute__((__packed__))
0028 #endif
0029 
0030 // A 64-bit magic number to uniquely identify the raw binary memprof profile file.
0031 #define MEMPROF_RAW_MAGIC_64                                                                        \
0032   ((uint64_t)255 << 56 | (uint64_t)'m' << 48 | (uint64_t)'p' << 40 | (uint64_t)'r' << 32 |          \
0033    (uint64_t)'o' << 24 | (uint64_t)'f' << 16 | (uint64_t)'r' << 8 | (uint64_t)129)
0034 
0035 // The version number of the raw binary format.
0036 #define MEMPROF_RAW_VERSION 4ULL
0037 
0038 // Currently supported versions.
0039 #define MEMPROF_RAW_SUPPORTED_VERSIONS                                         \
0040   { 3ULL, 4ULL }
0041 
0042 #define MEMPROF_V3_MIB_SIZE 132ULL;
0043 
0044 #define MEMPROF_BUILDID_MAX_SIZE 32ULL
0045 
0046 namespace llvm {
0047 namespace memprof {
0048 // A struct describing the header used for the raw binary memprof profile format.
0049 PACKED(struct Header {
0050   uint64_t Magic;
0051   uint64_t Version;
0052   uint64_t TotalSize;
0053   uint64_t SegmentOffset;
0054   uint64_t MIBOffset;
0055   uint64_t StackOffset;
0056 });
0057 
0058 // A struct describing the information necessary to describe a /proc/maps
0059 // segment entry for a particular binary/library identified by its build id.
0060 PACKED(struct SegmentEntry {
0061   uint64_t Start;
0062   uint64_t End;
0063   uint64_t Offset;
0064   uint64_t BuildIdSize;
0065   uint8_t BuildId[MEMPROF_BUILDID_MAX_SIZE] = {0};
0066 
0067   // This constructor is only used in tests so don't set the BuildId.
0068   SegmentEntry(uint64_t S, uint64_t E, uint64_t O)
0069       : Start(S), End(E), Offset(O), BuildIdSize(0) {}
0070 
0071   SegmentEntry(const SegmentEntry& S) {
0072     Start = S.Start;
0073     End = S.End;
0074     Offset = S.Offset;
0075     BuildIdSize = S.BuildIdSize;
0076     memcpy(BuildId, S.BuildId, S.BuildIdSize);
0077   }
0078 
0079   SegmentEntry& operator=(const SegmentEntry& S) {
0080     Start = S.Start;
0081     End = S.End;
0082     Offset = S.Offset;
0083     BuildIdSize = S.BuildIdSize;
0084     memcpy(BuildId, S.BuildId, S.BuildIdSize);
0085     return *this;
0086   }
0087 
0088   bool operator==(const SegmentEntry& S) const {
0089     return Start == S.Start && End == S.End && Offset == S.Offset &&
0090            BuildIdSize == S.BuildIdSize &&
0091            memcmp(BuildId, S.BuildId, S.BuildIdSize) == 0;
0092   }
0093 });
0094 
0095 // Packed struct definition for MSVC. We can't use the PACKED macro defined in
0096 // MemProfData.inc since it would mean we are embedding a directive (the
0097 // #include for MIBEntryDef) into the macros which is undefined behaviour.
0098 #ifdef _MSC_VER
0099 __pragma(pack(push,1))
0100 #endif
0101 
0102 // A struct representing the heap allocation characteristics of a particular
0103 // runtime context. This struct is shared between the compiler-rt runtime and
0104 // the raw profile reader. The indexed format uses a separate, self-describing
0105 // backwards compatible format.
0106 struct MemInfoBlock{
0107 
0108 #define MIBEntryDef(NameTag, Name, Type) Type Name;
0109 #include "MIBEntryDef.inc"
0110 #undef MIBEntryDef
0111 
0112 bool operator==(const MemInfoBlock& Other) const {
0113   bool IsEqual = true;
0114 #define MIBEntryDef(NameTag, Name, Type) \
0115   IsEqual = (IsEqual && Name == Other.Name);
0116 #include "MIBEntryDef.inc"
0117 #undef MIBEntryDef
0118   return IsEqual;
0119 }
0120 
0121 MemInfoBlock() {
0122 #define MIBEntryDef(NameTag, Name, Type) Name = Type();
0123 #include "MIBEntryDef.inc"
0124 #undef MIBEntryDef
0125 }
0126 
0127 MemInfoBlock(uint32_t Size, uint64_t AccessCount, uint32_t AllocTs,
0128              uint32_t DeallocTs, uint32_t AllocCpu, uint32_t DeallocCpu,
0129              uintptr_t Histogram, uint32_t HistogramSize)
0130     : MemInfoBlock() {
0131   AllocCount = 1U;
0132   TotalAccessCount = AccessCount;
0133   MinAccessCount = AccessCount;
0134   MaxAccessCount = AccessCount;
0135   TotalSize = Size;
0136   MinSize = Size;
0137   MaxSize = Size;
0138   AllocTimestamp = AllocTs;
0139   DeallocTimestamp = DeallocTs;
0140   TotalLifetime = DeallocTimestamp - AllocTimestamp;
0141   MinLifetime = TotalLifetime;
0142   MaxLifetime = TotalLifetime;
0143   // Access density is accesses per byte. Multiply by 100 to include the
0144   // fractional part.
0145   TotalAccessDensity = AccessCount * 100 / Size;
0146   MinAccessDensity = TotalAccessDensity;
0147   MaxAccessDensity = TotalAccessDensity;
0148   // Lifetime access density is the access density per second of lifetime.
0149   // Multiply by 1000 to convert denominator lifetime to seconds (using a
0150   // minimum lifetime of 1ms to avoid divide by 0. Do the multiplication first
0151   // to reduce truncations to 0.
0152   TotalLifetimeAccessDensity =
0153       TotalAccessDensity * 1000 / (TotalLifetime ? TotalLifetime : 1);
0154   MinLifetimeAccessDensity = TotalLifetimeAccessDensity;
0155   MaxLifetimeAccessDensity = TotalLifetimeAccessDensity;
0156   AllocCpuId = AllocCpu;
0157   DeallocCpuId = DeallocCpu;
0158   NumMigratedCpu = AllocCpuId != DeallocCpuId;
0159   AccessHistogramSize = HistogramSize;
0160   AccessHistogram = Histogram;
0161 }
0162 
0163 void Merge(const MemInfoBlock &newMIB) {
0164   AllocCount += newMIB.AllocCount;
0165 
0166   TotalAccessCount += newMIB.TotalAccessCount;
0167   MinAccessCount = newMIB.MinAccessCount < MinAccessCount ? newMIB.MinAccessCount : MinAccessCount;
0168   MaxAccessCount = newMIB.MaxAccessCount > MaxAccessCount ? newMIB.MaxAccessCount : MaxAccessCount;
0169 
0170   TotalSize += newMIB.TotalSize;
0171   MinSize = newMIB.MinSize < MinSize ? newMIB.MinSize : MinSize;
0172   MaxSize = newMIB.MaxSize > MaxSize ? newMIB.MaxSize : MaxSize;
0173 
0174   TotalLifetime += newMIB.TotalLifetime;
0175   MinLifetime = newMIB.MinLifetime < MinLifetime ? newMIB.MinLifetime : MinLifetime;
0176   MaxLifetime = newMIB.MaxLifetime > MaxLifetime ? newMIB.MaxLifetime : MaxLifetime;
0177 
0178   TotalAccessDensity += newMIB.TotalAccessDensity;
0179   MinAccessDensity = newMIB.MinAccessDensity < MinAccessDensity
0180                          ? newMIB.MinAccessDensity
0181                          : MinAccessDensity;
0182   MaxAccessDensity = newMIB.MaxAccessDensity > MaxAccessDensity
0183                          ? newMIB.MaxAccessDensity
0184                          : MaxAccessDensity;
0185 
0186   TotalLifetimeAccessDensity += newMIB.TotalLifetimeAccessDensity;
0187   MinLifetimeAccessDensity =
0188       newMIB.MinLifetimeAccessDensity < MinLifetimeAccessDensity
0189           ? newMIB.MinLifetimeAccessDensity
0190           : MinLifetimeAccessDensity;
0191   MaxLifetimeAccessDensity =
0192       newMIB.MaxLifetimeAccessDensity > MaxLifetimeAccessDensity
0193           ? newMIB.MaxLifetimeAccessDensity
0194           : MaxLifetimeAccessDensity;
0195 
0196   // We know newMIB was deallocated later, so just need to check if it was
0197   // allocated before last one deallocated.
0198   NumLifetimeOverlaps += newMIB.AllocTimestamp < DeallocTimestamp;
0199   AllocTimestamp = newMIB.AllocTimestamp;
0200   DeallocTimestamp = newMIB.DeallocTimestamp;
0201 
0202   NumSameAllocCpu += AllocCpuId == newMIB.AllocCpuId;
0203   NumSameDeallocCpu += DeallocCpuId == newMIB.DeallocCpuId;
0204   AllocCpuId = newMIB.AllocCpuId;
0205   DeallocCpuId = newMIB.DeallocCpuId;
0206 
0207   // For merging histograms, we always keep the longer histogram, and add
0208   // values of shorter histogram to larger one.
0209   uintptr_t ShorterHistogram;
0210   uint32_t ShorterHistogramSize;
0211   if (newMIB.AccessHistogramSize > AccessHistogramSize) {
0212     ShorterHistogram = AccessHistogram;
0213     ShorterHistogramSize = AccessHistogramSize;
0214     // Swap histogram of current to larger histogram
0215     AccessHistogram = newMIB.AccessHistogram;
0216     AccessHistogramSize = newMIB.AccessHistogramSize;
0217   } else {
0218     ShorterHistogram = newMIB.AccessHistogram;
0219     ShorterHistogramSize = newMIB.AccessHistogramSize;
0220   }
0221   for (size_t i = 0; i < ShorterHistogramSize; ++i) {
0222     ((uint64_t *)AccessHistogram)[i] += ((uint64_t *)ShorterHistogram)[i];
0223   }
0224 }
0225 
0226 #ifdef _MSC_VER
0227 } __pragma(pack(pop));
0228 #else
0229 } __attribute__((__packed__));
0230 #endif
0231 
0232 } // namespace memprof
0233 } // namespace llvm
0234 
0235 #endif