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