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 #ifndef SRC_TRACE_PROCESSOR_IMPORTERS_ART_METHOD_ART_METHOD_TOKENIZER_H_ 18 #define SRC_TRACE_PROCESSOR_IMPORTERS_ART_METHOD_ART_METHOD_TOKENIZER_H_ 19 20 #include <cstddef> 21 #include <cstdint> 22 #include <limits> 23 #include <optional> 24 #include <string> 25 #include <string_view> 26 #include <variant> 27 28 #include "perfetto/base/status.h" 29 #include "perfetto/ext/base/flat_hash_map.h" 30 #include "perfetto/ext/base/status_or.h" 31 #include "perfetto/trace_processor/trace_blob_view.h" 32 #include "src/trace_processor/importers/common/chunked_trace_reader.h" 33 #include "src/trace_processor/importers/common/trace_parser.h" 34 #include "src/trace_processor/storage/trace_storage.h" 35 #include "src/trace_processor/types/trace_processor_context.h" 36 #include "src/trace_processor/util/trace_blob_view_reader.h" 37 38 namespace perfetto::trace_processor::art_method { 39 40 class ArtMethodTokenizer : public ChunkedTraceReader { 41 public: 42 explicit ArtMethodTokenizer(TraceProcessorContext*); 43 ~ArtMethodTokenizer() override; 44 45 base::Status Parse(TraceBlobView) override; 46 base::Status NotifyEndOfFile() override; 47 48 private: 49 using Iterator = util::TraceBlobViewReader::Iterator; 50 struct Method { 51 StringId name; 52 std::optional<StringId> pathname; 53 std::optional<uint32_t> line_number; 54 }; 55 struct Thread { 56 StringId comm; 57 bool comm_used; 58 }; 59 struct Detect {}; 60 struct NonStreaming { 61 base::Status Parse(); 62 base::Status NotifyEndOfFile() const; 63 64 base::StatusOr<bool> ParseHeaderStart(Iterator&); 65 base::StatusOr<bool> ParseHeaderVersion(Iterator&); 66 base::StatusOr<bool> ParseHeaderOptions(Iterator&); 67 base::StatusOr<bool> ParseHeaderThreads(Iterator&); 68 base::StatusOr<bool> ParseHeaderMethods(Iterator&); 69 base::StatusOr<bool> ParseDataHeader(Iterator&); 70 71 base::Status ParseHeaderSectionLine(std::string_view); 72 73 ArtMethodTokenizer* tokenizer_; 74 enum { 75 kHeaderStart, 76 kHeaderVersion, 77 kHeaderOptions, 78 kHeaderThreads, 79 kHeaderMethods, 80 kDataHeader, 81 kData, 82 } mode_ = kHeaderStart; 83 }; 84 struct Streaming { 85 base::Status Parse(); 86 base::Status NotifyEndOfFile(); 87 88 base::StatusOr<bool> ParseHeaderStart(Iterator&); 89 base::StatusOr<bool> ParseData(Iterator&); 90 base::Status ParseSummary(std::string_view) const; 91 92 ArtMethodTokenizer* tokenizer_; 93 enum { 94 kHeaderStart, 95 kData, 96 kSummaryDone, 97 kDone, 98 } mode_ = kHeaderStart; 99 size_t it_offset_ = 0; 100 }; 101 using SubParser = std::variant<Detect, NonStreaming, Streaming>; 102 103 [[nodiscard]] base::Status ParseMethodLine(std::string_view); 104 [[nodiscard]] base::Status ParseOptionLine(std::string_view); 105 [[nodiscard]] base::Status ParseThread(uint32_t tid, const std::string&); 106 [[nodiscard]] base::Status ParseRecord(uint32_t tid, const TraceBlobView&); 107 108 TraceProcessorContext* const context_; 109 util::TraceBlobViewReader reader_; 110 111 SubParser sub_parser_; 112 enum { 113 kWall, 114 kDual, 115 } clock_ = kWall; 116 117 uint32_t version_ = std::numeric_limits<uint32_t>::max(); 118 int64_t ts_ = std::numeric_limits<int64_t>::max(); 119 uint32_t record_size_ = std::numeric_limits<uint32_t>::max(); 120 base::FlatHashMap<uint32_t, Method> method_map_; 121 base::FlatHashMap<uint32_t, Thread> thread_map_; 122 }; 123 124 } // namespace perfetto::trace_processor::art_method 125 126 #endif // SRC_TRACE_PROCESSOR_IMPORTERS_ART_METHOD_ART_METHOD_TOKENIZER_H_ 127