Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 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
 
23
#ifdef _MSC_VER
24
#define PACKED(...) __pragma(pack(push,1)) __VA_ARGS__ __pragma(pack(pop))
25
#else
26
#define PACKED(...) __VA_ARGS__ __attribute__((__packed__))
27
#endif
28
 
29
// A 64-bit magic number to uniquely identify the raw binary memprof profile file.
30
#define MEMPROF_RAW_MAGIC_64                                                                        \
31
  ((uint64_t)255 << 56 | (uint64_t)'m' << 48 | (uint64_t)'p' << 40 | (uint64_t)'r' << 32 |          \
32
   (uint64_t)'o' << 24 | (uint64_t)'f' << 16 | (uint64_t)'r' << 8 | (uint64_t)129)
33
 
34
// The version number of the raw binary format.
35
#define MEMPROF_RAW_VERSION 2ULL
36
 
37
namespace llvm {
38
namespace memprof {
39
// A struct describing the header used for the raw binary memprof profile format.
40
PACKED(struct Header {
41
  uint64_t Magic;
42
  uint64_t Version;
43
  uint64_t TotalSize;
44
  uint64_t SegmentOffset;
45
  uint64_t MIBOffset;
46
  uint64_t StackOffset;
47
});
48
 
49
 
50
// A struct describing the information necessary to describe a /proc/maps
51
// segment entry for a particular binary/library identified by its build id.
52
PACKED(struct SegmentEntry {
53
  uint64_t Start;
54
  uint64_t End;
55
  uint64_t Offset;
56
  // This field is unused until sanitizer procmaps support for build ids for
57
  // Linux-Elf is implemented.
58
  uint8_t BuildId[32] = {0};
59
 
60
  SegmentEntry(uint64_t S, uint64_t E, uint64_t O) :
61
    Start(S), End(E), Offset(O) {}
62
 
63
  SegmentEntry(const SegmentEntry& S) {
64
    Start = S.Start;
65
    End = S.End;
66
    Offset = S.Offset;
67
  }
68
 
69
  SegmentEntry& operator=(const SegmentEntry& S) {
70
    Start = S.Start;
71
    End = S.End;
72
    Offset = S.Offset;
73
    return *this;
74
  }
75
 
76
  bool operator==(const SegmentEntry& S) const {
77
    return Start == S.Start &&
78
           End == S.End &&
79
           Offset == S.Offset;
80
  }
81
});
82
 
83
// Packed struct definition for MSVC. We can't use the PACKED macro defined in
84
// MemProfData.inc since it would mean we are embedding a directive (the
85
// #include for MIBEntryDef) into the macros which is undefined behaviour.
86
#ifdef _MSC_VER
87
__pragma(pack(push,1))
88
#endif
89
 
90
// A struct representing the heap allocation characteristics of a particular
91
// runtime context. This struct is shared between the compiler-rt runtime and
92
// the raw profile reader. The indexed format uses a separate, self-describing
93
// backwards compatible format.
94
struct MemInfoBlock{
95
 
96
#define MIBEntryDef(NameTag, Name, Type) Type Name;
97
#include "MIBEntryDef.inc"
98
#undef MIBEntryDef
99
 
100
bool operator==(const MemInfoBlock& Other) const {
101
  bool IsEqual = true;
102
#define MIBEntryDef(NameTag, Name, Type) \
103
  IsEqual = (IsEqual && Name == Other.Name);
104
#include "MIBEntryDef.inc"
105
#undef MIBEntryDef
106
  return IsEqual;
107
}
108
 
109
MemInfoBlock() {
110
#define MIBEntryDef(NameTag, Name, Type) Name = Type();
111
#include "MIBEntryDef.inc"
112
#undef MIBEntryDef
113
}
114
 
115
MemInfoBlock(uint32_t Size, uint64_t AccessCount, uint32_t AllocTs,
116
             uint32_t DeallocTs, uint32_t AllocCpu, uint32_t DeallocCpu)
117
    : MemInfoBlock() {
118
  AllocCount = 1U;
119
  TotalAccessCount = AccessCount;
120
  MinAccessCount = AccessCount;
121
  MaxAccessCount = AccessCount;
122
  TotalSize = Size;
123
  MinSize = Size;
124
  MaxSize = Size;
125
  AllocTimestamp = AllocTs;
126
  DeallocTimestamp = DeallocTs;
127
  TotalLifetime = DeallocTimestamp - AllocTimestamp;
128
  MinLifetime = TotalLifetime;
129
  MaxLifetime = TotalLifetime;
130
  // Access density is accesses per byte. Multiply by 100 to include the
131
  // fractional part.
132
  TotalAccessDensity = AccessCount * 100 / Size;
133
  MinAccessDensity = TotalAccessDensity;
134
  MaxAccessDensity = TotalAccessDensity;
135
  // Lifetime access density is the access density per second of lifetime.
136
  // Multiply by 1000 to convert denominator lifetime to seconds (using a
137
  // minimum lifetime of 1ms to avoid divide by 0. Do the multiplication first
138
  // to reduce truncations to 0.
139
  TotalLifetimeAccessDensity =
140
      TotalAccessDensity * 1000 / (TotalLifetime ? TotalLifetime : 1);
141
  MinLifetimeAccessDensity = TotalLifetimeAccessDensity;
142
  MaxLifetimeAccessDensity = TotalLifetimeAccessDensity;
143
  AllocCpuId = AllocCpu;
144
  DeallocCpuId = DeallocCpu;
145
  NumMigratedCpu = AllocCpuId != DeallocCpuId;
146
}
147
 
148
void Merge(const MemInfoBlock &newMIB) {
149
  AllocCount += newMIB.AllocCount;
150
 
151
  TotalAccessCount += newMIB.TotalAccessCount;
152
  MinAccessCount = newMIB.MinAccessCount < MinAccessCount ? newMIB.MinAccessCount : MinAccessCount;
153
  MaxAccessCount = newMIB.MaxAccessCount > MaxAccessCount ? newMIB.MaxAccessCount : MaxAccessCount;
154
 
155
  TotalSize += newMIB.TotalSize;
156
  MinSize = newMIB.MinSize < MinSize ? newMIB.MinSize : MinSize;
157
  MaxSize = newMIB.MaxSize > MaxSize ? newMIB.MaxSize : MaxSize;
158
 
159
  TotalLifetime += newMIB.TotalLifetime;
160
  MinLifetime = newMIB.MinLifetime < MinLifetime ? newMIB.MinLifetime : MinLifetime;
161
  MaxLifetime = newMIB.MaxLifetime > MaxLifetime ? newMIB.MaxLifetime : MaxLifetime;
162
 
163
  TotalAccessDensity += newMIB.TotalAccessDensity;
164
  MinAccessDensity = newMIB.MinAccessDensity < MinAccessDensity
165
                         ? newMIB.MinAccessDensity
166
                         : MinAccessDensity;
167
  MaxAccessDensity = newMIB.MaxAccessDensity > MaxAccessDensity
168
                         ? newMIB.MaxAccessDensity
169
                         : MaxAccessDensity;
170
 
171
  TotalLifetimeAccessDensity += newMIB.TotalLifetimeAccessDensity;
172
  MinLifetimeAccessDensity =
173
      newMIB.MinLifetimeAccessDensity < MinLifetimeAccessDensity
174
          ? newMIB.MinLifetimeAccessDensity
175
          : MinLifetimeAccessDensity;
176
  MaxLifetimeAccessDensity =
177
      newMIB.MaxLifetimeAccessDensity > MaxLifetimeAccessDensity
178
          ? newMIB.MaxLifetimeAccessDensity
179
          : MaxLifetimeAccessDensity;
180
 
181
  // We know newMIB was deallocated later, so just need to check if it was
182
  // allocated before last one deallocated.
183
  NumLifetimeOverlaps += newMIB.AllocTimestamp < DeallocTimestamp;
184
  AllocTimestamp = newMIB.AllocTimestamp;
185
  DeallocTimestamp = newMIB.DeallocTimestamp;
186
 
187
  NumSameAllocCpu += AllocCpuId == newMIB.AllocCpuId;
188
  NumSameDeallocCpu += DeallocCpuId == newMIB.DeallocCpuId;
189
  AllocCpuId = newMIB.AllocCpuId;
190
  DeallocCpuId = newMIB.DeallocCpuId;
191
}
192
 
193
#ifdef _MSC_VER
194
} __pragma(pack(pop));
195
#else
196
} __attribute__((__packed__));
197
#endif
198
 
199
} // namespace memprof
200
} // namespace llvm
201
 
202
#endif