Calin Juravle | 31f2c15 | 2015-10-23 17:56:15 +0100 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2015 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 | |
Calin Juravle | 33083d6 | 2017-01-18 15:29:12 -0800 | [diff] [blame] | 17 | #ifndef ART_RUNTIME_JIT_PROFILE_COMPILATION_INFO_H_ |
| 18 | #define ART_RUNTIME_JIT_PROFILE_COMPILATION_INFO_H_ |
Calin Juravle | 31f2c15 | 2015-10-23 17:56:15 +0100 | [diff] [blame] | 19 | |
| 20 | #include <set> |
Calin Juravle | 4d77b6a | 2015-12-01 18:38:09 +0000 | [diff] [blame] | 21 | #include <vector> |
Calin Juravle | 31f2c15 | 2015-10-23 17:56:15 +0100 | [diff] [blame] | 22 | |
| 23 | #include "atomic.h" |
Mathieu Chartier | c5dd319 | 2015-12-09 16:38:30 -0800 | [diff] [blame] | 24 | #include "dex_cache_resolved_classes.h" |
Calin Juravle | 31f2c15 | 2015-10-23 17:56:15 +0100 | [diff] [blame] | 25 | #include "dex_file.h" |
Andreas Gampe | a5b09a6 | 2016-11-17 15:21:22 -0800 | [diff] [blame] | 26 | #include "dex_file_types.h" |
Calin Juravle | 226501b | 2015-12-11 14:41:31 +0000 | [diff] [blame] | 27 | #include "method_reference.h" |
Calin Juravle | 31f2c15 | 2015-10-23 17:56:15 +0100 | [diff] [blame] | 28 | #include "safe_map.h" |
| 29 | |
| 30 | namespace art { |
| 31 | |
Calin Juravle | 31f2c15 | 2015-10-23 17:56:15 +0100 | [diff] [blame] | 32 | /** |
Calin Juravle | 998c216 | 2015-12-21 15:39:33 +0200 | [diff] [blame] | 33 | * Profile information in a format suitable to be queried by the compiler and |
| 34 | * performing profile guided compilation. |
| 35 | * It is a serialize-friendly format based on information collected by the |
| 36 | * interpreter (ProfileInfo). |
Calin Juravle | 31f2c15 | 2015-10-23 17:56:15 +0100 | [diff] [blame] | 37 | * Currently it stores only the hot compiled methods. |
| 38 | */ |
Calin Juravle | 226501b | 2015-12-11 14:41:31 +0000 | [diff] [blame] | 39 | class ProfileCompilationInfo { |
| 40 | public: |
Calin Juravle | 6414295 | 2016-03-21 14:37:55 +0000 | [diff] [blame] | 41 | static const uint8_t kProfileMagic[]; |
| 42 | static const uint8_t kProfileVersion[]; |
| 43 | |
Calin Juravle | 6726546 | 2016-03-18 16:23:40 +0000 | [diff] [blame] | 44 | // Add the given methods and classes to the current profile object. |
Calin Juravle | 9962962 | 2016-04-19 16:33:46 +0100 | [diff] [blame] | 45 | bool AddMethodsAndClasses(const std::vector<MethodReference>& methods, |
Calin Juravle | 6726546 | 2016-03-18 16:23:40 +0000 | [diff] [blame] | 46 | const std::set<DexCacheResolvedClasses>& resolved_classes); |
Calin Juravle | 877fd96 | 2016-01-05 14:29:29 +0000 | [diff] [blame] | 47 | // Loads profile information from the given file descriptor. |
Calin Juravle | 2e2db78 | 2016-02-23 12:00:03 +0000 | [diff] [blame] | 48 | bool Load(int fd); |
Calin Juravle | 6726546 | 2016-03-18 16:23:40 +0000 | [diff] [blame] | 49 | // Merge the data from another ProfileCompilationInfo into the current object. |
| 50 | bool MergeWith(const ProfileCompilationInfo& info); |
Calin Juravle | 877fd96 | 2016-01-05 14:29:29 +0000 | [diff] [blame] | 51 | // Saves the profile data to the given file descriptor. |
Calin Juravle | 2e2db78 | 2016-02-23 12:00:03 +0000 | [diff] [blame] | 52 | bool Save(int fd); |
Calin Juravle | 6726546 | 2016-03-18 16:23:40 +0000 | [diff] [blame] | 53 | // Loads and merges profile information from the given file into the current |
| 54 | // object and tries to save it back to disk. |
Calin Juravle | 5d1bd0a | 2016-03-24 20:33:22 +0000 | [diff] [blame] | 55 | // If `force` is true then the save will go through even if the given file |
| 56 | // has bad data or its version does not match. In this cases the profile content |
| 57 | // is ignored. |
| 58 | bool MergeAndSave(const std::string& filename, uint64_t* bytes_written, bool force); |
Calin Juravle | 6726546 | 2016-03-18 16:23:40 +0000 | [diff] [blame] | 59 | |
Calin Juravle | 998c216 | 2015-12-21 15:39:33 +0200 | [diff] [blame] | 60 | // Returns the number of methods that were profiled. |
| 61 | uint32_t GetNumberOfMethods() const; |
Calin Juravle | 6726546 | 2016-03-18 16:23:40 +0000 | [diff] [blame] | 62 | // Returns the number of resolved classes that were profiled. |
| 63 | uint32_t GetNumberOfResolvedClasses() const; |
Calin Juravle | 226501b | 2015-12-11 14:41:31 +0000 | [diff] [blame] | 64 | |
| 65 | // Returns true if the method reference is present in the profiling info. |
| 66 | bool ContainsMethod(const MethodReference& method_ref) const; |
| 67 | |
Jeff Hao | 54b5855 | 2016-11-16 15:15:04 -0800 | [diff] [blame] | 68 | // Returns true if the class's type is present in the profiling info. |
Andreas Gampe | a5b09a6 | 2016-11-17 15:21:22 -0800 | [diff] [blame] | 69 | bool ContainsClass(const DexFile& dex_file, dex::TypeIndex type_idx) const; |
Mathieu Chartier | a807780 | 2016-03-16 19:08:31 -0700 | [diff] [blame] | 70 | |
Calin Juravle | 226501b | 2015-12-11 14:41:31 +0000 | [diff] [blame] | 71 | // Dumps all the loaded profile info into a string and returns it. |
Calin Juravle | 998c216 | 2015-12-21 15:39:33 +0200 | [diff] [blame] | 72 | // If dex_files is not null then the method indices will be resolved to their |
| 73 | // names. |
Calin Juravle | 226501b | 2015-12-11 14:41:31 +0000 | [diff] [blame] | 74 | // This is intended for testing and debugging. |
Calin Juravle | 998c216 | 2015-12-21 15:39:33 +0200 | [diff] [blame] | 75 | std::string DumpInfo(const std::vector<const DexFile*>* dex_files, |
| 76 | bool print_full_dex_location = true) const; |
Calin Juravle | 226501b | 2015-12-11 14:41:31 +0000 | [diff] [blame] | 77 | |
Calin Juravle | 2e2db78 | 2016-02-23 12:00:03 +0000 | [diff] [blame] | 78 | bool Equals(const ProfileCompilationInfo& other); |
Calin Juravle | 6726546 | 2016-03-18 16:23:40 +0000 | [diff] [blame] | 79 | |
Calin Juravle | 31708b7 | 2016-02-05 19:44:05 +0000 | [diff] [blame] | 80 | static std::string GetProfileDexFileKey(const std::string& dex_location); |
Calin Juravle | 877fd96 | 2016-01-05 14:29:29 +0000 | [diff] [blame] | 81 | |
Mathieu Chartier | c5dd319 | 2015-12-09 16:38:30 -0800 | [diff] [blame] | 82 | // Returns the class descriptors for all of the classes in the profiles' class sets. |
| 83 | // Note the dex location is actually the profile key, the caller needs to call back in to the |
| 84 | // profile info stuff to generate a map back to the dex location. |
| 85 | std::set<DexCacheResolvedClasses> GetResolvedClasses() const; |
Calin Juravle | 226501b | 2015-12-11 14:41:31 +0000 | [diff] [blame] | 86 | |
Calin Juravle | 6726546 | 2016-03-18 16:23:40 +0000 | [diff] [blame] | 87 | // Clears the resolved classes from the current object. |
| 88 | void ClearResolvedClasses(); |
| 89 | |
Calin Juravle | 7bcdb53 | 2016-06-07 16:14:47 +0100 | [diff] [blame] | 90 | static bool GenerateTestProfile(int fd, |
| 91 | uint16_t number_of_dex_files, |
| 92 | uint16_t method_ratio, |
| 93 | uint16_t class_ratio); |
| 94 | |
Mathieu Chartier | c5dd319 | 2015-12-09 16:38:30 -0800 | [diff] [blame] | 95 | private: |
Calin Juravle | 6414295 | 2016-03-21 14:37:55 +0000 | [diff] [blame] | 96 | enum ProfileLoadSatus { |
| 97 | kProfileLoadIOError, |
| 98 | kProfileLoadVersionMismatch, |
| 99 | kProfileLoadBadData, |
| 100 | kProfileLoadSuccess |
| 101 | }; |
| 102 | |
Calin Juravle | 998c216 | 2015-12-21 15:39:33 +0200 | [diff] [blame] | 103 | struct DexFileData { |
| 104 | explicit DexFileData(uint32_t location_checksum) : checksum(location_checksum) {} |
| 105 | uint32_t checksum; |
| 106 | std::set<uint16_t> method_set; |
Andreas Gampe | a5b09a6 | 2016-11-17 15:21:22 -0800 | [diff] [blame] | 107 | std::set<dex::TypeIndex> class_set; |
Calin Juravle | 877fd96 | 2016-01-05 14:29:29 +0000 | [diff] [blame] | 108 | |
| 109 | bool operator==(const DexFileData& other) const { |
| 110 | return checksum == other.checksum && method_set == other.method_set; |
| 111 | } |
Calin Juravle | 998c216 | 2015-12-21 15:39:33 +0200 | [diff] [blame] | 112 | }; |
Calin Juravle | 226501b | 2015-12-11 14:41:31 +0000 | [diff] [blame] | 113 | |
Calin Juravle | 998c216 | 2015-12-21 15:39:33 +0200 | [diff] [blame] | 114 | using DexFileToProfileInfoMap = SafeMap<const std::string, DexFileData>; |
| 115 | |
Mathieu Chartier | c5dd319 | 2015-12-09 16:38:30 -0800 | [diff] [blame] | 116 | DexFileData* GetOrAddDexFileData(const std::string& dex_location, uint32_t checksum); |
| 117 | bool AddMethodIndex(const std::string& dex_location, uint32_t checksum, uint16_t method_idx); |
Andreas Gampe | a5b09a6 | 2016-11-17 15:21:22 -0800 | [diff] [blame] | 118 | bool AddClassIndex(const std::string& dex_location, uint32_t checksum, dex::TypeIndex type_idx); |
Calin Juravle | 9962962 | 2016-04-19 16:33:46 +0100 | [diff] [blame] | 119 | bool AddResolvedClasses(const DexCacheResolvedClasses& classes); |
Calin Juravle | 6414295 | 2016-03-21 14:37:55 +0000 | [diff] [blame] | 120 | |
| 121 | // Parsing functionality. |
| 122 | |
| 123 | struct ProfileLineHeader { |
| 124 | std::string dex_location; |
| 125 | uint16_t method_set_size; |
| 126 | uint16_t class_set_size; |
| 127 | uint32_t checksum; |
| 128 | }; |
| 129 | |
| 130 | // A helper structure to make sure we don't read past our buffers in the loops. |
| 131 | struct SafeBuffer { |
| 132 | public: |
| 133 | explicit SafeBuffer(size_t size) : storage_(new uint8_t[size]) { |
| 134 | ptr_current_ = storage_.get(); |
| 135 | ptr_end_ = ptr_current_ + size; |
| 136 | } |
| 137 | |
| 138 | // Reads the content of the descriptor at the current position. |
| 139 | ProfileLoadSatus FillFromFd(int fd, |
| 140 | const std::string& source, |
| 141 | /*out*/std::string* error); |
| 142 | |
| 143 | // Reads an uint value (high bits to low bits) and advances the current pointer |
| 144 | // with the number of bits read. |
| 145 | template <typename T> T ReadUintAndAdvance(); |
| 146 | |
| 147 | // Compares the given data with the content current pointer. If the contents are |
| 148 | // equal it advances the current pointer by data_size. |
| 149 | bool CompareAndAdvance(const uint8_t* data, size_t data_size); |
| 150 | |
| 151 | // Get the underlying raw buffer. |
| 152 | uint8_t* Get() { return storage_.get(); } |
| 153 | |
| 154 | private: |
Andreas Gampe | 7b8a265 | 2016-11-11 17:11:25 -0800 | [diff] [blame] | 155 | std::unique_ptr<uint8_t[]> storage_; |
Calin Juravle | 6414295 | 2016-03-21 14:37:55 +0000 | [diff] [blame] | 156 | uint8_t* ptr_current_; |
| 157 | uint8_t* ptr_end_; |
| 158 | }; |
| 159 | |
| 160 | ProfileLoadSatus LoadInternal(int fd, std::string* error); |
| 161 | |
| 162 | ProfileLoadSatus ReadProfileHeader(int fd, |
| 163 | /*out*/uint16_t* number_of_lines, |
| 164 | /*out*/std::string* error); |
| 165 | |
| 166 | ProfileLoadSatus ReadProfileLineHeader(int fd, |
| 167 | /*out*/ProfileLineHeader* line_header, |
| 168 | /*out*/std::string* error); |
| 169 | ProfileLoadSatus ReadProfileLine(int fd, |
| 170 | const ProfileLineHeader& line_header, |
| 171 | /*out*/std::string* error); |
| 172 | |
| 173 | bool ProcessLine(SafeBuffer& line_buffer, |
| 174 | uint16_t method_set_size, |
| 175 | uint16_t class_set_size, |
| 176 | uint32_t checksum, |
| 177 | const std::string& dex_location); |
Mathieu Chartier | c5dd319 | 2015-12-09 16:38:30 -0800 | [diff] [blame] | 178 | |
Calin Juravle | 877fd96 | 2016-01-05 14:29:29 +0000 | [diff] [blame] | 179 | friend class ProfileCompilationInfoTest; |
| 180 | friend class CompilerDriverProfileTest; |
| 181 | friend class ProfileAssistantTest; |
Jeff Hao | 41fba6a | 2016-11-28 11:53:33 -0800 | [diff] [blame] | 182 | friend class Dex2oatLayoutTest; |
Calin Juravle | 877fd96 | 2016-01-05 14:29:29 +0000 | [diff] [blame] | 183 | |
Calin Juravle | 226501b | 2015-12-11 14:41:31 +0000 | [diff] [blame] | 184 | DexFileToProfileInfoMap info_; |
| 185 | }; |
| 186 | |
Calin Juravle | 31f2c15 | 2015-10-23 17:56:15 +0100 | [diff] [blame] | 187 | } // namespace art |
| 188 | |
Calin Juravle | 33083d6 | 2017-01-18 15:29:12 -0800 | [diff] [blame] | 189 | #endif // ART_RUNTIME_JIT_PROFILE_COMPILATION_INFO_H_ |