Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 49346585 authored by Yurii Zubrytskyi's avatar Yurii Zubrytskyi Committed by Android (Google) Code Review
Browse files

Merge "[aapt2] Fix and optimize tracing" into main

parents 2cd7e61b 76d51b13
Loading
Loading
Loading
Loading
+75 −53
Original line number Diff line number Diff line
@@ -36,13 +36,14 @@ constexpr char kBegin = 'B';
constexpr char kEnd = 'E';

struct TracePoint {
  char type;
  pid_t tid;
  int64_t time;
  std::string tag;
  char type;
};

std::vector<TracePoint> traces;
bool enabled = true;

int64_t GetTime() noexcept {
  auto now = std::chrono::steady_clock::now();
@@ -51,34 +52,39 @@ int64_t GetTime() noexcept {

} // namespace anonymous

void AddWithTime(const std::string& tag, char type, int64_t time) noexcept {
  TracePoint t = {getpid(), time, tag, type};
  traces.emplace_back(t);
void AddWithTime(std::string tag, char type, int64_t time) noexcept {
  TracePoint t = {type, getpid(), time, std::move(tag)};
  traces.emplace_back(std::move(t));
}

void Add(const std::string& tag, char type) noexcept {
  AddWithTime(tag, type, GetTime());
void Add(std::string tag, char type) noexcept {
  AddWithTime(std::move(tag), type, GetTime());
}




void Flush(const std::string& basePath) {
  TRACE_CALL();
  if (basePath.empty()) {
    return;
  }
  BeginTrace(__func__);  // We can't do much here, only record that it happened.

  std::stringstream s;
  std::ostringstream s;
  s << basePath << aapt::file::sDirSep << "report_aapt2_" << getpid() << ".json";
  FILE* f = android::base::utf8::fopen(s.str().c_str(), "a");
  if (f == nullptr) {
    return;
  }

  // Wrap the trace in a JSON array [] to make Chrome/Perfetto UI handle it.
  char delimiter = '[';
  for(const TracePoint& trace : traces) {
    fprintf(f, "{\"ts\" : \"%" PRIu64 "\", \"ph\" : \"%c\", \"tid\" : \"%d\" , \"pid\" : \"%d\", "
            "\"name\" : \"%s\" },\n", trace.time, trace.type, 0, trace.tid, trace.tag.c_str());
    fprintf(f,
            "%c{\"ts\" : \"%" PRIu64
            "\", \"ph\" : \"%c\", \"tid\" : \"%d\" , \"pid\" : \"%d\", \"name\" : \"%s\" }\n",
            delimiter, trace.time, trace.type, 0, trace.tid, trace.tag.c_str());
    delimiter = ',';
  }
  if (!traces.empty()) {
    fprintf(f, "]");
  }
  fclose(f);
  traces.clear();
@@ -86,66 +92,82 @@ void Flush(const std::string& basePath) {

} // namespace tracebuffer

void BeginTrace(const std::string& tag) {
  tracebuffer::Add(tag, tracebuffer::kBegin);
void BeginTrace(std::string tag) {
  if (!tracebuffer::enabled) return;
  tracebuffer::Add(std::move(tag), tracebuffer::kBegin);
}

void EndTrace(std::string tag) {
  if (!tracebuffer::enabled) return;
  tracebuffer::Add(std::move(tag), tracebuffer::kEnd);
}

bool Trace::enable(bool value) {
  return tracebuffer::enabled = value;
}

void EndTrace() {
  tracebuffer::Add("", tracebuffer::kEnd);
Trace::Trace(const char* tag) {
  if (!tracebuffer::enabled) return;
  tag_.assign(tag);
  tracebuffer::Add(tag_, tracebuffer::kBegin);
}

Trace::Trace(const std::string& tag) {
  tracebuffer::Add(tag, tracebuffer::kBegin);
Trace::Trace(std::string tag) : tag_(std::move(tag)) {
  if (!tracebuffer::enabled) return;
  tracebuffer::Add(tag_, tracebuffer::kBegin);
}

Trace::Trace(const std::string& tag, const std::vector<android::StringPiece>& args) {
  std::stringstream s;
template <class SpanOfStrings>
std::string makeTag(std::string_view tag, const SpanOfStrings& args) {
  std::ostringstream s;
  s << tag;
  s << " ";
  for (auto& arg : args) {
  if (!args.empty()) {
    for (const auto& arg : args) {
      s << ' ';
      s << arg;
    s << " ";
    }
  tracebuffer::Add(s.str(), tracebuffer::kBegin);
  }

Trace::~Trace() {
  tracebuffer::Add("", tracebuffer::kEnd);
  return std::move(s).str();
}

FlushTrace::FlushTrace(const std::string& basepath, const std::string& tag)
    : basepath_(basepath)  {
  tracebuffer::Add(tag, tracebuffer::kBegin);
Trace::Trace(std::string_view tag, const std::vector<android::StringPiece>& args) {
  if (!tracebuffer::enabled) return;
  tag_ = makeTag(tag, args);
  tracebuffer::Add(tag_, tracebuffer::kBegin);
}

FlushTrace::FlushTrace(const std::string& basepath, const std::string& tag,
    const std::vector<android::StringPiece>& args) : basepath_(basepath) {
  std::stringstream s;
  s << tag;
  s << " ";
  for (auto& arg : args) {
    s << arg;
    s << " ";
Trace::~Trace() {
  if (!tracebuffer::enabled) return;
  tracebuffer::Add(std::move(tag_), tracebuffer::kEnd);
}
  tracebuffer::Add(s.str(), tracebuffer::kBegin);

FlushTrace::FlushTrace(std::string_view basepath, std::string_view tag) {
  if (!Trace::enable(!basepath.empty())) return;
  basepath_.assign(basepath);
  tag_.assign(tag);
  tracebuffer::Add(tag_, tracebuffer::kBegin);
}

FlushTrace::FlushTrace(const std::string& basepath, const std::string& tag,
    const std::vector<std::string>& args) : basepath_(basepath){
  std::stringstream s;
  s << tag;
  s << " ";
  for (auto& arg : args) {
    s << arg;
    s << " ";
FlushTrace::FlushTrace(std::string_view basepath, std::string_view tag,
                       const std::vector<android::StringPiece>& args) {
  if (!Trace::enable(!basepath.empty())) return;
  basepath_.assign(basepath);
  tag_ = makeTag(tag, args);
  tracebuffer::Add(tag_, tracebuffer::kBegin);
}
  tracebuffer::Add(s.str(), tracebuffer::kBegin);

FlushTrace::FlushTrace(std::string_view basepath, std::string_view tag,
                       const std::vector<std::string>& args) {
  if (!Trace::enable(!basepath.empty())) return;
  basepath_.assign(basepath);
  tag_ = makeTag(tag, args);
  tracebuffer::Add(tag_, tracebuffer::kBegin);
}

FlushTrace::~FlushTrace() {
  tracebuffer::Add("", tracebuffer::kEnd);
  if (!tracebuffer::enabled) return;
  tracebuffer::Add(tag_, tracebuffer::kEnd);
  tracebuffer::Flush(basepath_);
}

}  // namespace aapt
+23 −14
Original line number Diff line number Diff line
@@ -17,41 +17,50 @@
#ifndef AAPT_TRACEBUFFER_H
#define AAPT_TRACEBUFFER_H

#include <androidfw/StringPiece.h>

#include <string>
#include <string_view>
#include <vector>

#include <androidfw/StringPiece.h>

namespace aapt {

// Record timestamps for beginning and end of a task and generate systrace json fragments.
// This is an in-process ftrace which has the advantage of being platform independent.
// These methods are NOT thread-safe since aapt2 is not multi-threaded.

// Convenience RIAA object to automatically finish an event when object goes out of scope.
// Convenience RAII object to automatically finish an event when object goes out of scope.
class Trace {
public:
  Trace(const std::string& tag);
  Trace(const std::string& tag, const std::vector<android::StringPiece>& args);
 Trace(const char* tag);
 Trace(std::string tag);
 Trace(std::string_view tag, const std::vector<android::StringPiece>& args);
 ~Trace();

 static bool enable(bool value = true);

private:
 std::string tag_;
};

// Manual markers.
void BeginTrace(const std::string& tag);
void EndTrace();
void BeginTrace(std::string tag);
void EndTrace(std::string tag);

// A main trace is required to flush events to disk. Events are formatted in systrace
// json format.
class FlushTrace {
public:
  explicit FlushTrace(const std::string& basepath, const std::string& tag);
  explicit FlushTrace(const std::string& basepath, const std::string& tag,
 explicit FlushTrace(std::string_view basepath, std::string_view tag);
 explicit FlushTrace(std::string_view basepath, std::string_view tag,
                     const std::vector<android::StringPiece>& args);
  explicit FlushTrace(const std::string& basepath, const std::string& tag,
 explicit FlushTrace(std::string_view basepath, std::string_view tag,
                     const std::vector<std::string>& args);
 ~FlushTrace();

private:
  std::string basepath_;
  std::string tag_;
};

#define TRACE_CALL() Trace __t(__func__)