1 /* 2 * Copyright (C) 2014 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_COMPILER_DRIVER_COMPILER_OPTIONS_H_ 18 #define ART_COMPILER_DRIVER_COMPILER_OPTIONS_H_ 19 20 #include <ostream> 21 #include <string> 22 #include <vector> 23 24 #include "base/macros.h" 25 #include "compiler_filter.h" 26 #include "globals.h" 27 #include "utils.h" 28 29 namespace art { 30 31 class CompilerOptions FINAL { 32 public: 33 // Guide heuristics to determine whether to compile method if profile data not available. 34 static const CompilerFilter::Filter kDefaultCompilerFilter = CompilerFilter::kSpeed; 35 static const size_t kDefaultHugeMethodThreshold = 10000; 36 static const size_t kDefaultLargeMethodThreshold = 600; 37 static const size_t kDefaultSmallMethodThreshold = 60; 38 static const size_t kDefaultTinyMethodThreshold = 20; 39 static const size_t kDefaultNumDexMethodsThreshold = 900; 40 static constexpr double kDefaultTopKProfileThreshold = 90.0; 41 static const bool kDefaultGenerateDebugInfo = false; 42 static const bool kDefaultGenerateMiniDebugInfo = false; 43 static const bool kDefaultIncludePatchInformation = false; 44 static const size_t kDefaultInlineDepthLimit = 3; 45 static const size_t kDefaultInlineMaxCodeUnits = 32; 46 static constexpr size_t kUnsetInlineDepthLimit = -1; 47 static constexpr size_t kUnsetInlineMaxCodeUnits = -1; 48 49 // Default inlining settings when the space filter is used. 50 static constexpr size_t kSpaceFilterInlineDepthLimit = 3; 51 static constexpr size_t kSpaceFilterInlineMaxCodeUnits = 10; 52 53 CompilerOptions(); 54 ~CompilerOptions(); 55 56 CompilerOptions(CompilerFilter::Filter compiler_filter, 57 size_t huge_method_threshold, 58 size_t large_method_threshold, 59 size_t small_method_threshold, 60 size_t tiny_method_threshold, 61 size_t num_dex_methods_threshold, 62 size_t inline_depth_limit, 63 size_t inline_max_code_units, 64 const std::vector<const DexFile*>* no_inline_from, 65 bool include_patch_information, 66 double top_k_profile_threshold, 67 bool debuggable, 68 bool generate_debug_info, 69 bool implicit_null_checks, 70 bool implicit_so_checks, 71 bool implicit_suspend_checks, 72 bool compile_pic, 73 const std::vector<std::string>* verbose_methods, 74 std::ostream* init_failure_output, 75 bool abort_on_hard_verifier_failure, 76 const std::string& dump_cfg_file_name, 77 bool dump_cfg_append, 78 bool force_determinism); 79 80 CompilerFilter::Filter GetCompilerFilter() const { 81 return compiler_filter_; 82 } 83 84 void SetCompilerFilter(CompilerFilter::Filter compiler_filter) { 85 compiler_filter_ = compiler_filter; 86 } 87 88 bool VerifyAtRuntime() const { 89 return compiler_filter_ == CompilerFilter::kVerifyAtRuntime; 90 } 91 92 bool IsBytecodeCompilationEnabled() const { 93 return CompilerFilter::IsBytecodeCompilationEnabled(compiler_filter_); 94 } 95 96 bool IsJniCompilationEnabled() const { 97 return CompilerFilter::IsJniCompilationEnabled(compiler_filter_); 98 } 99 100 bool IsVerificationEnabled() const { 101 return CompilerFilter::IsVerificationEnabled(compiler_filter_); 102 } 103 104 bool NeverVerify() const { 105 return compiler_filter_ == CompilerFilter::kVerifyNone; 106 } 107 108 bool VerifyOnlyProfile() const { 109 return compiler_filter_ == CompilerFilter::kVerifyProfile; 110 } 111 112 size_t GetHugeMethodThreshold() const { 113 return huge_method_threshold_; 114 } 115 116 size_t GetLargeMethodThreshold() const { 117 return large_method_threshold_; 118 } 119 120 size_t GetSmallMethodThreshold() const { 121 return small_method_threshold_; 122 } 123 124 size_t GetTinyMethodThreshold() const { 125 return tiny_method_threshold_; 126 } 127 128 bool IsHugeMethod(size_t num_dalvik_instructions) const { 129 return num_dalvik_instructions > huge_method_threshold_; 130 } 131 132 bool IsLargeMethod(size_t num_dalvik_instructions) const { 133 return num_dalvik_instructions > large_method_threshold_; 134 } 135 136 bool IsSmallMethod(size_t num_dalvik_instructions) const { 137 return num_dalvik_instructions > small_method_threshold_; 138 } 139 140 bool IsTinyMethod(size_t num_dalvik_instructions) const { 141 return num_dalvik_instructions > tiny_method_threshold_; 142 } 143 144 size_t GetNumDexMethodsThreshold() const { 145 return num_dex_methods_threshold_; 146 } 147 148 size_t GetInlineDepthLimit() const { 149 return inline_depth_limit_; 150 } 151 void SetInlineDepthLimit(size_t limit) { 152 inline_depth_limit_ = limit; 153 } 154 155 size_t GetInlineMaxCodeUnits() const { 156 return inline_max_code_units_; 157 } 158 void SetInlineMaxCodeUnits(size_t units) { 159 inline_max_code_units_ = units; 160 } 161 162 double GetTopKProfileThreshold() const { 163 return top_k_profile_threshold_; 164 } 165 166 bool GetDebuggable() const { 167 return debuggable_; 168 } 169 170 bool GetNativeDebuggable() const { 171 return GetDebuggable() && GetGenerateDebugInfo(); 172 } 173 174 // This flag controls whether the compiler collects debugging information. 175 // The other flags control how the information is written to disk. 176 bool GenerateAnyDebugInfo() const { 177 return GetGenerateDebugInfo() || GetGenerateMiniDebugInfo(); 178 } 179 180 bool GetGenerateDebugInfo() const { 181 return generate_debug_info_; 182 } 183 184 bool GetGenerateMiniDebugInfo() const { 185 return generate_mini_debug_info_; 186 } 187 188 bool GetImplicitNullChecks() const { 189 return implicit_null_checks_; 190 } 191 192 bool GetImplicitStackOverflowChecks() const { 193 return implicit_so_checks_; 194 } 195 196 bool GetImplicitSuspendChecks() const { 197 return implicit_suspend_checks_; 198 } 199 200 bool GetIncludePatchInformation() const { 201 return include_patch_information_; 202 } 203 204 // Should the code be compiled as position independent? 205 bool GetCompilePic() const { 206 return compile_pic_; 207 } 208 209 bool HasVerboseMethods() const { 210 return verbose_methods_ != nullptr && !verbose_methods_->empty(); 211 } 212 213 bool IsVerboseMethod(const std::string& pretty_method) const { 214 for (const std::string& cur_method : *verbose_methods_) { 215 if (pretty_method.find(cur_method) != std::string::npos) { 216 return true; 217 } 218 } 219 return false; 220 } 221 222 std::ostream* GetInitFailureOutput() const { 223 return init_failure_output_.get(); 224 } 225 226 bool AbortOnHardVerifierFailure() const { 227 return abort_on_hard_verifier_failure_; 228 } 229 230 const std::vector<const DexFile*>* GetNoInlineFromDexFile() const { 231 return no_inline_from_; 232 } 233 234 bool ParseCompilerOption(const StringPiece& option, UsageFn Usage); 235 236 const std::string& GetDumpCfgFileName() const { 237 return dump_cfg_file_name_; 238 } 239 240 bool GetDumpCfgAppend() const { 241 return dump_cfg_append_; 242 } 243 244 bool IsForceDeterminism() const { 245 return force_determinism_; 246 } 247 248 private: 249 void ParseDumpInitFailures(const StringPiece& option, UsageFn Usage); 250 void ParseDumpCfgPasses(const StringPiece& option, UsageFn Usage); 251 void ParseInlineMaxCodeUnits(const StringPiece& option, UsageFn Usage); 252 void ParseInlineDepthLimit(const StringPiece& option, UsageFn Usage); 253 void ParseNumDexMethods(const StringPiece& option, UsageFn Usage); 254 void ParseTinyMethodMax(const StringPiece& option, UsageFn Usage); 255 void ParseSmallMethodMax(const StringPiece& option, UsageFn Usage); 256 void ParseLargeMethodMax(const StringPiece& option, UsageFn Usage); 257 void ParseHugeMethodMax(const StringPiece& option, UsageFn Usage); 258 259 CompilerFilter::Filter compiler_filter_; 260 size_t huge_method_threshold_; 261 size_t large_method_threshold_; 262 size_t small_method_threshold_; 263 size_t tiny_method_threshold_; 264 size_t num_dex_methods_threshold_; 265 size_t inline_depth_limit_; 266 size_t inline_max_code_units_; 267 268 // Dex files from which we should not inline code. 269 // This is usually a very short list (i.e. a single dex file), so we 270 // prefer vector<> over a lookup-oriented container, such as set<>. 271 const std::vector<const DexFile*>* no_inline_from_; 272 273 bool include_patch_information_; 274 // When using a profile file only the top K% of the profiled samples will be compiled. 275 double top_k_profile_threshold_; 276 bool debuggable_; 277 bool generate_debug_info_; 278 bool generate_mini_debug_info_; 279 bool implicit_null_checks_; 280 bool implicit_so_checks_; 281 bool implicit_suspend_checks_; 282 bool compile_pic_; 283 284 // Vector of methods to have verbose output enabled for. 285 const std::vector<std::string>* verbose_methods_; 286 287 // Abort compilation with an error if we find a class that fails verification with a hard 288 // failure. 289 bool abort_on_hard_verifier_failure_; 290 291 // Log initialization of initialization failures to this stream if not null. 292 std::unique_ptr<std::ostream> init_failure_output_; 293 294 std::string dump_cfg_file_name_; 295 bool dump_cfg_append_; 296 297 // Whether the compiler should trade performance for determinism to guarantee exactly reproducable 298 // outcomes. 299 bool force_determinism_; 300 301 friend class Dex2Oat; 302 303 DISALLOW_COPY_AND_ASSIGN(CompilerOptions); 304 }; 305 306 } // namespace art 307 308 #endif // ART_COMPILER_DRIVER_COMPILER_OPTIONS_H_ 309