1 //===- FDRTraceExpander.cpp -----------------------------------------------===//
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 #include "llvm/XRay/FDRTraceExpander.h"
9 
10 namespace llvm {
11 namespace xray {
12 
13 void TraceExpander::resetCurrentRecord() {
14   if (BuildingRecord)
15     C(CurrentRecord);
16   BuildingRecord = false;
17   CurrentRecord.CallArgs.clear();
18   CurrentRecord.Data.clear();
19 }
20 
21 Error TraceExpander::visit(BufferExtents &) {
22   resetCurrentRecord();
23   return Error::success();
24 }
25 
26 Error TraceExpander::visit(WallclockRecord &) { return Error::success(); }
27 
28 Error TraceExpander::visit(NewCPUIDRecord &R) {
29   CPUId = R.cpuid();
30   BaseTSC = R.tsc();
31   return Error::success();
32 }
33 
34 Error TraceExpander::visit(TSCWrapRecord &R) {
35   BaseTSC = R.tsc();
36   return Error::success();
37 }
38 
39 Error TraceExpander::visit(CustomEventRecord &R) {
40   resetCurrentRecord();
41   if (!IgnoringRecords) {
42     CurrentRecord.TSC = R.tsc();
43     CurrentRecord.CPU = R.cpu();
44     CurrentRecord.PId = PID;
45     CurrentRecord.TId = TID;
46     CurrentRecord.Type = RecordTypes::CUSTOM_EVENT;
47     CurrentRecord.Data = std::string(R.data());
48     BuildingRecord = true;
49   }
50   return Error::success();
51 }
52 
53 Error TraceExpander::visit(CustomEventRecordV5 &R) {
54   resetCurrentRecord();
55   if (!IgnoringRecords) {
56     BaseTSC += R.delta();
57     CurrentRecord.TSC = BaseTSC;
58     CurrentRecord.CPU = CPUId;
59     CurrentRecord.PId = PID;
60     CurrentRecord.TId = TID;
61     CurrentRecord.Type = RecordTypes::CUSTOM_EVENT;
62     CurrentRecord.Data = std::string(R.data());
63     BuildingRecord = true;
64   }
65   return Error::success();
66 }
67 
68 Error TraceExpander::visit(TypedEventRecord &R) {
69   resetCurrentRecord();
70   if (!IgnoringRecords) {
71     BaseTSC += R.delta();
72     CurrentRecord.TSC = BaseTSC;
73     CurrentRecord.CPU = CPUId;
74     CurrentRecord.PId = PID;
75     CurrentRecord.TId = TID;
76     CurrentRecord.RecordType = R.eventType();
77     CurrentRecord.Type = RecordTypes::TYPED_EVENT;
78     CurrentRecord.Data = std::string(R.data());
79     BuildingRecord = true;
80   }
81   return Error::success();
82 }
83 
84 Error TraceExpander::visit(CallArgRecord &R) {
85   CurrentRecord.CallArgs.push_back(R.arg());
86   CurrentRecord.Type = RecordTypes::ENTER_ARG;
87   return Error::success();
88 }
89 
90 Error TraceExpander::visit(PIDRecord &R) {
91   PID = R.pid();
92   return Error::success();
93 }
94 
95 Error TraceExpander::visit(NewBufferRecord &R) {
96   if (IgnoringRecords)
97     IgnoringRecords = false;
98   TID = R.tid();
99   if (LogVersion == 2)
100     PID = R.tid();
101   return Error::success();
102 }
103 
104 Error TraceExpander::visit(EndBufferRecord &) {
105   IgnoringRecords = true;
106   resetCurrentRecord();
107   return Error::success();
108 }
109 
110 Error TraceExpander::visit(FunctionRecord &R) {
111   resetCurrentRecord();
112   if (!IgnoringRecords) {
113     BaseTSC += R.delta();
114     CurrentRecord.Type = R.recordType();
115     CurrentRecord.FuncId = R.functionId();
116     CurrentRecord.TSC = BaseTSC;
117     CurrentRecord.PId = PID;
118     CurrentRecord.TId = TID;
119     CurrentRecord.CPU = CPUId;
120     BuildingRecord = true;
121   }
122   return Error::success();
123 }
124 
125 Error TraceExpander::flush() {
126   resetCurrentRecord();
127   return Error::success();
128 }
129 
130 } // namespace xray
131 } // namespace llvm
132