OSDN Git Service

ANRdaemon: move trace result from /sdcard to /data am: d93aa41807
[android-x86/system-extras.git] / simpleperf / record.cpp
index c8735e5..fca2403 100644 (file)
@@ -73,25 +73,7 @@ size_t SampleId::CreateContent(const perf_event_attr& attr) {
   sample_id_all = attr.sample_id_all;
   sample_type = attr.sample_type;
   // Other data are not necessary. TODO: Set missing SampleId data.
-  size_t size = 0;
-  if (sample_id_all) {
-    if (sample_type & PERF_SAMPLE_TID) {
-      size += sizeof(PerfSampleTidType);
-    }
-    if (sample_type & PERF_SAMPLE_TIME) {
-      size += sizeof(PerfSampleTimeType);
-    }
-    if (sample_type & PERF_SAMPLE_ID) {
-      size += sizeof(PerfSampleIdType);
-    }
-    if (sample_type & PERF_SAMPLE_STREAM_ID) {
-      size += sizeof(PerfSampleStreamIdType);
-    }
-    if (sample_type & PERF_SAMPLE_CPU) {
-      size += sizeof(PerfSampleCpuType);
-    }
-  }
-  return size;
+  return Size();
 }
 
 void SampleId::ReadFromBinaryFormat(const perf_event_attr& attr, const char* p, const char* end) {
@@ -161,6 +143,28 @@ void SampleId::Dump(size_t indent) const {
   }
 }
 
+size_t SampleId::Size() const {
+  size_t size = 0;
+  if (sample_id_all) {
+    if (sample_type & PERF_SAMPLE_TID) {
+      size += sizeof(PerfSampleTidType);
+    }
+    if (sample_type & PERF_SAMPLE_TIME) {
+      size += sizeof(PerfSampleTimeType);
+    }
+    if (sample_type & PERF_SAMPLE_ID) {
+      size += sizeof(PerfSampleIdType);
+    }
+    if (sample_type & PERF_SAMPLE_STREAM_ID) {
+      size += sizeof(PerfSampleStreamIdType);
+    }
+    if (sample_type & PERF_SAMPLE_CPU) {
+      size += sizeof(PerfSampleCpuType);
+    }
+  }
+  return size;
+}
+
 Record::Record() {
   memset(&header, 0, sizeof(header));
 }
@@ -202,6 +206,10 @@ std::vector<char> MmapRecord::BinaryFormat() const {
   return buf;
 }
 
+void MmapRecord::AdjustSizeBasedOnData() {
+  header.size = sizeof(header) + sizeof(data) + ALIGN(filename.size() + 1, 8) + sample_id.Size();
+}
+
 void MmapRecord::DumpData(size_t indent) const {
   PrintIndented(indent, "pid %u, tid %u, addr 0x%" PRIx64 ", len 0x%" PRIx64 "\n", data.pid,
                 data.tid, data.addr, data.len);
@@ -230,6 +238,10 @@ std::vector<char> Mmap2Record::BinaryFormat() const {
   return buf;
 }
 
+void Mmap2Record::AdjustSizeBasedOnData() {
+  header.size = sizeof(header) + sizeof(data) + ALIGN(filename.size() + 1, 8) + sample_id.Size();
+}
+
 void Mmap2Record::DumpData(size_t indent) const {
   PrintIndented(indent, "pid %u, tid %u, addr 0x%" PRIx64 ", len 0x%" PRIx64 "\n", data.pid,
                 data.tid, data.addr, data.len);
@@ -437,7 +449,8 @@ std::vector<char> SampleRecord::BinaryFormat() const {
 
 void SampleRecord::AdjustSizeBasedOnData() {
   size_t size = BinaryFormat().size();
-  LOG(DEBUG) << "SampleRecord size is changed from " << header.size << " to " << size;
+  LOG(DEBUG) << "Record (type " << RecordTypeToString(header.type) << ") size is changed from "
+      << header.size << " to " << size;
   header.size = size;
 }
 
@@ -492,7 +505,8 @@ void SampleRecord::DumpData(size_t indent) const {
     PrintIndented(indent, "user regs: abi=%" PRId64 "\n", regs_user_data.abi);
     for (size_t i = 0, pos = 0; i < 64; ++i) {
       if ((regs_user_data.reg_mask >> i) & 1) {
-        PrintIndented(indent + 1, "reg (%s) 0x%016" PRIx64 "\n", GetRegName(i).c_str(),
+        PrintIndented(indent + 1, "reg (%s) 0x%016" PRIx64 "\n",
+                      GetRegName(i, ScopedCurrentArch::GetCurrentArch()).c_str(),
                       regs_user_data.regs[pos++]);
       }
     }
@@ -521,7 +535,7 @@ BuildIdRecord::BuildIdRecord(const perf_event_header* pheader) : Record(pheader)
   const char* p = reinterpret_cast<const char*>(pheader + 1);
   const char* end = reinterpret_cast<const char*>(pheader) + pheader->size;
   MoveFromBinaryFormat(pid, p);
-  build_id = BuildId(p);
+  build_id = BuildId(p, BUILD_ID_SIZE);
   p += ALIGN(build_id.Size(), 8);
   filename = p;
   p += ALIGN(filename.size() + 1, 64);
@@ -674,26 +688,27 @@ BuildIdRecord CreateBuildIdRecord(bool in_kernel, pid_t pid, const BuildId& buil
   return record;
 }
 
-bool IsRecordHappensBefore(const Record* r1, const Record* r2) {
-  bool is_r1_sample = (r1->header.type == PERF_RECORD_SAMPLE);
-  bool is_r2_sample = (r2->header.type == PERF_RECORD_SAMPLE);
-  uint64_t time1 = r1->Timestamp();
-  uint64_t time2 = r2->Timestamp();
+bool RecordCache::RecordWithSeq::IsHappensBefore(const RecordWithSeq& other) const {
+  bool is_sample = (record->header.type == PERF_RECORD_SAMPLE);
+  bool is_other_sample = (other.record->header.type == PERF_RECORD_SAMPLE);
+  uint64_t time = record->Timestamp();
+  uint64_t other_time = other.record->Timestamp();
   // The record with smaller time happens first.
-  if (time1 != time2) {
-    return time1 < time2;
+  if (time != other_time) {
+    return time < other_time;
   }
   // If happening at the same time, make non-sample records before sample records,
   // because non-sample records may contain useful information to parse sample records.
-  if (is_r1_sample != is_r2_sample) {
-    return is_r1_sample ? false : true;
+  if (is_sample != is_other_sample) {
+    return is_sample ? false : true;
   }
-  // Otherwise, don't care of the order.
-  return false;
+  // Otherwise, use the same order as they enter the cache.
+  return seq < other.seq;
 }
 
-bool RecordCache::RecordComparator::operator()(const Record* r1, const Record* r2) {
-  return !IsRecordHappensBefore(r1, r2);
+bool RecordCache::RecordComparator::operator()(const RecordWithSeq& r1,
+                                               const RecordWithSeq& r2) {
+  return r2.IsHappensBefore(r1);
 }
 
 RecordCache::RecordCache(const perf_event_attr& attr, size_t min_cache_size,
@@ -703,6 +718,7 @@ RecordCache::RecordCache(const perf_event_attr& attr, size_t min_cache_size,
       min_cache_size_(min_cache_size),
       min_time_diff_in_ns_(min_time_diff_in_ns),
       last_time_(0),
+      cur_seq_(0),
       queue_(RecordComparator()) {
 }
 
@@ -718,19 +734,19 @@ void RecordCache::Push(const char* data, size_t size) {
     }
   }
   for (auto& r : records) {
-    queue_.push(r.release());
+    queue_.push(CreateRecordWithSeq(r.release()));
   }
 }
 
 void RecordCache::Push(std::unique_ptr<Record> record) {
-  queue_.push(record.release());
+  queue_.push(CreateRecordWithSeq(record.release()));
 }
 
 std::unique_ptr<Record> RecordCache::Pop() {
   if (queue_.size() < min_cache_size_) {
     return nullptr;
   }
-  Record* r = queue_.top();
+  Record* r = queue_.top().record;
   if (has_timestamp_) {
     if (r->Timestamp() + min_time_diff_in_ns_ > last_time_) {
       return nullptr;
@@ -743,8 +759,15 @@ std::unique_ptr<Record> RecordCache::Pop() {
 std::vector<std::unique_ptr<Record>> RecordCache::PopAll() {
   std::vector<std::unique_ptr<Record>> result;
   while (!queue_.empty()) {
-    result.emplace_back(queue_.top());
+    result.emplace_back(queue_.top().record);
     queue_.pop();
   }
   return result;
 }
+
+RecordCache::RecordWithSeq RecordCache::CreateRecordWithSeq(Record *r) {
+  RecordWithSeq result;
+  result.seq = cur_seq_++;
+  result.record = r;
+  return result;
+}