| //===-- test_helpers.cpp --------------------------------------------------===// | |
| // | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| // See https://llvm.org/LICENSE.txt for license information. | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| // | |
| //===----------------------------------------------------------------------===// | |
| // | |
| // This file is a part of XRay, a function call tracing system. | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #include "test_helpers.h" | |
| #include "xray/xray_records.h" | |
| #include "xray_buffer_queue.h" | |
| #include "xray_fdr_log_writer.h" | |
| #include <type_traits> | |
| // TODO: Move these to llvm/include/Testing/XRay/... | |
| namespace llvm { | |
| namespace xray { | |
| std::string RecordTypeAsString(RecordTypes T) { | |
| switch (T) { | |
| case RecordTypes::ENTER: | |
| return "llvm::xray::RecordTypes::ENTER"; | |
| case RecordTypes::EXIT: | |
| return "llvm::xray::RecordTypes::EXIT"; | |
| case RecordTypes::TAIL_EXIT: | |
| return "llvm::xray::RecordTypes::TAIL_EXIT"; | |
| case RecordTypes::ENTER_ARG: | |
| return "llvm::xray::RecordTypes::ENTER_ARG"; | |
| case RecordTypes::CUSTOM_EVENT: | |
| return "llvm::xray::RecordTypes::CUSTOM_EVENT"; | |
| case RecordTypes::TYPED_EVENT: | |
| return "llvm::xray::RecordTypes::TYPED_EVENT"; | |
| } | |
| return "<UNKNOWN>"; | |
| } | |
| void PrintTo(RecordTypes T, std::ostream *OS) { | |
| *OS << RecordTypeAsString(T); | |
| } | |
| void PrintTo(const XRayRecord &R, std::ostream *OS) { | |
| *OS << "XRayRecord { CPU = " << R.CPU | |
| << "; Type = " << RecordTypeAsString(R.Type) << "; FuncId = " << R.FuncId | |
| << "; TSC = " << R.TSC << "; TId = " << R.TId << "; PId = " << R.PId | |
| << " Args = " << ::testing::PrintToString(R.CallArgs) << " }"; | |
| } | |
| void PrintTo(const Trace &T, std::ostream *OS) { | |
| const auto &H = T.getFileHeader(); | |
| *OS << "XRay Trace:\nHeader: { Version = " << H.Version | |
| << "; Type = " << H.Type | |
| << "; ConstantTSC = " << ::testing::PrintToString(H.ConstantTSC) | |
| << "; NonstopTSC = " << ::testing::PrintToString(H.NonstopTSC) | |
| << "; CycleFrequency = " << H.CycleFrequency << "; FreeFormData = '" | |
| << ::testing::PrintToString(H.FreeFormData) << "' }\n"; | |
| for (const auto &R : T) { | |
| PrintTo(R, OS); | |
| *OS << "\n"; | |
| } | |
| } | |
| } // namespace xray | |
| } // namespace llvm | |
| namespace __xray { | |
| std::string serialize(BufferQueue &Buffers, int32_t Version) { | |
| std::string Serialized; | |
| std::aligned_storage<sizeof(XRayFileHeader), alignof(XRayFileHeader)>::type | |
| HeaderStorage; | |
| auto *Header = reinterpret_cast<XRayFileHeader *>(&HeaderStorage); | |
| new (Header) XRayFileHeader(); | |
| Header->Version = Version; | |
| Header->Type = FileTypes::FDR_LOG; | |
| Header->CycleFrequency = 3e9; | |
| Header->ConstantTSC = 1; | |
| Header->NonstopTSC = 1; | |
| Serialized.append(reinterpret_cast<const char *>(&HeaderStorage), | |
| sizeof(XRayFileHeader)); | |
| Buffers.apply([&](const BufferQueue::Buffer &B) { | |
| auto Size = atomic_load_relaxed(B.Extents); | |
| auto Extents = | |
| createMetadataRecord<MetadataRecord::RecordKinds::BufferExtents>(Size); | |
| Serialized.append(reinterpret_cast<const char *>(&Extents), | |
| sizeof(Extents)); | |
| Serialized.append(reinterpret_cast<const char *>(B.Data), Size); | |
| }); | |
| return Serialized; | |
| } | |
| } // namespace __xray |