xref: /aosp_15_r20/external/perfetto/src/trace_processor/importers/common/stack_profile_tracker.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1 /*
2  * Copyright (C) 2019 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/stack_profile_tracker.h"
18 
19 #include <cstddef>
20 #include <cstdint>
21 
22 #include "perfetto/ext/base/string_view.h"
23 #include "src/trace_processor/storage/trace_storage.h"
24 #include "src/trace_processor/tables/profiler_tables_py.h"
25 #include "src/trace_processor/types/trace_processor_context.h"
26 #include "src/trace_processor/util/profiler_util.h"
27 
28 namespace perfetto {
29 namespace trace_processor {
30 
JavaFramesForName(NameInPackage name) const31 std::vector<FrameId> StackProfileTracker::JavaFramesForName(
32     NameInPackage name) const {
33   if (const auto* frames = java_frames_for_name_.Find(name); frames) {
34     return *frames;
35   }
36   return {};
37 }
38 
InternCallsite(std::optional<CallsiteId> parent_callsite_id,FrameId frame_id,uint32_t depth)39 CallsiteId StackProfileTracker::InternCallsite(
40     std::optional<CallsiteId> parent_callsite_id,
41     FrameId frame_id,
42     uint32_t depth) {
43   tables::StackProfileCallsiteTable::Row row{depth, parent_callsite_id,
44                                              frame_id};
45   if (CallsiteId* id = callsite_unique_row_index_.Find(row); id) {
46     return *id;
47   }
48 
49   CallsiteId callsite_id =
50       context_->storage->mutable_stack_profile_callsite_table()->Insert(row).id;
51   callsite_unique_row_index_.Insert(row, callsite_id);
52   return callsite_id;
53 }
54 
OnFrameCreated(FrameId frame_id)55 void StackProfileTracker::OnFrameCreated(FrameId frame_id) {
56   auto frame =
57       *context_->storage->stack_profile_frame_table().FindById(frame_id);
58   const MappingId mapping_id = frame.mapping();
59   const StringId name_id = frame.name();
60   const auto function_name = context_->storage->GetString(name_id);
61 
62   if (function_name.find('.') != base::StringView::npos) {
63     // Java frames always contain a '.'
64     base::StringView mapping_name = context_->storage->GetString(
65         context_->storage->stack_profile_mapping_table()
66             .FindById(mapping_id)
67             ->name());
68     std::optional<std::string> package =
69         PackageFromLocation(context_->storage.get(), mapping_name);
70     if (package) {
71       NameInPackage nip{
72           name_id, context_->storage->InternString(base::StringView(*package))};
73       java_frames_for_name_[nip].push_back(frame_id);
74     } else if (mapping_name.find("/memfd:") == 0) {
75       NameInPackage nip{name_id, context_->storage->InternString("memfd")};
76       java_frames_for_name_[nip].push_back(frame_id);
77     }
78   }
79 }
80 
81 }  // namespace trace_processor
82 }  // namespace perfetto
83