Merge "Major clean up build files, use flags-per-feature."
diff --git a/Android.bp b/Android.bp
index d9972ad..5202139 100644
--- a/Android.bp
+++ b/Android.bp
@@ -4750,6 +4750,7 @@
"src/trace_processor/clock_tracker.cc",
"src/trace_processor/counter_definitions_table.cc",
"src/trace_processor/counter_values_table.cc",
+ "src/trace_processor/cpu_profile_stack_sample_table.cc",
"src/trace_processor/db/bit_vector.cc",
"src/trace_processor/db/column.cc",
"src/trace_processor/db/row_map.cc",
@@ -4954,6 +4955,7 @@
"src/trace_processor/clock_tracker.cc",
"src/trace_processor/counter_definitions_table.cc",
"src/trace_processor/counter_values_table.cc",
+ "src/trace_processor/cpu_profile_stack_sample_table.cc",
"src/trace_processor/db/bit_vector.cc",
"src/trace_processor/db/column.cc",
"src/trace_processor/db/row_map.cc",
diff --git a/BUILD b/BUILD
index ebc1851..b332ccc 100644
--- a/BUILD
+++ b/BUILD
@@ -314,6 +314,8 @@
"src/trace_processor/counter_definitions_table.h",
"src/trace_processor/counter_values_table.cc",
"src/trace_processor/counter_values_table.h",
+ "src/trace_processor/cpu_profile_stack_sample_table.cc",
+ "src/trace_processor/cpu_profile_stack_sample_table.h",
"src/trace_processor/db/bit_vector.cc",
"src/trace_processor/db/bit_vector.h",
"src/trace_processor/db/column.cc",
@@ -637,6 +639,8 @@
"src/trace_processor/counter_definitions_table.h",
"src/trace_processor/counter_values_table.cc",
"src/trace_processor/counter_values_table.h",
+ "src/trace_processor/cpu_profile_stack_sample_table.cc",
+ "src/trace_processor/cpu_profile_stack_sample_table.h",
"src/trace_processor/db/bit_vector.cc",
"src/trace_processor/db/bit_vector.h",
"src/trace_processor/db/column.cc",
@@ -909,6 +913,8 @@
"src/trace_processor/counter_definitions_table.h",
"src/trace_processor/counter_values_table.cc",
"src/trace_processor/counter_values_table.h",
+ "src/trace_processor/cpu_profile_stack_sample_table.cc",
+ "src/trace_processor/cpu_profile_stack_sample_table.h",
"src/trace_processor/db/bit_vector.cc",
"src/trace_processor/db/bit_vector.h",
"src/trace_processor/db/column.cc",
diff --git a/src/trace_processor/BUILD.gn b/src/trace_processor/BUILD.gn
index aa193a7..7dbb4ac 100644
--- a/src/trace_processor/BUILD.gn
+++ b/src/trace_processor/BUILD.gn
@@ -62,6 +62,8 @@
"counter_definitions_table.h",
"counter_values_table.cc",
"counter_values_table.h",
+ "cpu_profile_stack_sample_table.cc",
+ "cpu_profile_stack_sample_table.h",
"event_tracker.cc",
"event_tracker.h",
"filtered_row_index.cc",
@@ -274,6 +276,7 @@
"../../protos/perfetto/trace/ftrace:zero",
"../../protos/perfetto/trace/gpu:zero",
"../../protos/perfetto/trace/interned_data:zero",
+ "../../protos/perfetto/trace/profiling:zero",
"../../protos/perfetto/trace/ps:zero",
"../../protos/perfetto/trace/sys_stats:zero",
"../../protos/perfetto/trace/track_event:zero",
diff --git a/src/trace_processor/cpu_profile_stack_sample_table.cc b/src/trace_processor/cpu_profile_stack_sample_table.cc
new file mode 100644
index 0000000..bb51404
--- /dev/null
+++ b/src/trace_processor/cpu_profile_stack_sample_table.cc
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/trace_processor/cpu_profile_stack_sample_table.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+CpuProfileStackSampleTable::CpuProfileStackSampleTable(
+ sqlite3*,
+ const TraceStorage* storage)
+ : storage_(storage) {}
+
+void CpuProfileStackSampleTable::RegisterTable(sqlite3* db,
+ const TraceStorage* storage) {
+ SqliteTable::Register<CpuProfileStackSampleTable>(db, storage,
+ "cpu_profile_stack_sample");
+}
+
+StorageSchema CpuProfileStackSampleTable::CreateStorageSchema() {
+ const auto& allocs = storage_->cpu_profile_stack_samples();
+ return StorageSchema::Builder()
+ .AddGenericNumericColumn("id", RowAccessor())
+ .AddOrderedNumericColumn("ts", &allocs.timestamps())
+ .AddNumericColumn("callsite_id", &allocs.callsite_ids())
+ .AddNumericColumn("utid", &allocs.utids())
+ .Build({"id"});
+}
+
+uint32_t CpuProfileStackSampleTable::RowCount() {
+ return storage_->cpu_profile_stack_samples().size();
+}
+
+int CpuProfileStackSampleTable::BestIndex(const QueryConstraints& qc,
+ BestIndexInfo* info) {
+ info->order_by_consumed = true;
+ info->estimated_cost = HasEqConstraint(qc, "id") ? 1 : RowCount();
+ return SQLITE_OK;
+}
+
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/cpu_profile_stack_sample_table.h b/src/trace_processor/cpu_profile_stack_sample_table.h
new file mode 100644
index 0000000..e422d75
--- /dev/null
+++ b/src/trace_processor/cpu_profile_stack_sample_table.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_CPU_PROFILE_STACK_SAMPLE_TABLE_H_
+#define SRC_TRACE_PROCESSOR_CPU_PROFILE_STACK_SAMPLE_TABLE_H_
+
+#include "src/trace_processor/storage_table.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+class CpuProfileStackSampleTable : public StorageTable {
+ public:
+ static void RegisterTable(sqlite3* db, const TraceStorage* storage);
+
+ CpuProfileStackSampleTable(sqlite3*, const TraceStorage*);
+
+ // StorageTable implementation.
+ StorageSchema CreateStorageSchema() override;
+ uint32_t RowCount() override;
+ int BestIndex(const QueryConstraints&, BestIndexInfo*) override;
+
+ private:
+ const TraceStorage* const storage_;
+};
+
+} // namespace trace_processor
+} // namespace perfetto
+
+#endif // SRC_TRACE_PROCESSOR_CPU_PROFILE_STACK_SAMPLE_TABLE_H_
diff --git a/src/trace_processor/proto_trace_parser.cc b/src/trace_processor/proto_trace_parser.cc
index 7da23ca..58de79f 100644
--- a/src/trace_processor/proto_trace_parser.cc
+++ b/src/trace_processor/proto_trace_parser.cc
@@ -427,6 +427,11 @@
if (packet.has_profile_packet())
ParseProfilePacket(ts, ttp.packet_sequence_state, packet.profile_packet());
+ if (packet.has_streaming_profile_packet()) {
+ ParseStreamingProfilePacket(ttp.packet_sequence_state,
+ packet.streaming_profile_packet());
+ }
+
if (packet.has_profiled_frame_symbols())
ParseProfiledFrameSymbols(ttp.packet_sequence_state,
packet.profiled_frame_symbols());
@@ -1500,6 +1505,49 @@
}
}
+void ProtoTraceParser::ParseStreamingProfilePacket(
+ ProtoIncrementalState::PacketSequenceState* sequence_state,
+ ConstBytes blob) {
+ protos::pbzero::StreamingProfilePacket::Decoder packet(blob.data, blob.size);
+
+ ProcessTracker* procs = context_->process_tracker.get();
+ TraceStorage* storage = context_->storage.get();
+ StackProfileTracker* stack_profile_tracker =
+ context_->stack_profile_tracker.get();
+ ProfilePacketInternLookup intern_lookup(sequence_state, storage);
+
+ uint32_t pid = static_cast<uint32_t>(sequence_state->pid());
+ uint32_t tid = static_cast<uint32_t>(sequence_state->tid());
+ UniqueTid utid = procs->UpdateThread(tid, pid);
+
+ auto timestamp_it = packet.timestamp_delta_us();
+ for (auto callstack_it = packet.callstack_iid(); callstack_it;
+ ++callstack_it, ++timestamp_it) {
+ if (!timestamp_it) {
+ context_->storage->IncrementStats(stats::stackprofile_parser_error);
+ PERFETTO_ELOG(
+ "StreamingProfilePacket has less callstack IDs than timestamps!");
+ break;
+ }
+
+ auto maybe_callstack_id = stack_profile_tracker->FindCallstack(
+ callstack_it->as_uint64(), &intern_lookup);
+ if (!maybe_callstack_id) {
+ context_->storage->IncrementStats(stats::stackprofile_parser_error);
+ PERFETTO_ELOG("StreamingProfilePacket referencing invalid callstack!");
+ continue;
+ }
+
+ int64_t callstack_id = *maybe_callstack_id;
+
+ TraceStorage::CpuProfileStackSamples::Row sample_row{
+ sequence_state->IncrementAndGetTrackEventTimeNs(
+ timestamp_it->as_int64()),
+ callstack_id, utid};
+ storage->mutable_cpu_profile_stack_samples()->Insert(sample_row);
+ }
+}
+
void ProtoTraceParser::ParseProfiledFrameSymbols(
ProtoIncrementalState::PacketSequenceState* sequence_state,
ConstBytes blob) {
diff --git a/src/trace_processor/proto_trace_parser.h b/src/trace_processor/proto_trace_parser.h
index c2fd422..6edccc4 100644
--- a/src/trace_processor/proto_trace_parser.h
+++ b/src/trace_processor/proto_trace_parser.h
@@ -97,6 +97,8 @@
void ParseProfilePacket(int64_t ts,
ProtoIncrementalState::PacketSequenceState*,
ConstBytes);
+ void ParseStreamingProfilePacket(ProtoIncrementalState::PacketSequenceState*,
+ ConstBytes);
void ParseProfiledFrameSymbols(ProtoIncrementalState::PacketSequenceState*,
ConstBytes);
void ParseSystemInfo(ConstBytes);
diff --git a/src/trace_processor/proto_trace_parser_unittest.cc b/src/trace_processor/proto_trace_parser_unittest.cc
index 1b75c5d..4e0589d 100644
--- a/src/trace_processor/proto_trace_parser_unittest.cc
+++ b/src/trace_processor/proto_trace_parser_unittest.cc
@@ -24,6 +24,7 @@
#include "src/trace_processor/process_tracker.h"
#include "src/trace_processor/proto_trace_parser.h"
#include "src/trace_processor/slice_tracker.h"
+#include "src/trace_processor/stack_profile_tracker.h"
#include "src/trace_processor/systrace_parser.h"
#include "src/trace_processor/trace_sorter.h"
#include "src/trace_processor/virtual_track_tracker.h"
@@ -41,6 +42,7 @@
#include "protos/perfetto/trace/ftrace/sched.pbzero.h"
#include "protos/perfetto/trace/ftrace/task.pbzero.h"
#include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
+#include "protos/perfetto/trace/profiling/profile_packet.pbzero.h"
#include "protos/perfetto/trace/ps/process_tree.pbzero.h"
#include "protos/perfetto/trace/sys_stats/sys_stats.pbzero.h"
#include "protos/perfetto/trace/trace.pbzero.h"
@@ -199,6 +201,7 @@
context_.sorter.reset(new TraceSorter(&context_, 0 /*window size*/));
context_.parser.reset(new ProtoTraceParser(&context_));
context_.systrace_parser.reset(new SystraceParser(&context_));
+ context_.stack_profile_tracker.reset(new StackProfileTracker(&context_));
}
void ResetTraceBuffers() {
@@ -2066,6 +2069,86 @@
EXPECT_EQ(find_arg(second_set_id, "version_code").int_value, 43);
}
+TEST_F(ProtoTraceParserTest, ParseCPUProfileSamplesIntoTable) {
+ {
+ auto* packet = trace_.add_packet();
+ packet->set_trusted_packet_sequence_id(1);
+ packet->set_incremental_state_cleared(true);
+
+ auto* thread_desc = packet->set_thread_descriptor();
+ thread_desc->set_pid(15);
+ thread_desc->set_tid(16);
+ thread_desc->set_reference_timestamp_us(1);
+ thread_desc->set_reference_thread_time_us(2);
+
+ auto* interned_data = packet->set_interned_data();
+
+ auto mapping = interned_data->add_mappings();
+ mapping->set_iid(1);
+
+ auto frame = interned_data->add_frames();
+ frame->set_iid(1);
+ frame->set_rel_pc(0x42);
+ frame->set_mapping_id(1);
+
+ auto frame2 = interned_data->add_frames();
+ frame2->set_iid(2);
+ frame2->set_rel_pc(0x4242);
+ frame2->set_mapping_id(1);
+
+ auto callstack = interned_data->add_callstacks();
+ callstack->set_iid(1);
+ callstack->add_frame_ids(1);
+
+ auto callstack2 = interned_data->add_callstacks();
+ callstack2->set_iid(42);
+ callstack2->add_frame_ids(2);
+ }
+
+ {
+ auto* packet = trace_.add_packet();
+ packet->set_trusted_packet_sequence_id(1);
+
+ auto* samples = packet->set_streaming_profile_packet();
+ samples->add_callstack_iid(42);
+ samples->add_timestamp_delta_us(10);
+
+ samples->add_callstack_iid(1);
+ samples->add_timestamp_delta_us(15);
+ }
+
+ {
+ auto* packet = trace_.add_packet();
+ packet->set_trusted_packet_sequence_id(1);
+ auto* samples = packet->set_streaming_profile_packet();
+
+ samples->add_callstack_iid(42);
+ samples->add_timestamp_delta_us(42);
+ }
+
+ EXPECT_CALL(*process_, UpdateThread(16, 15))
+ .Times(2)
+ .WillRepeatedly(Return(1));
+
+ Tokenize();
+
+ // Verify cpu_profile_samples.
+ const auto& samples = storage_->cpu_profile_stack_samples();
+ EXPECT_EQ(samples.size(), 3u);
+
+ EXPECT_EQ(samples.timestamps()[0], 1010);
+ EXPECT_EQ(samples.callsite_ids()[0], 0);
+ EXPECT_EQ(samples.utids()[0], 1u);
+
+ EXPECT_EQ(samples.timestamps()[1], 1025);
+ EXPECT_EQ(samples.callsite_ids()[1], 1);
+ EXPECT_EQ(samples.utids()[1], 1u);
+
+ EXPECT_EQ(samples.timestamps()[2], 1067);
+ EXPECT_EQ(samples.callsite_ids()[2], 0);
+ EXPECT_EQ(samples.utids()[2], 1u);
+}
+
} // namespace
} // namespace trace_processor
} // namespace perfetto
diff --git a/src/trace_processor/stats.h b/src/trace_processor/stats.h
index b9d3fe7..b7bd13e 100644
--- a/src/trace_processor/stats.h
+++ b/src/trace_processor/stats.h
@@ -71,6 +71,7 @@
F(stackprofile_invalid_mapping_id, kSingle, kError, kTrace), \
F(stackprofile_invalid_frame_id, kSingle, kError, kTrace), \
F(stackprofile_invalid_callstack_id, kSingle, kError, kTrace), \
+ F(stackprofile_parser_error, kSingle, kError, kTrace), \
F(systrace_parse_failure, kSingle, kError, kAnalysis), \
F(task_state_invalid, kSingle, kError, kAnalysis), \
F(traced_buf_buffer_size, kIndexed, kInfo, kTrace), \
diff --git a/src/trace_processor/trace_processor_impl.cc b/src/trace_processor/trace_processor_impl.cc
index 6a3f23b..d370351 100644
--- a/src/trace_processor/trace_processor_impl.cc
+++ b/src/trace_processor/trace_processor_impl.cc
@@ -32,6 +32,7 @@
#include "src/trace_processor/clock_tracker.h"
#include "src/trace_processor/counter_definitions_table.h"
#include "src/trace_processor/counter_values_table.h"
+#include "src/trace_processor/cpu_profile_stack_sample_table.h"
#include "src/trace_processor/event_tracker.h"
#include "src/trace_processor/forwarding_trace_parser.h"
#include "src/trace_processor/heap_profile_allocation_table.h"
@@ -295,6 +296,7 @@
AndroidLogsTable::RegisterTable(*db_, context_.storage.get());
RawTable::RegisterTable(*db_, context_.storage.get());
HeapProfileAllocationTable::RegisterTable(*db_, context_.storage.get());
+ CpuProfileStackSampleTable::RegisterTable(*db_, context_.storage.get());
StackProfileCallsiteTable::RegisterTable(*db_, context_.storage.get());
StackProfileFrameTable::RegisterTable(*db_, context_.storage.get());
StackProfileMappingTable::RegisterTable(*db_, context_.storage.get());
diff --git a/src/trace_processor/trace_storage.h b/src/trace_processor/trace_storage.h
index dad9744..3854435 100644
--- a/src/trace_processor/trace_storage.h
+++ b/src/trace_processor/trace_storage.h
@@ -1100,6 +1100,32 @@
std::deque<int64_t> sizes_;
};
+ class CpuProfileStackSamples {
+ public:
+ struct Row {
+ int64_t timestamp;
+ int64_t callsite_id;
+ UniqueTid utid;
+ };
+
+ uint32_t size() const { return static_cast<uint32_t>(timestamps_.size()); }
+
+ void Insert(const Row& row) {
+ timestamps_.emplace_back(row.timestamp);
+ callsite_ids_.emplace_back(row.callsite_id);
+ utids_.emplace_back(row.utid);
+ }
+
+ const std::deque<int64_t>& timestamps() const { return timestamps_; }
+ const std::deque<int64_t>& callsite_ids() const { return callsite_ids_; }
+ const std::deque<UniqueTid>& utids() const { return utids_; }
+
+ private:
+ std::deque<int64_t> timestamps_;
+ std::deque<int64_t> callsite_ids_;
+ std::deque<UniqueTid> utids_;
+ };
+
void ResetStorage();
UniqueTid AddEmptyThread(uint32_t tid) {
@@ -1324,6 +1350,12 @@
HeapProfileAllocations* mutable_heap_profile_allocations() {
return &heap_profile_allocations_;
}
+ const CpuProfileStackSamples& cpu_profile_stack_samples() const {
+ return cpu_profile_stack_samples_;
+ }
+ CpuProfileStackSamples* mutable_cpu_profile_stack_samples() {
+ return &cpu_profile_stack_samples_;
+ }
const GpuTracks& gpu_tracks() const { return gpu_tracks_; }
GpuTracks* mutable_gpu_tracks() { return &gpu_tracks_; }
@@ -1430,6 +1462,7 @@
StackProfileFrames stack_profile_frames_;
StackProfileCallsites stack_profile_callsites_;
HeapProfileAllocations heap_profile_allocations_;
+ CpuProfileStackSamples cpu_profile_stack_samples_;
};
} // namespace trace_processor