trace.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
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) 137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ScopedTrace::ScopedTrace(TraceItem::Type t, const Label& label) 138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) : item_(NULL), 139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) done_(false) { 140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (trace_log) { 141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) item_ = new TraceItem(t, label.GetUserVisibleName(false), 142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::PlatformThread::CurrentId()); 143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) item_->set_begin(base::TimeTicks::HighResNow()); 144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 14768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)ScopedTrace::~ScopedTrace() { 14868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Done(); 14968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 15068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 15168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void ScopedTrace::SetToolchain(const Label& label) { 15268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (item_) 15368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) item_->set_toolchain(label.GetUserVisibleName(false)); 15468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 15568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 15668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void ScopedTrace::SetCommandLine(const CommandLine& cmdline) { 15768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (item_) 15868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) item_->set_cmdline(FilePathToUTF8(cmdline.GetArgumentsString())); 15968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 16068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 16168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void ScopedTrace::Done() { 16268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!done_) { 16368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) done_ = true; 16468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (trace_log) { 16568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) item_->set_end(base::TimeTicks::HighResNow()); 16668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) AddTrace(item_); 16768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 16868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 16968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 17068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 17168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void EnableTracing() { 17268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) CHECK(!trace_log); 17368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) trace_log = new TraceLog; 17468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 17568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 17668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void AddTrace(TraceItem* item) { 17768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) trace_log->Add(item); 17868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 17968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 18068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)std::string SummarizeTraces() { 18168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!trace_log) 18268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return std::string(); 18368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 18468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::vector<TraceItem*> events = trace_log->events(); 18568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 18668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Classify all events. 18768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::vector<const TraceItem*> parses; 18868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::vector<const TraceItem*> file_execs; 18968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::vector<const TraceItem*> script_execs; 19068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (size_t i = 0; i < events.size(); i++) { 19168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) switch (events[i]->type()) { 19268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) case TraceItem::TRACE_FILE_PARSE: 19368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) parses.push_back(events[i]); 19468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) break; 19568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) case TraceItem::TRACE_FILE_EXECUTE: 19668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) file_execs.push_back(events[i]); 19768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) break; 19868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) case TraceItem::TRACE_SCRIPT_EXECUTE: 19968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) script_execs.push_back(events[i]); 20068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) break; 20168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) case TraceItem::TRACE_FILE_LOAD: 20268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) case TraceItem::TRACE_FILE_WRITE: 203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case TraceItem::TRACE_DEFINE_TARGET: 20468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) break; // Ignore these for the summary. 20568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 20668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 20768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 20868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::ostringstream out; 20968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) SummarizeParses(parses, out); 21068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << std::endl; 21168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) SummarizeFileExecs(file_execs, out); 21268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << std::endl; 21368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) SummarizeScriptExecs(script_execs, out); 21468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << std::endl; 21568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 21668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return out.str(); 21768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 21868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 21968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void SaveTraces(const base::FilePath& file_name) { 22068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::ostringstream out; 22168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 22268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << "{\"traceEvents\":["; 22368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 22468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::string quote_buffer; // Allocate outside loop to prevent reallocationg. 22568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Write main thread metadata (assume this is being written on the main 227f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // thread). 228f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) out << "{\"pid\":0,\"tid\":" << base::PlatformThread::CurrentId(); 229f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) out << ",\"ts\":0,\"ph\":\"M\","; 230f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) out << "\"name\":\"thread_name\",\"args\":{\"name\":\"Main thread\"}},"; 231f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 23268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::vector<TraceItem*> events = trace_log->events(); 23368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (size_t i = 0; i < events.size(); i++) { 23468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const TraceItem& item = *events[i]; 23568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 23668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (i != 0) 23768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << ","; 23868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << "{\"pid\":0,\"tid\":" << item.thread_id(); 23968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << ",\"ts\":" << item.begin().ToInternalValue(); 24068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << ",\"ph\":\"X\""; // "X" = complete event with begin & duration. 24168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << ",\"dur\":" << item.delta().InMicroseconds(); 24268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 24368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) quote_buffer.resize(0); 2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::EscapeJSONString(item.name(), true, "e_buffer); 24568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << ",\"name\":" << quote_buffer; 24668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 24768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << ",\"cat\":"; 24868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) switch (item.type()) { 24968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) case TraceItem::TRACE_FILE_LOAD: 25068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << "\"load\""; 25168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) break; 25268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) case TraceItem::TRACE_FILE_PARSE: 25368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << "\"parse\""; 25468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) break; 25568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) case TraceItem::TRACE_FILE_EXECUTE: 25668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << "\"file_exec\""; 25768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) break; 25868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) case TraceItem::TRACE_FILE_WRITE: 25968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << "\"file_write\""; 26068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) break; 26168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) case TraceItem::TRACE_SCRIPT_EXECUTE: 26268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << "\"script_exec\""; 26368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) break; 264f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case TraceItem::TRACE_DEFINE_TARGET: 265f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) out << "\"define\""; 26668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 26768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 26868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!item.toolchain().empty() || !item.cmdline().empty()) { 26968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << ",\"args\":{"; 27068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bool needs_comma = false; 27168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!item.toolchain().empty()) { 27268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) quote_buffer.resize(0); 2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::EscapeJSONString(item.toolchain(), true, "e_buffer); 27468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << "\"toolchain\":" << quote_buffer; 27568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) needs_comma = true; 27668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 27768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!item.cmdline().empty()) { 27868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) quote_buffer.resize(0); 2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::EscapeJSONString(item.cmdline(), true, "e_buffer); 28068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (needs_comma) 28168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << ","; 28268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << "\"cmdline\":" << quote_buffer; 28368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) needs_comma = true; 28468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 28568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << "}"; 28668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 28768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << "}"; 28868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 28968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 29068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) out << "]}"; 29168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 29268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::string out_str = out.str(); 293a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::WriteFile(file_name, out_str.data(), 2944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) static_cast<int>(out_str.size())); 29568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 296