• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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 #ifndef SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_PROFILE_PACKET_UTILS_H_
18 #define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_PROFILE_PACKET_UTILS_H_
19 
20 #include "perfetto/ext/base/optional.h"
21 #include "perfetto/ext/base/string_view.h"
22 #include "src/trace_processor/importers/proto/packet_sequence_state.h"
23 #include "src/trace_processor/importers/proto/stack_profile_tracker.h"
24 
25 #include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
26 #include "protos/perfetto/trace/profiling/profile_common.pbzero.h"
27 
28 namespace perfetto {
29 namespace trace_processor {
30 
31 class ProfilePacketUtils {
32  public:
MakeSourceMapping(const protos::pbzero::Mapping::Decoder & entry)33   static StackProfileTracker::SourceMapping MakeSourceMapping(
34       const protos::pbzero::Mapping::Decoder& entry) {
35     StackProfileTracker::SourceMapping src_mapping{};
36     src_mapping.build_id = entry.build_id();
37     src_mapping.exact_offset = entry.exact_offset();
38     src_mapping.start_offset = entry.start_offset();
39     src_mapping.start = entry.start();
40     src_mapping.end = entry.end();
41     src_mapping.load_bias = entry.load_bias();
42     for (auto path_string_id_it = entry.path_string_ids(); path_string_id_it;
43          ++path_string_id_it) {
44       src_mapping.name_ids.emplace_back(*path_string_id_it);
45     }
46     return src_mapping;
47   }
48 
MakeSourceFrame(const protos::pbzero::Frame::Decoder & entry)49   static StackProfileTracker::SourceFrame MakeSourceFrame(
50       const protos::pbzero::Frame::Decoder& entry) {
51     StackProfileTracker::SourceFrame src_frame;
52     src_frame.name_id = entry.function_name_id();
53     src_frame.mapping_id = entry.mapping_id();
54     src_frame.rel_pc = entry.rel_pc();
55     return src_frame;
56   }
57 
MakeSourceCallstack(const protos::pbzero::Callstack::Decoder & entry)58   static StackProfileTracker::SourceCallstack MakeSourceCallstack(
59       const protos::pbzero::Callstack::Decoder& entry) {
60     StackProfileTracker::SourceCallstack src_callstack;
61     for (auto frame_it = entry.frame_ids(); frame_it; ++frame_it)
62       src_callstack.emplace_back(*frame_it);
63     return src_callstack;
64   }
65 };
66 
67 class ProfilePacketInternLookup : public StackProfileTracker::InternLookup {
68  public:
ProfilePacketInternLookup(PacketSequenceStateGeneration * seq_state)69   explicit ProfilePacketInternLookup(PacketSequenceStateGeneration* seq_state)
70       : seq_state_(seq_state) {}
71   ~ProfilePacketInternLookup() override;
72 
GetString(StackProfileTracker::SourceStringId iid,StackProfileTracker::InternedStringType type)73   base::Optional<base::StringView> GetString(
74       StackProfileTracker::SourceStringId iid,
75       StackProfileTracker::InternedStringType type) const override {
76     protos::pbzero::InternedString::Decoder* decoder = nullptr;
77     switch (type) {
78       case StackProfileTracker::InternedStringType::kBuildId:
79         decoder = seq_state_->LookupInternedMessage<
80             protos::pbzero::InternedData::kBuildIdsFieldNumber,
81             protos::pbzero::InternedString>(iid);
82         break;
83       case StackProfileTracker::InternedStringType::kFunctionName:
84         decoder = seq_state_->LookupInternedMessage<
85             protos::pbzero::InternedData::kFunctionNamesFieldNumber,
86             protos::pbzero::InternedString>(iid);
87         break;
88       case StackProfileTracker::InternedStringType::kMappingPath:
89         decoder = seq_state_->LookupInternedMessage<
90             protos::pbzero::InternedData::kMappingPathsFieldNumber,
91             protos::pbzero::InternedString>(iid);
92         break;
93     }
94     if (!decoder)
95       return base::nullopt;
96     return base::StringView(reinterpret_cast<const char*>(decoder->str().data),
97                             decoder->str().size);
98   }
99 
GetMapping(StackProfileTracker::SourceMappingId iid)100   base::Optional<StackProfileTracker::SourceMapping> GetMapping(
101       StackProfileTracker::SourceMappingId iid) const override {
102     auto* decoder = seq_state_->LookupInternedMessage<
103         protos::pbzero::InternedData::kMappingsFieldNumber,
104         protos::pbzero::Mapping>(iid);
105     if (!decoder)
106       return base::nullopt;
107     return ProfilePacketUtils::MakeSourceMapping(*decoder);
108   }
109 
GetFrame(StackProfileTracker::SourceFrameId iid)110   base::Optional<StackProfileTracker::SourceFrame> GetFrame(
111       StackProfileTracker::SourceFrameId iid) const override {
112     auto* decoder = seq_state_->LookupInternedMessage<
113         protos::pbzero::InternedData::kFramesFieldNumber,
114         protos::pbzero::Frame>(iid);
115     if (!decoder)
116       return base::nullopt;
117     return ProfilePacketUtils::MakeSourceFrame(*decoder);
118   }
119 
GetCallstack(StackProfileTracker::SourceCallstackId iid)120   base::Optional<StackProfileTracker::SourceCallstack> GetCallstack(
121       StackProfileTracker::SourceCallstackId iid) const override {
122     auto* decoder = seq_state_->LookupInternedMessage<
123         protos::pbzero::InternedData::kCallstacksFieldNumber,
124         protos::pbzero::Callstack>(iid);
125     if (!decoder)
126       return base::nullopt;
127     return ProfilePacketUtils::MakeSourceCallstack(*decoder);
128   }
129 
130  private:
131   PacketSequenceStateGeneration* seq_state_;
132 };
133 
134 }  // namespace trace_processor
135 }  // namespace perfetto
136 
137 #endif  // SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_PROFILE_PACKET_UTILS_H_
138