1 /* 2 * Copyright (C) 2016 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 ART_PROFMAN_PROFILE_ASSISTANT_H_ 18 #define ART_PROFMAN_PROFILE_ASSISTANT_H_ 19 20 #include <string> 21 #include <vector> 22 23 #include "base/scoped_flock.h" 24 #include "profile/profile_compilation_info.h" 25 26 namespace art { 27 28 class ProfileAssistant { 29 public: 30 // These also serve as return codes of profman and are processed by installd 31 // (frameworks/native/cmds/installd/commands.cpp) 32 enum ProcessingResult { 33 kSuccess = 0, // Generic success code for non-analysis runs. 34 kCompile = 1, 35 kSkipCompilationSmallDelta = 2, 36 kErrorBadProfiles = 3, 37 kErrorIO = 4, 38 kErrorCannotLock = 5, 39 kErrorDifferentVersions = 6, 40 kSkipCompilationEmptyProfiles = 7, 41 }; 42 43 class Options { 44 public: 45 static constexpr bool kForceMergeDefault = false; 46 static constexpr bool kBootImageMergeDefault = false; 47 static constexpr uint32_t kMinNewMethodsPercentChangeForCompilation = 20; 48 static constexpr uint32_t kMinNewClassesPercentChangeForCompilation = 20; 49 Options()50 Options() 51 : force_merge_(kForceMergeDefault), 52 boot_image_merge_(kBootImageMergeDefault), 53 min_new_methods_percent_change_for_compilation_( 54 kMinNewMethodsPercentChangeForCompilation), 55 min_new_classes_percent_change_for_compilation_( 56 kMinNewClassesPercentChangeForCompilation) { 57 } 58 IsForceMerge()59 bool IsForceMerge() const { return force_merge_; } IsBootImageMerge()60 bool IsBootImageMerge() const { return boot_image_merge_; } GetMinNewMethodsPercentChangeForCompilation()61 uint32_t GetMinNewMethodsPercentChangeForCompilation() const { 62 return min_new_methods_percent_change_for_compilation_; 63 } GetMinNewClassesPercentChangeForCompilation()64 uint32_t GetMinNewClassesPercentChangeForCompilation() const { 65 return min_new_classes_percent_change_for_compilation_; 66 } 67 SetForceMerge(bool value)68 void SetForceMerge(bool value) { force_merge_ = value; } SetBootImageMerge(bool value)69 void SetBootImageMerge(bool value) { boot_image_merge_ = value; } SetMinNewMethodsPercentChangeForCompilation(uint32_t value)70 void SetMinNewMethodsPercentChangeForCompilation(uint32_t value) { 71 min_new_methods_percent_change_for_compilation_ = value; 72 } SetMinNewClassesPercentChangeForCompilation(uint32_t value)73 void SetMinNewClassesPercentChangeForCompilation(uint32_t value) { 74 min_new_classes_percent_change_for_compilation_ = value; 75 } 76 77 private: 78 // If true, performs a forced merge, without analyzing if there is a 79 // significant difference between the current profile and the reference profile. 80 // See ProfileAssistant#ProcessProfile. 81 bool force_merge_; 82 // Signals that the merge is for boot image profiles. It will ignore differences 83 // in profile versions (instead of aborting). 84 bool boot_image_merge_; 85 uint32_t min_new_methods_percent_change_for_compilation_; 86 uint32_t min_new_classes_percent_change_for_compilation_; 87 }; 88 89 // Process the profile information present in the given files. Returns one of 90 // ProcessingResult values depending on profile information and whether or not 91 // the analysis ended up successfully (i.e. no errors during reading, 92 // merging or writing of profile files). 93 // 94 // When the returned value is kCompile there is a significant difference 95 // between profile_files and reference_profile_files. In this case 96 // reference_profile will be updated with the profiling info obtain after 97 // merging all profiles. 98 // 99 // When the returned value is kSkipCompilationSmallDelta, the difference between 100 // the merge of the current profiles and the reference one is insignificant. In 101 // this case no file will be updated. A variation of this code is 102 // kSkipCompilationEmptyProfiles which indicates that all the profiles are empty. 103 // This allow the caller to make fine grain decisions on the compilation strategy. 104 static ProcessingResult ProcessProfiles( 105 const std::vector<std::string>& profile_files, 106 const std::string& reference_profile_file, 107 const ProfileCompilationInfo::ProfileLoadFilterFn& filter_fn 108 = ProfileCompilationInfo::ProfileFilterFnAcceptAll, 109 const Options& options = Options()); 110 111 static ProcessingResult ProcessProfiles( 112 const std::vector<int>& profile_files_fd_, 113 int reference_profile_file_fd, 114 const ProfileCompilationInfo::ProfileLoadFilterFn& filter_fn 115 = ProfileCompilationInfo::ProfileFilterFnAcceptAll, 116 const Options& options = Options()); 117 118 private: 119 static ProcessingResult ProcessProfilesInternal( 120 const std::vector<ScopedFlock>& profile_files, 121 const ScopedFlock& reference_profile_file, 122 const ProfileCompilationInfo::ProfileLoadFilterFn& filter_fn, 123 const Options& options); 124 125 DISALLOW_COPY_AND_ASSIGN(ProfileAssistant); 126 }; 127 128 } // namespace art 129 130 #endif // ART_PROFMAN_PROFILE_ASSISTANT_H_ 131