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