1 /*
2 * Copyright (C) 2024 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "src/trace_processor/importers/common/virtual_memory_mapping.h"
18
19 #include <cstddef>
20 #include <cstdint>
21 #include <memory>
22 #include <optional>
23 #include <string>
24 #include <utility>
25
26 #include "perfetto/ext/base/string_view.h"
27 #include "src/trace_processor/importers/common/address_range.h"
28 #include "src/trace_processor/importers/common/jit_cache.h"
29 #include "src/trace_processor/importers/common/stack_profile_tracker.h"
30 #include "src/trace_processor/storage/trace_storage.h"
31 #include "src/trace_processor/tables/profiler_tables_py.h"
32 #include "src/trace_processor/types/trace_processor_context.h"
33 #include "src/trace_processor/util/build_id.h"
34
35 namespace perfetto {
36 namespace trace_processor {
37 namespace {
38
CreateMapping(TraceProcessorContext * context,const CreateMappingParams & params)39 MappingId CreateMapping(TraceProcessorContext* context,
40 const CreateMappingParams& params) {
41 StringId build_id = context->storage->InternString(base::StringView(
42 params.build_id ? params.build_id->ToHex() : std::string()));
43 MappingId mapping_id =
44 context->storage->mutable_stack_profile_mapping_table()
45 ->Insert(
46 {build_id, static_cast<int64_t>(params.exact_offset),
47 static_cast<int64_t>(params.start_offset),
48 static_cast<int64_t>(params.memory_range.start()),
49 static_cast<int64_t>(params.memory_range.end()),
50 static_cast<int64_t>(params.load_bias),
51 context->storage->InternString(base::StringView(params.name))})
52 .id;
53
54 return mapping_id;
55 }
56
57 } // namespace
58
VirtualMemoryMapping(TraceProcessorContext * context,CreateMappingParams params)59 VirtualMemoryMapping::VirtualMemoryMapping(TraceProcessorContext* context,
60 CreateMappingParams params)
61 : context_(context),
62 mapping_id_(CreateMapping(context, params)),
63 memory_range_(params.memory_range),
64 offset_(params.exact_offset),
65 load_bias_(params.load_bias),
66 name_(std::move(params.name)),
67 build_id_(std::move(params.build_id)) {}
68
69 VirtualMemoryMapping::~VirtualMemoryMapping() = default;
70
KernelMemoryMapping(TraceProcessorContext * context,CreateMappingParams params)71 KernelMemoryMapping::KernelMemoryMapping(TraceProcessorContext* context,
72 CreateMappingParams params)
73 : VirtualMemoryMapping(context, std::move(params)) {}
74
75 KernelMemoryMapping::~KernelMemoryMapping() = default;
76
UserMemoryMapping(TraceProcessorContext * context,UniquePid upid,CreateMappingParams params)77 UserMemoryMapping::UserMemoryMapping(TraceProcessorContext* context,
78 UniquePid upid,
79 CreateMappingParams params)
80 : VirtualMemoryMapping(context, std::move(params)), upid_(upid) {}
81
82 UserMemoryMapping::~UserMemoryMapping() = default;
83
InternFrame(uint64_t rel_pc,base::StringView function_name)84 FrameId VirtualMemoryMapping::InternFrame(uint64_t rel_pc,
85 base::StringView function_name) {
86 auto [frame_id, was_inserted] =
87 jit_cache_ ? jit_cache_->InternFrame(this, rel_pc, function_name)
88 : InternFrameImpl(rel_pc, function_name);
89 if (was_inserted) {
90 frames_by_rel_pc_[rel_pc].push_back(frame_id);
91 context_->stack_profile_tracker->OnFrameCreated(frame_id);
92 }
93 return frame_id;
94 }
95
FindFrameIds(uint64_t rel_pc) const96 std::vector<FrameId> VirtualMemoryMapping::FindFrameIds(uint64_t rel_pc) const {
97 if (auto* res = frames_by_rel_pc_.Find(rel_pc); res != nullptr) {
98 return *res;
99 }
100 return {};
101 }
102
InternFrameImpl(uint64_t rel_pc,base::StringView function_name)103 std::pair<FrameId, bool> VirtualMemoryMapping::InternFrameImpl(
104 uint64_t rel_pc,
105 base::StringView function_name) {
106 const FrameKey frame_key{rel_pc,
107 context_->storage->InternString(function_name)};
108 if (FrameId* id = interned_frames_.Find(frame_key); id) {
109 return {*id, false};
110 }
111
112 const FrameId frame_id =
113 context_->storage->mutable_stack_profile_frame_table()
114 ->Insert(
115 {frame_key.name_id, mapping_id_, static_cast<int64_t>(rel_pc)})
116 .id;
117 interned_frames_.Insert(frame_key, frame_id);
118
119 return {frame_id, true};
120 }
121
122 } // namespace trace_processor
123 } // namespace perfetto
124