1bc0d697dSNico Weber //===-- test_helpers.cpp --------------------------------------------------===//
2bc0d697dSNico Weber //
3bc0d697dSNico Weber // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4bc0d697dSNico Weber // See https://llvm.org/LICENSE.txt for license information.
5bc0d697dSNico Weber // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6bc0d697dSNico Weber //
7bc0d697dSNico Weber //===----------------------------------------------------------------------===//
8bc0d697dSNico Weber //
9bc0d697dSNico Weber // This file is a part of XRay, a function call tracing system.
10bc0d697dSNico Weber //
11bc0d697dSNico Weber //===----------------------------------------------------------------------===//
12bc0d697dSNico Weber #include "test_helpers.h"
13bc0d697dSNico Weber #include "xray/xray_records.h"
14bc0d697dSNico Weber #include "xray_buffer_queue.h"
15bc0d697dSNico Weber #include "xray_fdr_log_writer.h"
16bc0d697dSNico Weber #include <type_traits>
17bc0d697dSNico Weber
18bc0d697dSNico Weber // TODO: Move these to llvm/include/Testing/XRay/...
19bc0d697dSNico Weber namespace llvm {
20bc0d697dSNico Weber namespace xray {
21bc0d697dSNico Weber
RecordTypeAsString(RecordTypes T)22bc0d697dSNico Weber std::string RecordTypeAsString(RecordTypes T) {
23bc0d697dSNico Weber switch (T) {
24bc0d697dSNico Weber case RecordTypes::ENTER:
25bc0d697dSNico Weber return "llvm::xray::RecordTypes::ENTER";
26bc0d697dSNico Weber case RecordTypes::EXIT:
27bc0d697dSNico Weber return "llvm::xray::RecordTypes::EXIT";
28bc0d697dSNico Weber case RecordTypes::TAIL_EXIT:
29bc0d697dSNico Weber return "llvm::xray::RecordTypes::TAIL_EXIT";
30bc0d697dSNico Weber case RecordTypes::ENTER_ARG:
31bc0d697dSNico Weber return "llvm::xray::RecordTypes::ENTER_ARG";
32bc0d697dSNico Weber case RecordTypes::CUSTOM_EVENT:
33bc0d697dSNico Weber return "llvm::xray::RecordTypes::CUSTOM_EVENT";
34bc0d697dSNico Weber case RecordTypes::TYPED_EVENT:
35bc0d697dSNico Weber return "llvm::xray::RecordTypes::TYPED_EVENT";
36bc0d697dSNico Weber }
37bc0d697dSNico Weber return "<UNKNOWN>";
38bc0d697dSNico Weber }
39bc0d697dSNico Weber
PrintTo(RecordTypes T,std::ostream * OS)40bc0d697dSNico Weber void PrintTo(RecordTypes T, std::ostream *OS) {
41bc0d697dSNico Weber *OS << RecordTypeAsString(T);
42bc0d697dSNico Weber }
43bc0d697dSNico Weber
PrintTo(const XRayRecord & R,std::ostream * OS)44bc0d697dSNico Weber void PrintTo(const XRayRecord &R, std::ostream *OS) {
45bc0d697dSNico Weber *OS << "XRayRecord { CPU = " << R.CPU
46bc0d697dSNico Weber << "; Type = " << RecordTypeAsString(R.Type) << "; FuncId = " << R.FuncId
47bc0d697dSNico Weber << "; TSC = " << R.TSC << "; TId = " << R.TId << "; PId = " << R.PId
48bc0d697dSNico Weber << " Args = " << ::testing::PrintToString(R.CallArgs) << " }";
49bc0d697dSNico Weber }
50bc0d697dSNico Weber
PrintTo(const Trace & T,std::ostream * OS)51bc0d697dSNico Weber void PrintTo(const Trace &T, std::ostream *OS) {
52bc0d697dSNico Weber const auto &H = T.getFileHeader();
53bc0d697dSNico Weber *OS << "XRay Trace:\nHeader: { Version = " << H.Version
54bc0d697dSNico Weber << "; Type = " << H.Type
55bc0d697dSNico Weber << "; ConstantTSC = " << ::testing::PrintToString(H.ConstantTSC)
56bc0d697dSNico Weber << "; NonstopTSC = " << ::testing::PrintToString(H.NonstopTSC)
57bc0d697dSNico Weber << "; CycleFrequency = " << H.CycleFrequency << "; FreeFormData = '"
58bc0d697dSNico Weber << ::testing::PrintToString(H.FreeFormData) << "' }\n";
59bc0d697dSNico Weber for (const auto &R : T) {
60bc0d697dSNico Weber PrintTo(R, OS);
61bc0d697dSNico Weber *OS << "\n";
62bc0d697dSNico Weber }
63bc0d697dSNico Weber }
64bc0d697dSNico Weber
65bc0d697dSNico Weber } // namespace xray
66bc0d697dSNico Weber } // namespace llvm
67bc0d697dSNico Weber
68bc0d697dSNico Weber namespace __xray {
69bc0d697dSNico Weber
serialize(BufferQueue & Buffers,int32_t Version)70bc0d697dSNico Weber std::string serialize(BufferQueue &Buffers, int32_t Version) {
71bc0d697dSNico Weber std::string Serialized;
72*cac78214SMarc Auberer alignas(XRayFileHeader) std::byte HeaderStorage[sizeof(XRayFileHeader)];
73bc0d697dSNico Weber auto *Header = reinterpret_cast<XRayFileHeader *>(&HeaderStorage);
74bc0d697dSNico Weber new (Header) XRayFileHeader();
75bc0d697dSNico Weber Header->Version = Version;
76bc0d697dSNico Weber Header->Type = FileTypes::FDR_LOG;
77bc0d697dSNico Weber Header->CycleFrequency = 3e9;
78bc0d697dSNico Weber Header->ConstantTSC = 1;
79bc0d697dSNico Weber Header->NonstopTSC = 1;
80bc0d697dSNico Weber Serialized.append(reinterpret_cast<const char *>(&HeaderStorage),
81bc0d697dSNico Weber sizeof(XRayFileHeader));
82bc0d697dSNico Weber Buffers.apply([&](const BufferQueue::Buffer &B) {
83bc0d697dSNico Weber auto Size = atomic_load_relaxed(B.Extents);
84bc0d697dSNico Weber auto Extents =
85bc0d697dSNico Weber createMetadataRecord<MetadataRecord::RecordKinds::BufferExtents>(Size);
86bc0d697dSNico Weber Serialized.append(reinterpret_cast<const char *>(&Extents),
87bc0d697dSNico Weber sizeof(Extents));
88bc0d697dSNico Weber Serialized.append(reinterpret_cast<const char *>(B.Data), Size);
89bc0d697dSNico Weber });
90bc0d697dSNico Weber return Serialized;
91bc0d697dSNico Weber }
92bc0d697dSNico Weber
93bc0d697dSNico Weber } // namespace __xray
94