Merge "profiling/memory: tiny fixups of a couple of copy/move aspects."
diff --git a/src/trace_processor/slice_tracker.cc b/src/trace_processor/slice_tracker.cc
index 45e6c17..a2e9a8e 100644
--- a/src/trace_processor/slice_tracker.cc
+++ b/src/trace_processor/slice_tracker.cc
@@ -46,9 +46,8 @@
UniqueTid utid,
StringId cat,
StringId name) {
- auto& stack = threads_[utid];
- MaybeCloseStack(timestamp, stack);
- stack.emplace_back(Slice{cat, name, timestamp, 0});
+ MaybeCloseStack(timestamp, &threads_[utid]);
+ StartSlice(timestamp, 0, utid, cat, name);
}
void SliceTracker::Scoped(uint64_t timestamp,
@@ -56,12 +55,32 @@
StringId cat,
StringId name,
uint64_t duration) {
- auto& stack = threads_[utid];
- MaybeCloseStack(timestamp, stack);
- stack.emplace_back(Slice{cat, name, timestamp, timestamp + duration});
+ MaybeCloseStack(timestamp, &threads_[utid]);
+ StartSlice(timestamp, duration, utid, cat, name);
CompleteSlice(utid);
}
+void SliceTracker::StartSlice(uint64_t timestamp,
+ uint64_t duration,
+ UniqueTid utid,
+ StringId cat,
+ StringId name) {
+ auto* stack = &threads_[utid];
+ auto* slices = context_->storage->mutable_nestable_slices();
+
+ const uint8_t depth = static_cast<uint8_t>(stack->size());
+ if (depth >= std::numeric_limits<uint8_t>::max()) {
+ PERFETTO_DFATAL("Slices with too large depth found.");
+ return;
+ }
+ uint64_t parent_stack_id = depth == 0 ? 0 : slices->stack_ids().back();
+ size_t slice_idx = slices->AddSlice(timestamp, duration, utid, cat, name,
+ depth, 0, parent_stack_id);
+ stack->emplace_back(slice_idx);
+
+ slices->set_stack_id(slice_idx, GetStackHash(*stack));
+}
+
void SliceTracker::EndAndroid(uint64_t timestamp,
uint32_t ftrace_tid,
uint32_t atrace_tid) {
@@ -81,82 +100,69 @@
UniqueTid utid,
StringId cat,
StringId name) {
- auto& stack = threads_[utid];
- MaybeCloseStack(timestamp, stack);
- if (stack.empty()) {
+ MaybeCloseStack(timestamp, &threads_[utid]);
+
+ const auto& stack = threads_[utid];
+ if (stack.empty())
return;
- }
- PERFETTO_CHECK(cat == 0 || stack.back().cat_id == cat);
- PERFETTO_CHECK(name == 0 || stack.back().name_id == name);
+ auto* slices = context_->storage->mutable_nestable_slices();
+ size_t slice_idx = stack.back();
- Slice& slice = stack.back();
- slice.end_ts = timestamp;
+ PERFETTO_CHECK(cat == 0 || slices->cats()[slice_idx] == cat);
+ PERFETTO_CHECK(name == 0 || slices->names()[slice_idx] == name);
+
+ slices->set_duration(slice_idx, timestamp - slices->start_ns()[slice_idx]);
CompleteSlice(utid);
// TODO(primiano): auto-close B slices left open at the end.
}
void SliceTracker::CompleteSlice(UniqueTid utid) {
- auto& stack = threads_[utid];
- if (stack.size() >= std::numeric_limits<uint8_t>::max()) {
- stack.pop_back();
- return;
- }
- const uint8_t depth = static_cast<uint8_t>(stack.size()) - 1;
-
- uint64_t parent_stack_id, stack_id;
- std::tie(parent_stack_id, stack_id) = GetStackHashes(stack);
-
- Slice& slice = stack.back();
- auto* slices = context_->storage->mutable_nestable_slices();
- slices->AddSlice(slice.start_ts, slice.end_ts - slice.start_ts, utid,
- slice.cat_id, slice.name_id, depth, stack_id,
- parent_stack_id);
-
- stack.pop_back();
+ threads_[utid].pop_back();
}
-void SliceTracker::MaybeCloseStack(uint64_t ts, SlicesStack& stack) {
+void SliceTracker::MaybeCloseStack(uint64_t ts, SlicesStack* stack) {
+ const auto& slices = context_->storage->nestable_slices();
bool check_only = false;
- for (int i = static_cast<int>(stack.size()) - 1; i >= 0; i--) {
- const Slice& slice = stack[size_t(i)];
- if (slice.end_ts == 0) {
+ for (int i = static_cast<int>(stack->size()) - 1; i >= 0; i--) {
+ size_t slice_idx = (*stack)[static_cast<size_t>(i)];
+
+ uint64_t start_ts = slices.start_ns()[slice_idx];
+ uint64_t dur = slices.durations()[slice_idx];
+ uint64_t end_ts = start_ts + dur;
+ if (dur == 0) {
check_only = true;
}
if (check_only) {
- PERFETTO_DCHECK(ts >= slice.start_ts);
- PERFETTO_DCHECK(slice.end_ts == 0 || ts <= slice.end_ts);
+ PERFETTO_DCHECK(ts >= start_ts);
+ PERFETTO_DCHECK(dur == 0 || ts <= end_ts);
continue;
}
- if (slice.end_ts <= ts) {
- stack.pop_back();
+ if (end_ts <= ts) {
+ stack->pop_back();
}
}
}
-// Returns <parent_stack_id, stack_id>, where
-// |parent_stack_id| == hash(stack_id - last slice).
-std::tuple<uint64_t, uint64_t> SliceTracker::GetStackHashes(
- const SlicesStack& stack) {
+uint64_t SliceTracker::GetStackHash(const SlicesStack& stack) {
PERFETTO_DCHECK(!stack.empty());
+
+ const auto& slices = context_->storage->nestable_slices();
+
std::string s;
s.reserve(stack.size() * sizeof(uint64_t) * 2);
- constexpr uint64_t kMask = uint64_t(-1) >> 1;
- uint64_t parent_stack_id = 0;
for (size_t i = 0; i < stack.size(); i++) {
- if (i == stack.size() - 1)
- parent_stack_id = i > 0 ? (std::hash<std::string>{}(s)) & kMask : 0;
- const Slice& slice = stack[i];
- s.append(reinterpret_cast<const char*>(&slice.cat_id),
- sizeof(slice.cat_id));
- s.append(reinterpret_cast<const char*>(&slice.name_id),
- sizeof(slice.name_id));
+ size_t slice_idx = stack[i];
+ s.append(reinterpret_cast<const char*>(&slices.cats()[slice_idx]),
+ sizeof(slices.cats()[slice_idx]));
+ s.append(reinterpret_cast<const char*>(&slices.names()[slice_idx]),
+ sizeof(slices.names()[slice_idx]));
}
- uint64_t stack_id = (std::hash<std::string>{}(s)) & kMask;
- return std::make_tuple(parent_stack_id, stack_id);
+ constexpr uint64_t kMask = uint64_t(-1) >> 1;
+ return (std::hash<std::string>{}(s)) & kMask;
}
} // namespace trace_processor
diff --git a/src/trace_processor/slice_tracker.h b/src/trace_processor/slice_tracker.h
index 1c08d6b..cfed40c 100644
--- a/src/trace_processor/slice_tracker.h
+++ b/src/trace_processor/slice_tracker.h
@@ -53,19 +53,18 @@
StringId opt_name = {});
private:
- struct Slice {
- StringId cat_id;
- StringId name_id;
- uint64_t start_ts;
- uint64_t end_ts; // Only for complete events (scoped TRACE_EVENT macros).
- };
- using SlicesStack = std::vector<Slice>;
+ using SlicesStack = std::vector<size_t>;
- static inline void MaybeCloseStack(uint64_t end_ts, SlicesStack&);
- static inline std::tuple<uint64_t, uint64_t> GetStackHashes(
- const SlicesStack&);
+ void StartSlice(uint64_t timestamp,
+ uint64_t duration,
+ UniqueTid utid,
+ StringId cat,
+ StringId name);
void CompleteSlice(UniqueTid tid);
+ void MaybeCloseStack(uint64_t end_ts, SlicesStack*);
+ uint64_t GetStackHash(const SlicesStack&);
+
TraceProcessorContext* const context_;
std::unordered_map<UniqueTid, SlicesStack> threads_;
std::unordered_map<uint32_t, uint32_t> ftrace_to_atrace_pid_;
diff --git a/src/trace_processor/slice_tracker_unittest.cc b/src/trace_processor/slice_tracker_unittest.cc
index 8eb72b9..bd5ca2e 100644
--- a/src/trace_processor/slice_tracker_unittest.cc
+++ b/src/trace_processor/slice_tracker_unittest.cc
@@ -83,23 +83,24 @@
EXPECT_EQ(slices.slice_count(), 2);
- EXPECT_EQ(slices.start_ns()[0], 3);
- EXPECT_EQ(slices.durations()[0], 2);
- EXPECT_EQ(slices.cats()[0], 0);
- EXPECT_EQ(slices.names()[0], 2);
- EXPECT_EQ(slices.utids()[0], 42);
- EXPECT_EQ(slices.depths()[0], 1);
+ size_t idx = 0;
+ EXPECT_EQ(slices.start_ns()[idx], 2);
+ EXPECT_EQ(slices.durations()[idx], 8);
+ EXPECT_EQ(slices.cats()[idx], 0);
+ EXPECT_EQ(slices.names()[idx], 1);
+ EXPECT_EQ(slices.utids()[idx], 42);
+ EXPECT_EQ(slices.depths()[idx++], 0);
- EXPECT_EQ(slices.start_ns()[1], 2);
- EXPECT_EQ(slices.durations()[1], 8);
- EXPECT_EQ(slices.cats()[1], 0);
- EXPECT_EQ(slices.names()[1], 1);
- EXPECT_EQ(slices.utids()[1], 42);
- EXPECT_EQ(slices.depths()[1], 0);
+ EXPECT_EQ(slices.start_ns()[idx], 3);
+ EXPECT_EQ(slices.durations()[idx], 2);
+ EXPECT_EQ(slices.cats()[idx], 0);
+ EXPECT_EQ(slices.names()[idx], 2);
+ EXPECT_EQ(slices.utids()[idx], 42);
+ EXPECT_EQ(slices.depths()[idx], 1);
- EXPECT_EQ(slices.parent_stack_ids()[1], 0);
- EXPECT_EQ(slices.stack_ids()[1], slices.parent_stack_ids()[0]);
- EXPECT_NE(slices.stack_ids()[0], 0);
+ EXPECT_EQ(slices.parent_stack_ids()[0], 0);
+ EXPECT_EQ(slices.stack_ids()[0], slices.parent_stack_ids()[1]);
+ EXPECT_NE(slices.stack_ids()[1], 0);
}
TEST(SliceTrackerTest, Scoped) {
@@ -115,7 +116,7 @@
auto slices = ToSliceInfo(context.storage->nestable_slices());
EXPECT_THAT(slices,
- ElementsAre(SliceInfo{2, 6}, SliceInfo{1, 8}, SliceInfo{0, 10}));
+ ElementsAre(SliceInfo{0, 10}, SliceInfo{1, 8}, SliceInfo{2, 6}));
}
} // namespace
diff --git a/src/trace_processor/trace_storage.h b/src/trace_processor/trace_storage.h
index 57de9ed..b42b539 100644
--- a/src/trace_processor/trace_storage.h
+++ b/src/trace_processor/trace_storage.h
@@ -124,14 +124,14 @@
class NestableSlices {
public:
- inline void AddSlice(uint64_t start_ns,
- uint64_t duration_ns,
- UniqueTid utid,
- StringId cat,
- StringId name,
- uint8_t depth,
- uint64_t stack_id,
- uint64_t parent_stack_id) {
+ inline size_t AddSlice(uint64_t start_ns,
+ uint64_t duration_ns,
+ UniqueTid utid,
+ StringId cat,
+ StringId name,
+ uint8_t depth,
+ uint64_t stack_id,
+ uint64_t parent_stack_id) {
start_ns_.emplace_back(start_ns);
durations_.emplace_back(duration_ns);
utids_.emplace_back(utid);
@@ -140,6 +140,15 @@
depths_.emplace_back(depth);
stack_ids_.emplace_back(stack_id);
parent_stack_ids_.emplace_back(parent_stack_id);
+ return slice_count() - 1;
+ }
+
+ void set_duration(size_t index, uint64_t duration_ns) {
+ durations_[index] = duration_ns;
+ }
+
+ void set_stack_id(size_t index, uint64_t stack_id) {
+ stack_ids_[index] = stack_id;
}
size_t slice_count() const { return start_ns_.size(); }