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
//===- FDRRecords.h - XRay Flight Data Recorder Mode Records --------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// Define types and operations on these types that represent the different kinds
10
// of records we encounter in XRay flight data recorder mode traces.
11
//
12
//===----------------------------------------------------------------------===//
13
#ifndef LLVM_XRAY_FDRRECORDS_H
14
#define LLVM_XRAY_FDRRECORDS_H
15
 
16
#include <cstdint>
17
#include <string>
18
 
19
#include "llvm/ADT/StringRef.h"
20
#include "llvm/Support/Casting.h"
21
#include "llvm/Support/DataExtractor.h"
22
#include "llvm/Support/Error.h"
23
#include "llvm/XRay/XRayRecord.h"
24
 
25
namespace llvm {
26
namespace xray {
27
 
28
class RecordVisitor;
29
class RecordInitializer;
30
 
31
class Record {
32
public:
33
  enum class RecordKind {
34
    RK_Metadata,
35
    RK_Metadata_BufferExtents,
36
    RK_Metadata_WallClockTime,
37
    RK_Metadata_NewCPUId,
38
    RK_Metadata_TSCWrap,
39
    RK_Metadata_CustomEvent,
40
    RK_Metadata_CustomEventV5,
41
    RK_Metadata_CallArg,
42
    RK_Metadata_PIDEntry,
43
    RK_Metadata_NewBuffer,
44
    RK_Metadata_EndOfBuffer,
45
    RK_Metadata_TypedEvent,
46
    RK_Metadata_LastMetadata,
47
    RK_Function,
48
  };
49
 
50
  static StringRef kindToString(RecordKind K);
51
 
52
private:
53
  const RecordKind T;
54
 
55
public:
56
  Record(const Record &) = delete;
57
  Record(Record &&) = delete;
58
  Record &operator=(const Record &) = delete;
59
  Record &operator=(Record &&) = delete;
60
  explicit Record(RecordKind T) : T(T) {}
61
 
62
  RecordKind getRecordType() const { return T; }
63
 
64
  // Each Record should be able to apply an abstract visitor, and choose the
65
  // appropriate function in the visitor to invoke, given its own type.
66
  virtual Error apply(RecordVisitor &V) = 0;
67
 
68
  virtual ~Record() = default;
69
};
70
 
71
class MetadataRecord : public Record {
72
public:
73
  enum class MetadataType : unsigned {
74
    Unknown,
75
    BufferExtents,
76
    WallClockTime,
77
    NewCPUId,
78
    TSCWrap,
79
    CustomEvent,
80
    CallArg,
81
    PIDEntry,
82
    NewBuffer,
83
    EndOfBuffer,
84
    TypedEvent,
85
  };
86
 
87
protected:
88
  static constexpr int kMetadataBodySize = 15;
89
  friend class RecordInitializer;
90
 
91
private:
92
  const MetadataType MT;
93
 
94
public:
95
  explicit MetadataRecord(RecordKind T, MetadataType M) : Record(T), MT(M) {}
96
 
97
  static bool classof(const Record *R) {
98
    return R->getRecordType() >= RecordKind::RK_Metadata &&
99
           R->getRecordType() <= RecordKind::RK_Metadata_LastMetadata;
100
  }
101
 
102
  MetadataType metadataType() const { return MT; }
103
 
104
  virtual ~MetadataRecord() = default;
105
};
106
 
107
// What follows are specific Metadata record types which encapsulate the
108
// information associated with specific metadata record types in an FDR mode
109
// log.
110
class BufferExtents : public MetadataRecord {
111
  uint64_t Size = 0;
112
  friend class RecordInitializer;
113
 
114
public:
115
  BufferExtents()
116
      : MetadataRecord(RecordKind::RK_Metadata_BufferExtents,
117
                       MetadataType::BufferExtents) {}
118
 
119
  explicit BufferExtents(uint64_t S)
120
      : MetadataRecord(RecordKind::RK_Metadata_BufferExtents,
121
                       MetadataType::BufferExtents),
122
        Size(S) {}
123
 
124
  uint64_t size() const { return Size; }
125
 
126
  Error apply(RecordVisitor &V) override;
127
 
128
  static bool classof(const Record *R) {
129
    return R->getRecordType() == RecordKind::RK_Metadata_BufferExtents;
130
  }
131
};
132
 
133
class WallclockRecord : public MetadataRecord {
134
  uint64_t Seconds = 0;
135
  uint32_t Nanos = 0;
136
  friend class RecordInitializer;
137
 
138
public:
139
  WallclockRecord()
140
      : MetadataRecord(RecordKind::RK_Metadata_WallClockTime,
141
                       MetadataType::WallClockTime) {}
142
 
143
  explicit WallclockRecord(uint64_t S, uint32_t N)
144
      : MetadataRecord(RecordKind::RK_Metadata_WallClockTime,
145
                       MetadataType::WallClockTime),
146
        Seconds(S), Nanos(N) {}
147
 
148
  uint64_t seconds() const { return Seconds; }
149
  uint32_t nanos() const { return Nanos; }
150
 
151
  Error apply(RecordVisitor &V) override;
152
 
153
  static bool classof(const Record *R) {
154
    return R->getRecordType() == RecordKind::RK_Metadata_WallClockTime;
155
  }
156
};
157
 
158
class NewCPUIDRecord : public MetadataRecord {
159
  uint16_t CPUId = 0;
160
  uint64_t TSC = 0;
161
  friend class RecordInitializer;
162
 
163
public:
164
  NewCPUIDRecord()
165
      : MetadataRecord(RecordKind::RK_Metadata_NewCPUId,
166
                       MetadataType::NewCPUId) {}
167
 
168
  NewCPUIDRecord(uint16_t C, uint64_t T)
169
      : MetadataRecord(RecordKind::RK_Metadata_NewCPUId,
170
                       MetadataType::NewCPUId),
171
        CPUId(C), TSC(T) {}
172
 
173
  uint16_t cpuid() const { return CPUId; }
174
 
175
  uint64_t tsc() const { return TSC; }
176
 
177
  Error apply(RecordVisitor &V) override;
178
 
179
  static bool classof(const Record *R) {
180
    return R->getRecordType() == RecordKind::RK_Metadata_NewCPUId;
181
  }
182
};
183
 
184
class TSCWrapRecord : public MetadataRecord {
185
  uint64_t BaseTSC = 0;
186
  friend class RecordInitializer;
187
 
188
public:
189
  TSCWrapRecord()
190
      : MetadataRecord(RecordKind::RK_Metadata_TSCWrap, MetadataType::TSCWrap) {
191
  }
192
 
193
  explicit TSCWrapRecord(uint64_t B)
194
      : MetadataRecord(RecordKind::RK_Metadata_TSCWrap, MetadataType::TSCWrap),
195
        BaseTSC(B) {}
196
 
197
  uint64_t tsc() const { return BaseTSC; }
198
 
199
  Error apply(RecordVisitor &V) override;
200
 
201
  static bool classof(const Record *R) {
202
    return R->getRecordType() == RecordKind::RK_Metadata_TSCWrap;
203
  }
204
};
205
 
206
class CustomEventRecord : public MetadataRecord {
207
  int32_t Size = 0;
208
  uint64_t TSC = 0;
209
  uint16_t CPU = 0;
210
  std::string Data{};
211
  friend class RecordInitializer;
212
 
213
public:
214
  CustomEventRecord()
215
      : MetadataRecord(RecordKind::RK_Metadata_CustomEvent,
216
                       MetadataType::CustomEvent) {}
217
 
218
  explicit CustomEventRecord(uint64_t S, uint64_t T, uint16_t C, std::string D)
219
      : MetadataRecord(RecordKind::RK_Metadata_CustomEvent,
220
                       MetadataType::CustomEvent),
221
        Size(S), TSC(T), CPU(C), Data(std::move(D)) {}
222
 
223
  int32_t size() const { return Size; }
224
  uint64_t tsc() const { return TSC; }
225
  uint16_t cpu() const { return CPU; }
226
  StringRef data() const { return Data; }
227
 
228
  Error apply(RecordVisitor &V) override;
229
 
230
  static bool classof(const Record *R) {
231
    return R->getRecordType() == RecordKind::RK_Metadata_CustomEvent;
232
  }
233
};
234
 
235
class CustomEventRecordV5 : public MetadataRecord {
236
  int32_t Size = 0;
237
  int32_t Delta = 0;
238
  std::string Data{};
239
  friend class RecordInitializer;
240
 
241
public:
242
  CustomEventRecordV5()
243
      : MetadataRecord(RecordKind::RK_Metadata_CustomEventV5,
244
                       MetadataType::CustomEvent) {}
245
 
246
  explicit CustomEventRecordV5(int32_t S, int32_t D, std::string P)
247
      : MetadataRecord(RecordKind::RK_Metadata_CustomEventV5,
248
                       MetadataType::CustomEvent),
249
        Size(S), Delta(D), Data(std::move(P)) {}
250
 
251
  int32_t size() const { return Size; }
252
  int32_t delta() const { return Delta; }
253
  StringRef data() const { return Data; }
254
 
255
  Error apply(RecordVisitor &V) override;
256
 
257
  static bool classof(const Record *R) {
258
    return R->getRecordType() == RecordKind::RK_Metadata_CustomEventV5;
259
  }
260
};
261
 
262
class TypedEventRecord : public MetadataRecord {
263
  int32_t Size = 0;
264
  int32_t Delta = 0;
265
  uint16_t EventType = 0;
266
  std::string Data{};
267
  friend class RecordInitializer;
268
 
269
public:
270
  TypedEventRecord()
271
      : MetadataRecord(RecordKind::RK_Metadata_TypedEvent,
272
                       MetadataType::TypedEvent) {}
273
 
274
  explicit TypedEventRecord(int32_t S, int32_t D, uint16_t E, std::string P)
275
      : MetadataRecord(RecordKind::RK_Metadata_TypedEvent,
276
                       MetadataType::TypedEvent),
277
        Size(S), Delta(D), Data(std::move(P)) {}
278
 
279
  int32_t size() const { return Size; }
280
  int32_t delta() const { return Delta; }
281
  uint16_t eventType() const { return EventType; }
282
  StringRef data() const { return Data; }
283
 
284
  Error apply(RecordVisitor &V) override;
285
 
286
  static bool classof(const Record *R) {
287
    return R->getRecordType() == RecordKind::RK_Metadata_TypedEvent;
288
  }
289
};
290
 
291
class CallArgRecord : public MetadataRecord {
292
  uint64_t Arg = 0;
293
  friend class RecordInitializer;
294
 
295
public:
296
  CallArgRecord()
297
      : MetadataRecord(RecordKind::RK_Metadata_CallArg, MetadataType::CallArg) {
298
  }
299
 
300
  explicit CallArgRecord(uint64_t A)
301
      : MetadataRecord(RecordKind::RK_Metadata_CallArg, MetadataType::CallArg),
302
        Arg(A) {}
303
 
304
  uint64_t arg() const { return Arg; }
305
 
306
  Error apply(RecordVisitor &V) override;
307
 
308
  static bool classof(const Record *R) {
309
    return R->getRecordType() == RecordKind::RK_Metadata_CallArg;
310
  }
311
};
312
 
313
class PIDRecord : public MetadataRecord {
314
  int32_t PID = 0;
315
  friend class RecordInitializer;
316
 
317
public:
318
  PIDRecord()
319
      : MetadataRecord(RecordKind::RK_Metadata_PIDEntry,
320
                       MetadataType::PIDEntry) {}
321
 
322
  explicit PIDRecord(int32_t P)
323
      : MetadataRecord(RecordKind::RK_Metadata_PIDEntry,
324
                       MetadataType::PIDEntry),
325
        PID(P) {}
326
 
327
  int32_t pid() const { return PID; }
328
 
329
  Error apply(RecordVisitor &V) override;
330
 
331
  static bool classof(const Record *R) {
332
    return R->getRecordType() == RecordKind::RK_Metadata_PIDEntry;
333
  }
334
};
335
 
336
class NewBufferRecord : public MetadataRecord {
337
  int32_t TID = 0;
338
  friend class RecordInitializer;
339
 
340
public:
341
  NewBufferRecord()
342
      : MetadataRecord(RecordKind::RK_Metadata_NewBuffer,
343
                       MetadataType::NewBuffer) {}
344
 
345
  explicit NewBufferRecord(int32_t T)
346
      : MetadataRecord(RecordKind::RK_Metadata_NewBuffer,
347
                       MetadataType::NewBuffer),
348
        TID(T) {}
349
 
350
  int32_t tid() const { return TID; }
351
 
352
  Error apply(RecordVisitor &V) override;
353
 
354
  static bool classof(const Record *R) {
355
    return R->getRecordType() == RecordKind::RK_Metadata_NewBuffer;
356
  }
357
};
358
 
359
class EndBufferRecord : public MetadataRecord {
360
public:
361
  EndBufferRecord()
362
      : MetadataRecord(RecordKind::RK_Metadata_EndOfBuffer,
363
                       MetadataType::EndOfBuffer) {}
364
 
365
  Error apply(RecordVisitor &V) override;
366
 
367
  static bool classof(const Record *R) {
368
    return R->getRecordType() == RecordKind::RK_Metadata_EndOfBuffer;
369
  }
370
};
371
 
372
class FunctionRecord : public Record {
373
  RecordTypes Kind;
374
  int32_t FuncId = 0;
375
  uint32_t Delta = 0;
376
  friend class RecordInitializer;
377
 
378
  static constexpr unsigned kFunctionRecordSize = 8;
379
 
380
public:
381
  FunctionRecord() : Record(RecordKind::RK_Function) {}
382
 
383
  explicit FunctionRecord(RecordTypes K, int32_t F, uint32_t D)
384
      : Record(RecordKind::RK_Function), Kind(K), FuncId(F), Delta(D) {}
385
 
386
  // A function record is a concrete record type which has a number of common
387
  // properties.
388
  RecordTypes recordType() const { return Kind; }
389
  int32_t functionId() const { return FuncId; }
390
  uint32_t delta() const { return Delta; }
391
 
392
  Error apply(RecordVisitor &V) override;
393
 
394
  static bool classof(const Record *R) {
395
    return R->getRecordType() == RecordKind::RK_Function;
396
  }
397
};
398
 
399
class RecordVisitor {
400
public:
401
  virtual ~RecordVisitor() = default;
402
 
403
  // Support all specific kinds of records:
404
  virtual Error visit(BufferExtents &) = 0;
405
  virtual Error visit(WallclockRecord &) = 0;
406
  virtual Error visit(NewCPUIDRecord &) = 0;
407
  virtual Error visit(TSCWrapRecord &) = 0;
408
  virtual Error visit(CustomEventRecord &) = 0;
409
  virtual Error visit(CallArgRecord &) = 0;
410
  virtual Error visit(PIDRecord &) = 0;
411
  virtual Error visit(NewBufferRecord &) = 0;
412
  virtual Error visit(EndBufferRecord &) = 0;
413
  virtual Error visit(FunctionRecord &) = 0;
414
  virtual Error visit(CustomEventRecordV5 &) = 0;
415
  virtual Error visit(TypedEventRecord &) = 0;
416
};
417
 
418
class RecordInitializer : public RecordVisitor {
419
  DataExtractor &E;
420
  uint64_t &OffsetPtr;
421
  uint16_t Version;
422
 
423
public:
424
  static constexpr uint16_t DefaultVersion = 5u;
425
 
426
  explicit RecordInitializer(DataExtractor &DE, uint64_t &OP, uint16_t V)
427
      : E(DE), OffsetPtr(OP), Version(V) {}
428
 
429
  explicit RecordInitializer(DataExtractor &DE, uint64_t &OP)
430
      : RecordInitializer(DE, OP, DefaultVersion) {}
431
 
432
  Error visit(BufferExtents &) override;
433
  Error visit(WallclockRecord &) override;
434
  Error visit(NewCPUIDRecord &) override;
435
  Error visit(TSCWrapRecord &) override;
436
  Error visit(CustomEventRecord &) override;
437
  Error visit(CallArgRecord &) override;
438
  Error visit(PIDRecord &) override;
439
  Error visit(NewBufferRecord &) override;
440
  Error visit(EndBufferRecord &) override;
441
  Error visit(FunctionRecord &) override;
442
  Error visit(CustomEventRecordV5 &) override;
443
  Error visit(TypedEventRecord &) override;
444
};
445
 
446
} // namespace xray
447
} // namespace llvm
448
 
449
#endif // LLVM_XRAY_FDRRECORDS_H