Merge "Move protolog_viewer_config parsing to TokenizePacket" into main
diff --git a/src/trace_processor/importers/common/mapping_tracker.cc b/src/trace_processor/importers/common/mapping_tracker.cc
index 02976f9..6e6fbf3 100644
--- a/src/trace_processor/importers/common/mapping_tracker.cc
+++ b/src/trace_processor/importers/common/mapping_tracker.cc
@@ -25,6 +25,7 @@
#include "perfetto/ext/base/string_view.h"
#include "src/trace_processor/importers/common/address_range.h"
#include "src/trace_processor/importers/common/jit_cache.h"
+#include "src/trace_processor/importers/common/virtual_memory_mapping.h"
#include "src/trace_processor/storage/trace_storage.h"
#include "src/trace_processor/types/trace_processor_context.h"
#include "src/trace_processor/util/build_id.h"
@@ -161,14 +162,15 @@
});
}
-VirtualMemoryMapping* MappingTracker::GetDummyMapping() {
- if (!dummy_mapping_) {
- CreateMappingParams params;
- params.memory_range =
- AddressRange::FromStartAndSize(0, std::numeric_limits<uint64_t>::max());
- dummy_mapping_ = &InternMemoryMapping(params);
- }
- return dummy_mapping_;
+DummyMemoryMapping& MappingTracker::CreateDummyMapping(std::string name) {
+ CreateMappingParams params;
+ params.name = std::move(name);
+ params.memory_range =
+ AddressRange::FromStartAndSize(0, std::numeric_limits<uint64_t>::max());
+ std::unique_ptr<DummyMemoryMapping> mapping(
+ new DummyMemoryMapping(context_, std::move(params)));
+
+ return AddMapping(std::move(mapping));
}
} // namespace trace_processor
diff --git a/src/trace_processor/importers/common/mapping_tracker.h b/src/trace_processor/importers/common/mapping_tracker.h
index 4791dba..c655d57 100644
--- a/src/trace_processor/importers/common/mapping_tracker.h
+++ b/src/trace_processor/importers/common/mapping_tracker.h
@@ -68,6 +68,10 @@
UserMemoryMapping& CreateUserMemoryMapping(UniquePid upid,
CreateMappingParams params);
+ // Sometimes we just need a mapping and we are lacking trace data to create a
+ // proper one. Use this mapping in those cases.
+ DummyMemoryMapping& CreateDummyMapping(std::string name);
+
// Create an "other" mapping. Returned reference will be valid for the
// duration of this instance.
VirtualMemoryMapping& InternMemoryMapping(CreateMappingParams params);
@@ -91,10 +95,6 @@
// Jitted ranges will only be applied to UserMemoryMappings
void AddJitRange(UniquePid upid, AddressRange range, JitCache* jit_cache);
- // Sometimes we just need a mapping and we are lacking trace data to create a
- // proper one. Use this mapping in those cases.
- VirtualMemoryMapping* GetDummyMapping();
-
private:
template <typename MappingImpl>
MappingImpl& AddMapping(std::unique_ptr<MappingImpl> mapping);
@@ -140,8 +140,6 @@
KernelMemoryMapping* kernel_ = nullptr;
base::FlatHashMap<UniquePid, AddressRangeMap<JitCache*>> jit_caches_;
-
- VirtualMemoryMapping* dummy_mapping_ = nullptr;
};
} // namespace trace_processor
diff --git a/src/trace_processor/importers/common/virtual_memory_mapping.cc b/src/trace_processor/importers/common/virtual_memory_mapping.cc
index 0485243..99aa23b 100644
--- a/src/trace_processor/importers/common/virtual_memory_mapping.cc
+++ b/src/trace_processor/importers/common/virtual_memory_mapping.cc
@@ -23,6 +23,7 @@
#include <string>
#include <utility>
+#include "perfetto/base/logging.h"
#include "perfetto/ext/base/string_view.h"
#include "src/trace_processor/importers/common/address_range.h"
#include "src/trace_processor/importers/common/jit_cache.h"
@@ -119,5 +120,39 @@
return {frame_id, true};
}
+DummyMemoryMapping::~DummyMemoryMapping() = default;
+
+DummyMemoryMapping::DummyMemoryMapping(TraceProcessorContext* context,
+ CreateMappingParams params)
+ : VirtualMemoryMapping(context, std::move(params)) {}
+
+FrameId DummyMemoryMapping::InternDummyFrame(base::StringView function_name,
+ base::StringView source_file) {
+ DummyFrameKey key{context()->storage->InternString(function_name),
+ context()->storage->InternString(source_file)};
+
+ if (FrameId* id = interned_dummy_frames_.Find(key); id) {
+ return *id;
+ }
+
+ uint32_t symbol_set_id = context()->storage->symbol_table().row_count();
+
+ tables::SymbolTable::Id symbol_id =
+ context()
+ ->storage->mutable_symbol_table()
+ ->Insert({symbol_set_id, key.function_name_id, key.source_file_id})
+ .id;
+
+ PERFETTO_CHECK(symbol_set_id == symbol_id.value);
+
+ const FrameId frame_id = context()
+ ->storage->mutable_stack_profile_frame_table()
+ ->Insert({key.function_name_id, mapping_id(), 0})
+ .id;
+ interned_dummy_frames_.Insert(key, frame_id);
+
+ return frame_id;
+}
+
} // namespace trace_processor
} // namespace perfetto
diff --git a/src/trace_processor/importers/common/virtual_memory_mapping.h b/src/trace_processor/importers/common/virtual_memory_mapping.h
index 498a9ef..1676437 100644
--- a/src/trace_processor/importers/common/virtual_memory_mapping.h
+++ b/src/trace_processor/importers/common/virtual_memory_mapping.h
@@ -86,6 +86,8 @@
VirtualMemoryMapping(TraceProcessorContext* context,
CreateMappingParams params);
+ TraceProcessorContext* context() const { return context_; }
+
private:
friend class MappingTracker;
@@ -149,6 +151,42 @@
const UniquePid upid_;
};
+// Dummy mapping to be able to create frames when we have no real pc addresses
+// or real mappings.
+class DummyMemoryMapping : public VirtualMemoryMapping {
+ public:
+ ~DummyMemoryMapping() override;
+
+ // Interns a frame based solely on function name and source file. This is
+ // useful for profilers that do not emit an address nor a mapping.
+ FrameId InternDummyFrame(base::StringView function_name,
+ base::StringView source_file);
+
+ private:
+ friend class MappingTracker;
+ DummyMemoryMapping(TraceProcessorContext* context,
+ CreateMappingParams params);
+
+ struct DummyFrameKey {
+ StringId function_name_id;
+ StringId source_file_id;
+
+ bool operator==(const DummyFrameKey& o) const {
+ return function_name_id == o.function_name_id &&
+ source_file_id == o.source_file_id;
+ }
+
+ struct Hasher {
+ size_t operator()(const DummyFrameKey& k) const {
+ return static_cast<size_t>(base::Hasher::Combine(
+ k.function_name_id.raw_id(), k.source_file_id.raw_id()));
+ }
+ };
+ };
+ base::FlatHashMap<DummyFrameKey, FrameId, DummyFrameKey::Hasher>
+ interned_dummy_frames_;
+};
+
} // namespace trace_processor
} // namespace perfetto
diff --git a/src/trace_processor/importers/perf/record_parser.cc b/src/trace_processor/importers/perf/record_parser.cc
index a63a5bd..0b0d169 100644
--- a/src/trace_processor/importers/perf/record_parser.cc
+++ b/src/trace_processor/importers/perf/record_parser.cc
@@ -225,7 +225,7 @@
context_->storage->IncrementStats(stats::perf_dummy_mapping_used);
// Simpleperf will not create mappings for anonymous executable mappings
// which are used by JITted code (e.g. V8 JavaScript).
- mapping = mapping_tracker_->GetDummyMapping();
+ mapping = GetDummyMapping(upid);
}
const FrameId frame_id =
@@ -346,4 +346,14 @@
return base::OkStatus();
}
+DummyMemoryMapping* RecordParser::GetDummyMapping(UniquePid upid) {
+ if (auto it = dummy_mappings_.Find(upid); it) {
+ return *it;
+ }
+
+ DummyMemoryMapping* mapping = &mapping_tracker_->CreateDummyMapping("");
+ dummy_mappings_.Insert(upid, mapping);
+ return mapping;
+}
+
} // namespace perfetto::trace_processor::perf_importer
diff --git a/src/trace_processor/importers/perf/record_parser.h b/src/trace_processor/importers/perf/record_parser.h
index 76926d1..6230845 100644
--- a/src/trace_processor/importers/perf/record_parser.h
+++ b/src/trace_processor/importers/perf/record_parser.h
@@ -22,6 +22,7 @@
#include <optional>
#include "perfetto/base/status.h"
+#include "perfetto/ext/base/flat_hash_map.h"
#include "src/trace_processor/importers/common/trace_parser.h"
#include "src/trace_processor/importers/perf/mmap_record.h"
#include "src/trace_processor/importers/perf/record.h"
@@ -31,6 +32,7 @@
namespace perfetto {
namespace trace_processor {
+class DummyMemoryMapping;
class MappingTracker;
class TraceProcessorContext;
@@ -66,8 +68,11 @@
UniquePid GetUpid(const CommonMmapRecordFields& fields) const;
- TraceProcessorContext* const context_ = nullptr;
+ DummyMemoryMapping* GetDummyMapping(UniquePid upid);
+
+ TraceProcessorContext* const context_;
MappingTracker* const mapping_tracker_;
+ base::FlatHashMap<UniquePid, DummyMemoryMapping*> dummy_mappings_;
};
} // namespace perf_importer