34 #include "third_party/jsoncpp/include/json/json.h"
46 static const uint32 kEmptyScopeMarker = 0xfeeb1e57;
52 size_t TraceRecorder::s_default_buffer_size_ =
59 bool TraceRecorder::s_reserve_buffer_ =
false;
63 trace_buffer_(s_default_buffer_size_ / sizeof(uint32),
68 thread_name_(
"UnnamedThread"),
70 current_frame_number_(0) {
71 trace_buffer_.
AddItem(kEmptyScopeMarker);
77 buffer_size / sizeof(uint32), GetAllocator(), s_reserve_buffer_),
80 thread_name_(
"UnnamedThread"),
82 current_frame_number_(0) {
83 trace_buffer_.
AddItem(kEmptyScopeMarker);
91 const std::string&
value) {
100 trace_buffer_.
AddItem(event_id);
101 trace_buffer_.
AddItem(timestamp);
106 const std::string&
name,
107 const std::string&
value) {
119 trace_buffer_.
AddItem(timestamp);
120 trace_buffer_.
AddItem(name_index);
121 trace_buffer_.
AddItem(value_index);
126 trace_buffer_.
AddItem(timestamp);
129 if (scope_level_ == 0) {
130 trace_buffer_.
AddItem(kEmptyScopeMarker);
135 if (frame_level_ == 0) {
137 current_frame_number_ = frame_number;
140 trace_buffer_.
AddItem(frame_number);
148 <<
"LeaveFrame() should not be called outside of a frame.";
153 if (frame_level_ == 0) {
156 trace_buffer_.
AddItem(current_frame_number_);
161 uint32 unique_id,
const char*
name,
const char*
value) {
165 uint32 value_index = -1;
172 trace_buffer_.
AddItem(unique_id);
173 trace_buffer_.
AddItem(name_index);
174 trace_buffer_.
AddItem(value_index);
181 uint32 value_index = -1;
191 trace_buffer_.
AddItem(name_index);
192 trace_buffer_.
AddItem(name_index);
193 trace_buffer_.
AddItem(value_index);
209 uint32 timestamp,
const char*
name,
const char*
value) {
213 uint32 value_index = -1;
219 trace_buffer_.
AddItem(timestamp);
220 trace_buffer_.
AddItem(name_index);
221 trace_buffer_.
AddItem(value_index);
227 while (index < trace_buffer_.
GetSize() &&
228 trace_buffer_.
GetItem(index) != kEmptyScopeMarker) {
233 while (index < trace_buffer_.
GetSize()) {
235 uint32 wire_id = trace_buffer_.
GetItem(index);
236 if (wire_id == kEmptyScopeMarker) {
246 uint32 TraceRecorder::GetStringIndex(
const std::string&
str) {
249 uint32 index =
static_cast<uint32
>(string_buffer_.size());
250 return string_buffer_.insert(
251 std::make_pair(str, index)).first->second;
255 size_t base = table->size();
256 table->resize(base + string_buffer_.size());
257 for (
auto it = string_buffer_.begin(); it != string_buffer_.end(); ++it) {
258 DCHECK_LT(base + it->second, table->size());
259 (*table)[base + it->second] = it->first;
264 std::string* output, uint32 string_index_offset)
const {
268 while (index < trace_buffer_.
GetSize() &&
269 trace_buffer_.
GetItem(index) != kEmptyScopeMarker) {
274 while (index < trace_buffer_.
GetSize()) {
275 uint32 wire_id = trace_buffer_.
GetItem(index);
276 if (wire_id == kEmptyScopeMarker) {
285 for (
int i = 0; i < num_args; ++i) {
289 uint32 item = trace_buffer_.
GetItem(index + 2 + i);
291 item != 0xffffffff) {
297 index += num_args + 2;
302 std::string TraceRecorder::GetStringArg(
303 size_t index,
int arg_index,
304 const IndexToStringMap& inverse_string_buffer)
const {
305 const uint32 wire_id = trace_buffer_.
GetItem(index);
309 const uint32 string_index = trace_buffer_.
GetItem(index + 2 + arg_index);
312 if (string_index == 0xffffffff)
return std::string();
313 return inverse_string_buffer.at(string_index);
316 std::unique_ptr<TimelineEvent> TraceRecorder::GetTimelineEvent(
317 size_t index,
const IndexToStringMap& inverse_string_buffer)
const {
318 const uint32 wire_id = trace_buffer_.
GetItem(index);
319 const uint32 timestamp = trace_buffer_.
GetItem(index + 1);
320 Json::Reader json_reader;
322 std::string event_name;
323 Json::Value args(Json::objectValue);
326 event_name = GetStringArg(index, 1, inverse_string_buffer);
327 json_reader.parse(GetStringArg(index, 2, inverse_string_buffer), args);
328 return std::unique_ptr<TimelineEvent>(
331 const uint32 frame_number = trace_buffer_.
GetItem(index + 2);
333 return std::unique_ptr<TimelineEvent>(
334 new TimelineFrame(event_name, timestamp, 0, args, frame_number));
337 return std::unique_ptr<TimelineEvent>(
340 CHECK(
false) <<
"Event type not supported by timeline exporter!";
341 return std::unique_ptr<TimelineEvent>(
349 std::stack<TimelineEvent*> open_events;
350 uint32 previous_begin = 0;
351 bool first_event =
true;
353 Json::Reader json_reader;
356 for (
auto it = string_buffer_.begin(); it != string_buffer_.end(); ++it) {
357 inverse_string_buffer[it->second] = it->first;
361 while (index < trace_buffer_.
GetSize() &&
362 trace_buffer_.
GetItem(index) != kEmptyScopeMarker) {
367 while (index < trace_buffer_.
GetSize()) {
368 const uint32 wire_id = trace_buffer_.
GetItem(index);
369 if (wire_id == kEmptyScopeMarker) {
374 const uint32 timestamp = trace_buffer_.
GetItem(index + 1);
375 CHECK(first_event || timestamp >= previous_begin)
376 <<
"Timestamps not monotonically increasing!\n";
378 previous_begin = timestamp;
386 (open_events.empty() || parent != open_events.top()) &&
387 parent->
GetEnd() < timestamp) {
396 std::unique_ptr<TimelineEvent> timeline_event =
397 GetTimelineEvent(index, inverse_string_buffer);
398 open_events.push(timeline_event.get());
402 parent_candidate = timeline_event.get();
403 parent->
AddChild(std::move(timeline_event));
408 open_events.top()->UpdateDuration(timestamp);
414 const std::string arg_name =
415 GetStringArg(index, 0, inverse_string_buffer);
416 const std::string arg_value =
417 GetStringArg(index, 1, inverse_string_buffer);
418 open_events.top()->GetArgs()[arg_name] = Json::objectValue;
419 json_reader.parse(arg_value, open_events.top()->GetArgs()[arg_name]);
423 index += num_args + 2;
429 LOG_ONCE(
WARNING) <<
"GetCurrentFrameNumber() should not be called outside "
433 return current_frame_number_;
uint32 GetCurrentFrameNumber() const
Returns the frame number of the current frame scope, or 0 (and a warning message) if TraceRecorder is...
void AnnotateCurrentScopeAtTime(uint32 timestamp, const std::string &name, const std::string &value)
Same as AnnotateCurrentScope, but with specified timestamp.
size_t GetSize() const
Get the current number of items in the buffer.
Copyright 2016 Google Inc.
Leaving the current scope.
void EnterTimeRange(uint32 unique_id, const char *name, const char *value)
Records the start of a time range event.
void AnnotateCurrentScope(const std::string &name, const std::string &value)
Attaches data to the current scope, which will be visible on mouse-over.
static int GetNumArgsForEvent(uint32 event_id)
Gets the number of arguments for a particular event.
Copyright 2016 Google Inc.
void AddChild(std::unique_ptr< TimelineNode > child)
Add a node to the children. It becomes the last child.
Attaching data to the current scope.
#define DCHECK_GT(val1, val2)
size_t GetNumTraces() const
Returns the total number of recorded trace events.
static EventArgType GetArgType(uint32 event_id, int arg_index)
Gets the argument types for a particular event.
void EnterScopeAtTime(uint32 timestamp, int event_id)
Same as EnterScope, but with specified timestamp.
TraceRecorder(CallTraceManager *manager)
#define CHECK_LT(val1, val2)
void AddTraceToTimelineNode(TimelineNode *root) const
Adds all events in the trace as a sub-tree under the passed in root node.
void LeaveScope()
Leaves the current (most recent) scope.
void CreateTimeStampAtTime(uint32 timestamp, const char *name, const char *value)
Same as CreateTimeStamp, but with specified timestamp.
virtual uint32 GetTimeInUs() const
Returns the time in microseconds, relative to the timebase.
std::string ValueToString(const T &val)
ValueToString.
#define DCHECK_NE(val1, val2)
void CreateTimeStamp(const char *name, const char *value)
Records a timeStamp event.
Copyright 2016 Google Inc.
Time range start and end events.
void AppendBytes(std::string *s, const T &value)
Convenience method to append bytes to string.
void DumpStrings(std::vector< std::string > *table) const
Dumps the strings one by one to a string table.
const TimelineNode * GetParent() const
EventArgType
Defines argument types for WTF events.
void LeaveFrame()
Records a frame exit event for the current frame index.
void AddItem(const T &item)
Add an item to the buffer.
#define LOG_ONCE(severity)
Logs the streamed message once per process run with a severity of severity.
#define CHECK_EQ(val1, val2)
Copyright 2016 Google Inc.
const T & GetItem(size_t i) const
Return the item at position i.
void LeaveTimeRange(uint32 id)
Records the end of a time range event for the specified unique id.
std::unordered_map< uint32, std::string > IndexToStringMap
The frame start and end events.
void EnterScope(int event_id)
Queries and records the event corresponding to the provided event_id.
void DumpTrace(std::string *output, uint32 string_index_offset) const
Appends a binary dump of the trace to the output string.
void EnterFrame(uint32 frame_number)
Records a frame enter event with a specified frame index.
bool IsInFrameScope() const
Returns if the TraceRecorder is currently in a frame scope.
Manages call trace recording for visualization in Web Tracing Framework (WTF) format.
Copyright 2016 Google Inc.
std::string TrimEndWhitespace(const std::string &target)
Removes any whitespace characters at the end of the string.
The starting offset for scope event ids, purposefully set high to make room for built-in WTF events...
void LeaveScopeAtTime(uint32 timestamp)
Same as LeaveScope, but with specified timestamp.
#define DCHECK_LT(val1, val2)
ThreadId GetCurrentThreadId()
Thread ID functions.
const char * GetScopeEnterEventName(uint32 event_id) const
Returns the name of the scope enter event with the given id.