• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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