trace.cc revision 68043e1e95eeb07d5cae7aca370b26518b0867d6
168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// found in the LICENSE file. 468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "tools/gn/trace.h" 668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include <algorithm> 868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include <map> 968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include <sstream> 1068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include <vector> 1168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 1268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "base/file_util.h" 1368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "base/json/string_escape.h" 1468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "base/logging.h" 1568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "base/strings/stringprintf.h" 1668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "base/synchronization/lock.h" 1768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "tools/gn/filesystem_utils.h" 1868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "tools/gn/label.h" 1968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 2068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)namespace { 2168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 2268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)class TraceLog { 2368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) public: 2468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) TraceLog() { 2568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) events_.reserve(16384); 2668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 2768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ~TraceLog() { 2868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Trace items leanked intentionally. 2968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 3068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 3168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) void Add(TraceItem* item) { 3268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) base::AutoLock lock(lock_); 3368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) events_.push_back(item); 3468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 3568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 3668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Returns a copy for threadsafety. 3768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::vector<TraceItem*> events() const { return events_; } 3868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 3968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) private: 4068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) base::Lock lock_; 4168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 4268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::vector<TraceItem*> events_; 4368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 4468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(TraceLog); 4568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}; 4668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 4768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)TraceLog* trace_log = NULL; 4868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 4968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)struct Coalesced { 5068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Coalesced() : name_ptr(NULL), total_duration(0.0), count(0) {} 5168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 5268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string* name_ptr; // Pointer to a string with the name in it. 5368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) double total_duration; 5468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int count; 5568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}; 5668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 5768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool DurationGreater(const TraceItem* a, const TraceItem* b) { 5868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return a->delta() > b->delta(); 5968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 6068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 6168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool CoalescedDurationGreater(const Coalesced& a, const Coalesced& b) { 6268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return a.total_duration > b.total_duration; 6368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 6468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 6568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void SummarizeParses(std::vector<const TraceItem*>& loads, 6668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::ostream& out) { 6768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << "File parse times: (time in ms, name)\n"; 6868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 6968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::sort(loads.begin(), loads.end(), &DurationGreater); 7068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 7168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (size_t i = 0; i < loads.size(); i++) { 7268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << base::StringPrintf(" %8.2f ", 7368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) loads[i]->delta().InMillisecondsF()); 7468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << loads[i]->name() << std::endl; 7568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 7668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 7768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 7868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void SummarizeCoalesced(std::vector<const TraceItem*>& items, 7968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::ostream& out) { 8068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Group by file name. 8168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::map<std::string, Coalesced> coalesced; 8268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (size_t i = 0; i < items.size(); i++) { 8368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Coalesced& c = coalesced[items[i]->name()]; 8468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) c.name_ptr = &items[i]->name(); 8568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) c.total_duration += items[i]->delta().InMillisecondsF(); 8668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) c.count++; 8768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 8868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 8968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Sort by duration. 9068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::vector<Coalesced> sorted; 9168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (std::map<std::string, Coalesced>::iterator iter = coalesced.begin(); 9268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) iter != coalesced.end(); ++iter) 9368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) sorted.push_back(iter->second); 9468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::sort(sorted.begin(), sorted.end(), &CoalescedDurationGreater); 9568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 9668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (size_t i = 0; i < sorted.size(); i++) { 9768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << base::StringPrintf(" %8.2f %d ", 9868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) sorted[i].total_duration, sorted[i].count); 9968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << *sorted[i].name_ptr << std::endl; 10068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 10168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 10268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 10368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void SummarizeFileExecs(std::vector<const TraceItem*>& execs, 10468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::ostream& out) { 10568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << "File execute times: (total time in ms, # executions, name)\n"; 10668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) SummarizeCoalesced(execs, out); 10768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 10868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 10968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void SummarizeScriptExecs(std::vector<const TraceItem*>& execs, 11068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::ostream& out) { 11168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << "Script execute times: (total time in ms, # executions, name)\n"; 11268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) SummarizeCoalesced(execs, out); 11368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 11468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 11568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} // namespace 11668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 11768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)TraceItem::TraceItem(Type type, 11868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& name, 11968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) base::PlatformThreadId thread_id) 12068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) : type_(type), 12168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) name_(name), 12268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) thread_id_(thread_id) { 12368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 12468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 12568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)TraceItem::~TraceItem() { 12668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 12768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 12868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)ScopedTrace::ScopedTrace(TraceItem::Type t, const std::string& name) 12968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) : item_(NULL), 13068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) done_(false) { 13168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (trace_log) { 13268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) item_ = new TraceItem(t, name, base::PlatformThread::CurrentId()); 13368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) item_->set_begin(base::TimeTicks::HighResNow()); 13468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 13568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 13668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 13768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)ScopedTrace::~ScopedTrace() { 13868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Done(); 13968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 14068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 14168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void ScopedTrace::SetToolchain(const Label& label) { 14268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (item_) 14368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) item_->set_toolchain(label.GetUserVisibleName(false)); 14468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 14568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 14668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void ScopedTrace::SetCommandLine(const CommandLine& cmdline) { 14768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (item_) 14868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) item_->set_cmdline(FilePathToUTF8(cmdline.GetArgumentsString())); 14968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 15068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 15168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void ScopedTrace::Done() { 15268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!done_) { 15368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) done_ = true; 15468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (trace_log) { 15568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) item_->set_end(base::TimeTicks::HighResNow()); 15668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) AddTrace(item_); 15768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 15868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 15968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 16068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 16168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void EnableTracing() { 16268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) CHECK(!trace_log); 16368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) trace_log = new TraceLog; 16468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 16568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 16668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void AddTrace(TraceItem* item) { 16768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) trace_log->Add(item); 16868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 16968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 17068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)std::string SummarizeTraces() { 17168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!trace_log) 17268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return std::string(); 17368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 17468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::vector<TraceItem*> events = trace_log->events(); 17568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 17668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Classify all events. 17768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::vector<const TraceItem*> parses; 17868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::vector<const TraceItem*> file_execs; 17968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::vector<const TraceItem*> script_execs; 18068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (size_t i = 0; i < events.size(); i++) { 18168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) switch (events[i]->type()) { 18268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) case TraceItem::TRACE_FILE_PARSE: 18368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) parses.push_back(events[i]); 18468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) break; 18568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) case TraceItem::TRACE_FILE_EXECUTE: 18668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) file_execs.push_back(events[i]); 18768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) break; 18868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) case TraceItem::TRACE_SCRIPT_EXECUTE: 18968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) script_execs.push_back(events[i]); 19068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) break; 19168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) case TraceItem::TRACE_FILE_LOAD: 19268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) case TraceItem::TRACE_FILE_WRITE: 19368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) break; // Ignore these for the summary. 19468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 19568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 19668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 19768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::ostringstream out; 19868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) SummarizeParses(parses, out); 19968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << std::endl; 20068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) SummarizeFileExecs(file_execs, out); 20168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << std::endl; 20268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) SummarizeScriptExecs(script_execs, out); 20368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << std::endl; 20468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 20568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return out.str(); 20668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 20768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 20868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void SaveTraces(const base::FilePath& file_name) { 20968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::ostringstream out; 21068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 21168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << "{\"traceEvents\":["; 21268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 21368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::string quote_buffer; // Allocate outside loop to prevent reallocationg. 21468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 21568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::vector<TraceItem*> events = trace_log->events(); 21668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (size_t i = 0; i < events.size(); i++) { 21768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const TraceItem& item = *events[i]; 21868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 21968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (i != 0) 22068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << ","; 22168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << "{\"pid\":0,\"tid\":" << item.thread_id(); 22268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << ",\"ts\":" << item.begin().ToInternalValue(); 22368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << ",\"ph\":\"X\""; // "X" = complete event with begin & duration. 22468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << ",\"dur\":" << item.delta().InMicroseconds(); 22568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 22668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) quote_buffer.resize(0); 22768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) base::JsonDoubleQuote(item.name(), true, "e_buffer); 22868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << ",\"name\":" << quote_buffer; 22968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 23068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << ",\"cat\":"; 23168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) switch (item.type()) { 23268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) case TraceItem::TRACE_FILE_LOAD: 23368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << "\"load\""; 23468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) break; 23568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) case TraceItem::TRACE_FILE_PARSE: 23668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << "\"parse\""; 23768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) break; 23868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) case TraceItem::TRACE_FILE_EXECUTE: 23968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << "\"file_exec\""; 24068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) break; 24168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) case TraceItem::TRACE_FILE_WRITE: 24268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << "\"file_write\""; 24368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) break; 24468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) case TraceItem::TRACE_SCRIPT_EXECUTE: 24568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << "\"script_exec\""; 24668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) break; 24768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 24868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 24968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!item.toolchain().empty() || !item.cmdline().empty()) { 25068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << ",\"args\":{"; 25168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bool needs_comma = false; 25268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!item.toolchain().empty()) { 25368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) quote_buffer.resize(0); 25468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) base::JsonDoubleQuote(item.toolchain(), true, "e_buffer); 25568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << "\"toolchain\":" << quote_buffer; 25668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) needs_comma = true; 25768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 25868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!item.cmdline().empty()) { 25968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) quote_buffer.resize(0); 26068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) base::JsonDoubleQuote(item.cmdline(), true, "e_buffer); 26168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (needs_comma) 26268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << ","; 26368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << "\"cmdline\":" << quote_buffer; 26468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) needs_comma = true; 26568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 26668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << "}"; 26768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 26868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << "}"; 26968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 27068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 27168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << "]}"; 27268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 27368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::string out_str = out.str(); 27468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) file_util::WriteFile(file_name, out_str.data(), out_str.size()); 27568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 276