[llvm] r338834 - [XRay][tools] Use Support/JSON.h in llvm-xray convert
Dean Michael Berris via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 3 02:21:31 PDT 2018
Author: dberris
Date: Fri Aug 3 02:21:31 2018
New Revision: 338834
URL: http://llvm.org/viewvc/llvm-project?rev=338834&view=rev
Log:
[XRay][tools] Use Support/JSON.h in llvm-xray convert
Summary:
This change removes the ad-hoc implementation used by llvm-xray's
`convert` subcommand to generate JSON encoded catapult (AKA Chrome
Trace Viewer) trace output, to instead use the JSON encoder now in the
Support library.
Reviewers: kpw, zturner, eizan
Reviewed By: kpw
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D50129
Modified:
llvm/trunk/tools/llvm-xray/xray-converter.cpp
Modified: llvm/trunk/tools/llvm-xray/xray-converter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-xray/xray-converter.cpp?rev=338834&r1=338833&r2=338834&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-xray/xray-converter.cpp (original)
+++ llvm/trunk/tools/llvm-xray/xray-converter.cpp Fri Aug 3 02:21:31 2018
@@ -18,6 +18,7 @@
#include "llvm/Support/EndianStream.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/JSON.h"
#include "llvm/Support/ScopedPrinter.h"
#include "llvm/Support/YAMLTraits.h"
#include "llvm/Support/raw_ostream.h"
@@ -234,31 +235,6 @@ StackTrieNode *findOrCreateStackNode(
return CurrentStack;
}
-void writeTraceViewerRecord(uint16_t Version, raw_ostream &OS, int32_t FuncId,
- uint32_t TId, uint32_t PId, bool Symbolize,
- const FuncIdConversionHelper &FuncIdHelper,
- double EventTimestampUs,
- const StackTrieNode &StackCursor,
- StringRef FunctionPhenotype) {
- OS << " ";
- if (Version >= 3) {
- OS << llvm::formatv(
- R"({ "name" : "{0}", "ph" : "{1}", "tid" : "{2}", "pid" : "{3}", )"
- R"("ts" : "{4:f4}", "sf" : "{5}" })",
- (Symbolize ? FuncIdHelper.SymbolOrNumber(FuncId)
- : llvm::to_string(FuncId)),
- FunctionPhenotype, TId, PId, EventTimestampUs,
- StackCursor.ExtraData.id);
- } else {
- OS << llvm::formatv(
- R"({ "name" : "{0}", "ph" : "{1}", "tid" : "{2}", "pid" : "1", )"
- R"("ts" : "{3:f3}", "sf" : "{4}" })",
- (Symbolize ? FuncIdHelper.SymbolOrNumber(FuncId)
- : llvm::to_string(FuncId)),
- FunctionPhenotype, TId, EventTimestampUs, StackCursor.ExtraData.id);
- }
-}
-
} // namespace
void TraceConverter::exportAsChromeTraceEventFormat(const Trace &Records,
@@ -269,18 +245,14 @@ void TraceConverter::exportAsChromeTrace
unsigned id_counter = 0;
- OS << "{\n \"traceEvents\": [";
DenseMap<uint32_t, StackTrieNode *> StackCursorByThreadId{};
DenseMap<uint32_t, SmallVector<StackTrieNode *, 4>> StackRootsByThreadId{};
DenseMap<unsigned, StackTrieNode *> StacksByStackId{};
std::forward_list<StackTrieNode> NodeStore{};
- int loop_count = 0;
- for (const auto &R : Records) {
- if (loop_count++ == 0)
- OS << "\n";
- else
- OS << ",\n";
+ // Create a JSON Array which will hold all trace events.
+ json::Array TraceEvents;
+ for (const auto &R : Records) {
// Chrome trace event format always wants data in micros.
// CyclesPerMicro = CycleHertz / 10^6
// TSC / CyclesPerMicro == TSC * 10^6 / CycleHertz == MicroTimestamp
@@ -301,8 +273,15 @@ void TraceConverter::exportAsChromeTrace
// type of B for begin or E for end, thread id, process id,
// timestamp in microseconds, and a stack frame id. The ids are logged
// in an id dictionary after the events.
- writeTraceViewerRecord(Version, OS, R.FuncId, R.TId, R.PId, Symbolize,
- FuncIdHelper, EventTimestampUs, *StackCursor, "B");
+ TraceEvents.push_back(json::Object({
+ {"name", Symbolize ? FuncIdHelper.SymbolOrNumber(R.FuncId)
+ : llvm::to_string(R.FuncId)},
+ {"ph", "B"},
+ {"tid", llvm::to_string(R.TId)},
+ {"pid", llvm::to_string(Version >= 3 ? R.PId : 1)},
+ {"ts", llvm::formatv("{0:f4}", EventTimestampUs)},
+ {"sf", llvm::to_string(StackCursor->ExtraData.id)},
+ }));
break;
case RecordTypes::EXIT:
case RecordTypes::TAIL_EXIT:
@@ -313,43 +292,51 @@ void TraceConverter::exportAsChromeTrace
// (And/Or in loop termination below)
StackTrieNode *PreviousCursor = nullptr;
do {
- if (PreviousCursor != nullptr) {
- OS << ",\n";
- }
- writeTraceViewerRecord(Version, OS, StackCursor->FuncId, R.TId, R.PId,
- Symbolize, FuncIdHelper, EventTimestampUs,
- *StackCursor, "E");
+ TraceEvents.push_back(json::Object({
+ {"name", Symbolize
+ ? FuncIdHelper.SymbolOrNumber(StackCursor->FuncId)
+ : llvm::to_string(StackCursor->FuncId)},
+ {"ph", "E"},
+ {"tid", llvm::to_string(R.TId)},
+ {"pid", llvm::to_string(Version >= 3 ? R.PId : 1)},
+ {"ts", llvm::formatv("{0:f4}", EventTimestampUs)},
+ {"sf", llvm::to_string(StackCursor->ExtraData.id)},
+ }));
PreviousCursor = StackCursor;
StackCursor = StackCursor->Parent;
} while (PreviousCursor->FuncId != R.FuncId && StackCursor != nullptr);
break;
}
}
- OS << "\n ],\n"; // Close the Trace Events array.
- OS << " "
- << "\"displayTimeUnit\": \"ns\",\n";
// The stackFrames dictionary substantially reduces size of the output file by
// avoiding repeating the entire call stack of function names for each entry.
- OS << R"( "stackFrames": {)";
- int stack_frame_count = 0;
- for (auto map_iter : StacksByStackId) {
- if (stack_frame_count++ == 0)
- OS << "\n";
- else
- OS << ",\n";
- OS << " ";
- OS << llvm::formatv(
- R"("{0}" : { "name" : "{1}")", map_iter.first,
- (Symbolize ? FuncIdHelper.SymbolOrNumber(map_iter.second->FuncId)
- : llvm::to_string(map_iter.second->FuncId)));
- if (map_iter.second->Parent != nullptr)
- OS << llvm::formatv(R"(, "parent": "{0}")",
- map_iter.second->Parent->ExtraData.id);
- OS << " }";
+ json::Object StackFrames;
+ for (const auto &Stack : StacksByStackId) {
+ const auto &StackId = Stack.first;
+ const auto &StackFunctionNode = Stack.second;
+ json::Object::iterator It;
+ std::tie(It, std::ignore) = StackFrames.insert({
+ llvm::to_string(StackId),
+ json::Object{
+ {"name",
+ Symbolize ? FuncIdHelper.SymbolOrNumber(StackFunctionNode->FuncId)
+ : llvm::to_string(StackFunctionNode->FuncId)}},
+ });
+
+ if (StackFunctionNode->Parent != nullptr)
+ It->second.getAsObject()->insert(
+ {"parent", llvm::to_string(StackFunctionNode->Parent->ExtraData.id)});
}
- OS << "\n }\n"; // Close the stack frames map.
- OS << "}\n"; // Close the JSON entry.
+
+ json::Object TraceJSON{
+ {"displayTimeUnit", "ns"},
+ {"traceEvents", std::move(TraceEvents)},
+ {"stackFrames", std::move(StackFrames)},
+ };
+
+ // Pretty-print the JSON using two spaces for indentations.
+ OS << formatv("{0:2}", json::Value(std::move(TraceJSON)));
}
namespace llvm {
More information about the llvm-commits
mailing list