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 "optimizing/register_allocator.h" 28 #include "utils.h" 29 30 namespace art { 31 32 namespace verifier { 33 class VerifierDepsTest; 34 } 35 36 class DexFile; 37 38 class CompilerOptions FINAL { 39 public: 40 // Guide heuristics to determine whether to compile method if profile data not available. 41 static const size_t kDefaultHugeMethodThreshold = 10000; 42 static const size_t kDefaultLargeMethodThreshold = 600; 43 static const size_t kDefaultSmallMethodThreshold = 60; 44 static const size_t kDefaultTinyMethodThreshold = 20; 45 static const size_t kDefaultNumDexMethodsThreshold = 900; 46 static constexpr double kDefaultTopKProfileThreshold = 90.0; 47 static const bool kDefaultGenerateDebugInfo = false; 48 static const bool kDefaultGenerateMiniDebugInfo = false; 49 static const size_t kDefaultInlineMaxCodeUnits = 32; 50 static constexpr size_t kUnsetInlineMaxCodeUnits = -1; 51 52 CompilerOptions(); 53 ~CompilerOptions(); 54 55 CompilerOptions(CompilerFilter::Filter compiler_filter, 56 size_t huge_method_threshold, 57 size_t large_method_threshold, 58 size_t small_method_threshold, 59 size_t tiny_method_threshold, 60 size_t num_dex_methods_threshold, 61 size_t inline_max_code_units, 62 const std::vector<const DexFile*>* no_inline_from, 63 double top_k_profile_threshold, 64 bool debuggable, 65 bool generate_debug_info, 66 bool implicit_null_checks, 67 bool implicit_so_checks, 68 bool implicit_suspend_checks, 69 bool compile_pic, 70 const std::vector<std::string>* verbose_methods, 71 std::ostream* init_failure_output, 72 bool abort_on_hard_verifier_failure, 73 const std::string& dump_cfg_file_name, 74 bool dump_cfg_append, 75 bool force_determinism, 76 RegisterAllocator::Strategy regalloc_strategy, 77 const std::vector<std::string>* passes_to_run); 78 GetCompilerFilter()79 CompilerFilter::Filter GetCompilerFilter() const { 80 return compiler_filter_; 81 } 82 SetCompilerFilter(CompilerFilter::Filter compiler_filter)83 void SetCompilerFilter(CompilerFilter::Filter compiler_filter) { 84 compiler_filter_ = compiler_filter; 85 } 86 IsAotCompilationEnabled()87 bool IsAotCompilationEnabled() const { 88 return CompilerFilter::IsAotCompilationEnabled(compiler_filter_); 89 } 90 IsJniCompilationEnabled()91 bool IsJniCompilationEnabled() const { 92 return CompilerFilter::IsJniCompilationEnabled(compiler_filter_); 93 } 94 IsQuickeningCompilationEnabled()95 bool IsQuickeningCompilationEnabled() const { 96 return CompilerFilter::IsQuickeningCompilationEnabled(compiler_filter_); 97 } 98 IsVerificationEnabled()99 bool IsVerificationEnabled() const { 100 return CompilerFilter::IsVerificationEnabled(compiler_filter_); 101 } 102 AssumeClassesAreVerified()103 bool AssumeClassesAreVerified() const { 104 return compiler_filter_ == CompilerFilter::kAssumeVerified; 105 } 106 VerifyAtRuntime()107 bool VerifyAtRuntime() const { 108 return compiler_filter_ == CompilerFilter::kExtract; 109 } 110 IsAnyCompilationEnabled()111 bool IsAnyCompilationEnabled() const { 112 return CompilerFilter::IsAnyCompilationEnabled(compiler_filter_); 113 } 114 GetHugeMethodThreshold()115 size_t GetHugeMethodThreshold() const { 116 return huge_method_threshold_; 117 } 118 GetLargeMethodThreshold()119 size_t GetLargeMethodThreshold() const { 120 return large_method_threshold_; 121 } 122 GetSmallMethodThreshold()123 size_t GetSmallMethodThreshold() const { 124 return small_method_threshold_; 125 } 126 GetTinyMethodThreshold()127 size_t GetTinyMethodThreshold() const { 128 return tiny_method_threshold_; 129 } 130 IsHugeMethod(size_t num_dalvik_instructions)131 bool IsHugeMethod(size_t num_dalvik_instructions) const { 132 return num_dalvik_instructions > huge_method_threshold_; 133 } 134 IsLargeMethod(size_t num_dalvik_instructions)135 bool IsLargeMethod(size_t num_dalvik_instructions) const { 136 return num_dalvik_instructions > large_method_threshold_; 137 } 138 IsSmallMethod(size_t num_dalvik_instructions)139 bool IsSmallMethod(size_t num_dalvik_instructions) const { 140 return num_dalvik_instructions > small_method_threshold_; 141 } 142 IsTinyMethod(size_t num_dalvik_instructions)143 bool IsTinyMethod(size_t num_dalvik_instructions) const { 144 return num_dalvik_instructions > tiny_method_threshold_; 145 } 146 GetNumDexMethodsThreshold()147 size_t GetNumDexMethodsThreshold() const { 148 return num_dex_methods_threshold_; 149 } 150 GetInlineMaxCodeUnits()151 size_t GetInlineMaxCodeUnits() const { 152 return inline_max_code_units_; 153 } SetInlineMaxCodeUnits(size_t units)154 void SetInlineMaxCodeUnits(size_t units) { 155 inline_max_code_units_ = units; 156 } 157 GetTopKProfileThreshold()158 double GetTopKProfileThreshold() const { 159 return top_k_profile_threshold_; 160 } 161 GetDebuggable()162 bool GetDebuggable() const { 163 return debuggable_; 164 } 165 GetNativeDebuggable()166 bool GetNativeDebuggable() const { 167 return GetDebuggable() && GetGenerateDebugInfo(); 168 } 169 170 // This flag controls whether the compiler collects debugging information. 171 // The other flags control how the information is written to disk. GenerateAnyDebugInfo()172 bool GenerateAnyDebugInfo() const { 173 return GetGenerateDebugInfo() || GetGenerateMiniDebugInfo(); 174 } 175 GetGenerateDebugInfo()176 bool GetGenerateDebugInfo() const { 177 return generate_debug_info_; 178 } 179 GetGenerateMiniDebugInfo()180 bool GetGenerateMiniDebugInfo() const { 181 return generate_mini_debug_info_; 182 } 183 GetGenerateBuildId()184 bool GetGenerateBuildId() const { 185 return generate_build_id_; 186 } 187 GetImplicitNullChecks()188 bool GetImplicitNullChecks() const { 189 return implicit_null_checks_; 190 } 191 GetImplicitStackOverflowChecks()192 bool GetImplicitStackOverflowChecks() const { 193 return implicit_so_checks_; 194 } 195 GetImplicitSuspendChecks()196 bool GetImplicitSuspendChecks() const { 197 return implicit_suspend_checks_; 198 } 199 IsBootImage()200 bool IsBootImage() const { 201 return boot_image_; 202 } 203 IsAppImage()204 bool IsAppImage() const { 205 return app_image_; 206 } 207 208 // Should the code be compiled as position independent? GetCompilePic()209 bool GetCompilePic() const { 210 return compile_pic_; 211 } 212 HasVerboseMethods()213 bool HasVerboseMethods() const { 214 return verbose_methods_ != nullptr && !verbose_methods_->empty(); 215 } 216 IsVerboseMethod(const std::string & pretty_method)217 bool IsVerboseMethod(const std::string& pretty_method) const { 218 for (const std::string& cur_method : *verbose_methods_) { 219 if (pretty_method.find(cur_method) != std::string::npos) { 220 return true; 221 } 222 } 223 return false; 224 } 225 GetInitFailureOutput()226 std::ostream* GetInitFailureOutput() const { 227 return init_failure_output_.get(); 228 } 229 AbortOnHardVerifierFailure()230 bool AbortOnHardVerifierFailure() const { 231 return abort_on_hard_verifier_failure_; 232 } 233 GetNoInlineFromDexFile()234 const std::vector<const DexFile*>* GetNoInlineFromDexFile() const { 235 return no_inline_from_; 236 } 237 238 bool ParseCompilerOption(const StringPiece& option, UsageFn Usage); 239 GetDumpCfgFileName()240 const std::string& GetDumpCfgFileName() const { 241 return dump_cfg_file_name_; 242 } 243 GetDumpCfgAppend()244 bool GetDumpCfgAppend() const { 245 return dump_cfg_append_; 246 } 247 IsForceDeterminism()248 bool IsForceDeterminism() const { 249 return force_determinism_; 250 } 251 GetRegisterAllocationStrategy()252 RegisterAllocator::Strategy GetRegisterAllocationStrategy() const { 253 return register_allocation_strategy_; 254 } 255 GetPassesToRun()256 const std::vector<std::string>* GetPassesToRun() const { 257 return passes_to_run_; 258 } 259 260 private: 261 void ParseDumpInitFailures(const StringPiece& option, UsageFn Usage); 262 void ParseDumpCfgPasses(const StringPiece& option, UsageFn Usage); 263 void ParseInlineMaxCodeUnits(const StringPiece& option, UsageFn Usage); 264 void ParseNumDexMethods(const StringPiece& option, UsageFn Usage); 265 void ParseTinyMethodMax(const StringPiece& option, UsageFn Usage); 266 void ParseSmallMethodMax(const StringPiece& option, UsageFn Usage); 267 void ParseLargeMethodMax(const StringPiece& option, UsageFn Usage); 268 void ParseHugeMethodMax(const StringPiece& option, UsageFn Usage); 269 void ParseRegisterAllocationStrategy(const StringPiece& option, UsageFn Usage); 270 271 CompilerFilter::Filter compiler_filter_; 272 size_t huge_method_threshold_; 273 size_t large_method_threshold_; 274 size_t small_method_threshold_; 275 size_t tiny_method_threshold_; 276 size_t num_dex_methods_threshold_; 277 size_t inline_max_code_units_; 278 279 // Dex files from which we should not inline code. 280 // This is usually a very short list (i.e. a single dex file), so we 281 // prefer vector<> over a lookup-oriented container, such as set<>. 282 const std::vector<const DexFile*>* no_inline_from_; 283 284 bool boot_image_; 285 bool app_image_; 286 // When using a profile file only the top K% of the profiled samples will be compiled. 287 double top_k_profile_threshold_; 288 bool debuggable_; 289 bool generate_debug_info_; 290 bool generate_mini_debug_info_; 291 bool generate_build_id_; 292 bool implicit_null_checks_; 293 bool implicit_so_checks_; 294 bool implicit_suspend_checks_; 295 bool compile_pic_; 296 297 // Vector of methods to have verbose output enabled for. 298 const std::vector<std::string>* verbose_methods_; 299 300 // Abort compilation with an error if we find a class that fails verification with a hard 301 // failure. 302 bool abort_on_hard_verifier_failure_; 303 304 // Log initialization of initialization failures to this stream if not null. 305 std::unique_ptr<std::ostream> init_failure_output_; 306 307 std::string dump_cfg_file_name_; 308 bool dump_cfg_append_; 309 310 // Whether the compiler should trade performance for determinism to guarantee exactly reproducible 311 // outcomes. 312 bool force_determinism_; 313 314 RegisterAllocator::Strategy register_allocation_strategy_; 315 316 // If not null, specifies optimization passes which will be run instead of defaults. 317 // Note that passes_to_run_ is not checked for correctness and providing an incorrect 318 // list of passes can lead to unexpected compiler behaviour. This is caused by dependencies 319 // between passes. Failing to satisfy them can for example lead to compiler crashes. 320 // Passing pass names which are not recognized by the compiler will result in 321 // compiler-dependant behavior. 322 const std::vector<std::string>* passes_to_run_; 323 324 friend class Dex2Oat; 325 friend class DexToDexDecompilerTest; 326 friend class CommonCompilerTest; 327 friend class verifier::VerifierDepsTest; 328 329 DISALLOW_COPY_AND_ASSIGN(CompilerOptions); 330 }; 331 332 } // namespace art 333 334 #endif // ART_COMPILER_DRIVER_COMPILER_OPTIONS_H_ 335