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 "base/utils.h" 26 #include "compiler_filter.h" 27 #include "globals.h" 28 #include "optimizing/register_allocator.h" 29 30 namespace art { 31 32 namespace verifier { 33 class VerifierDepsTest; 34 } // namespace verifier 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 GetCompilerFilter()55 CompilerFilter::Filter GetCompilerFilter() const { 56 return compiler_filter_; 57 } 58 SetCompilerFilter(CompilerFilter::Filter compiler_filter)59 void SetCompilerFilter(CompilerFilter::Filter compiler_filter) { 60 compiler_filter_ = compiler_filter; 61 } 62 IsAotCompilationEnabled()63 bool IsAotCompilationEnabled() const { 64 return CompilerFilter::IsAotCompilationEnabled(compiler_filter_); 65 } 66 IsJniCompilationEnabled()67 bool IsJniCompilationEnabled() const { 68 return CompilerFilter::IsJniCompilationEnabled(compiler_filter_); 69 } 70 IsQuickeningCompilationEnabled()71 bool IsQuickeningCompilationEnabled() const { 72 return CompilerFilter::IsQuickeningCompilationEnabled(compiler_filter_); 73 } 74 IsVerificationEnabled()75 bool IsVerificationEnabled() const { 76 return CompilerFilter::IsVerificationEnabled(compiler_filter_); 77 } 78 AssumeClassesAreVerified()79 bool AssumeClassesAreVerified() const { 80 return compiler_filter_ == CompilerFilter::kAssumeVerified; 81 } 82 VerifyAtRuntime()83 bool VerifyAtRuntime() const { 84 return compiler_filter_ == CompilerFilter::kExtract; 85 } 86 IsAnyCompilationEnabled()87 bool IsAnyCompilationEnabled() const { 88 return CompilerFilter::IsAnyCompilationEnabled(compiler_filter_); 89 } 90 GetHugeMethodThreshold()91 size_t GetHugeMethodThreshold() const { 92 return huge_method_threshold_; 93 } 94 GetLargeMethodThreshold()95 size_t GetLargeMethodThreshold() const { 96 return large_method_threshold_; 97 } 98 GetSmallMethodThreshold()99 size_t GetSmallMethodThreshold() const { 100 return small_method_threshold_; 101 } 102 GetTinyMethodThreshold()103 size_t GetTinyMethodThreshold() const { 104 return tiny_method_threshold_; 105 } 106 IsHugeMethod(size_t num_dalvik_instructions)107 bool IsHugeMethod(size_t num_dalvik_instructions) const { 108 return num_dalvik_instructions > huge_method_threshold_; 109 } 110 IsLargeMethod(size_t num_dalvik_instructions)111 bool IsLargeMethod(size_t num_dalvik_instructions) const { 112 return num_dalvik_instructions > large_method_threshold_; 113 } 114 IsSmallMethod(size_t num_dalvik_instructions)115 bool IsSmallMethod(size_t num_dalvik_instructions) const { 116 return num_dalvik_instructions > small_method_threshold_; 117 } 118 IsTinyMethod(size_t num_dalvik_instructions)119 bool IsTinyMethod(size_t num_dalvik_instructions) const { 120 return num_dalvik_instructions > tiny_method_threshold_; 121 } 122 GetNumDexMethodsThreshold()123 size_t GetNumDexMethodsThreshold() const { 124 return num_dex_methods_threshold_; 125 } 126 GetInlineMaxCodeUnits()127 size_t GetInlineMaxCodeUnits() const { 128 return inline_max_code_units_; 129 } SetInlineMaxCodeUnits(size_t units)130 void SetInlineMaxCodeUnits(size_t units) { 131 inline_max_code_units_ = units; 132 } 133 GetTopKProfileThreshold()134 double GetTopKProfileThreshold() const { 135 return top_k_profile_threshold_; 136 } 137 GetDebuggable()138 bool GetDebuggable() const { 139 return debuggable_; 140 } 141 SetDebuggable(bool value)142 void SetDebuggable(bool value) { 143 debuggable_ = value; 144 } 145 GetNativeDebuggable()146 bool GetNativeDebuggable() const { 147 return GetDebuggable() && GetGenerateDebugInfo(); 148 } 149 150 // This flag controls whether the compiler collects debugging information. 151 // The other flags control how the information is written to disk. GenerateAnyDebugInfo()152 bool GenerateAnyDebugInfo() const { 153 return GetGenerateDebugInfo() || GetGenerateMiniDebugInfo(); 154 } 155 GetGenerateDebugInfo()156 bool GetGenerateDebugInfo() const { 157 return generate_debug_info_; 158 } 159 GetGenerateMiniDebugInfo()160 bool GetGenerateMiniDebugInfo() const { 161 return generate_mini_debug_info_; 162 } 163 164 // Should run-time checks be emitted in debug mode? 165 bool EmitRunTimeChecksInDebugMode() const; 166 GetGenerateBuildId()167 bool GetGenerateBuildId() const { 168 return generate_build_id_; 169 } 170 GetImplicitNullChecks()171 bool GetImplicitNullChecks() const { 172 return implicit_null_checks_; 173 } 174 GetImplicitStackOverflowChecks()175 bool GetImplicitStackOverflowChecks() const { 176 return implicit_so_checks_; 177 } 178 GetImplicitSuspendChecks()179 bool GetImplicitSuspendChecks() const { 180 return implicit_suspend_checks_; 181 } 182 183 // Are we compiling a boot image? IsBootImage()184 bool IsBootImage() const { 185 return boot_image_; 186 } 187 188 // Are we compiling a core image (small boot image only used for ART testing)? IsCoreImage()189 bool IsCoreImage() const { 190 // Ensure that `core_image_` => `boot_image_`. 191 DCHECK(!core_image_ || boot_image_); 192 return core_image_; 193 } 194 195 // Are we compiling an app image? IsAppImage()196 bool IsAppImage() const { 197 return app_image_; 198 } 199 DisableAppImage()200 void DisableAppImage() { 201 app_image_ = false; 202 } 203 204 // Should the code be compiled as position independent? GetCompilePic()205 bool GetCompilePic() const { 206 return compile_pic_; 207 } 208 HasVerboseMethods()209 bool HasVerboseMethods() const { 210 return !verbose_methods_.empty(); 211 } 212 IsVerboseMethod(const std::string & pretty_method)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 GetInitFailureOutput()222 std::ostream* GetInitFailureOutput() const { 223 return init_failure_output_.get(); 224 } 225 AbortOnHardVerifierFailure()226 bool AbortOnHardVerifierFailure() const { 227 return abort_on_hard_verifier_failure_; 228 } AbortOnSoftVerifierFailure()229 bool AbortOnSoftVerifierFailure() const { 230 return abort_on_soft_verifier_failure_; 231 } 232 GetNoInlineFromDexFile()233 const std::vector<const DexFile*>* GetNoInlineFromDexFile() const { 234 return no_inline_from_; 235 } 236 237 bool ParseCompilerOptions(const std::vector<std::string>& options, 238 bool ignore_unrecognized, 239 std::string* error_msg); 240 SetNonPic()241 void SetNonPic() { 242 compile_pic_ = false; 243 } 244 GetDumpCfgFileName()245 const std::string& GetDumpCfgFileName() const { 246 return dump_cfg_file_name_; 247 } 248 GetDumpCfgAppend()249 bool GetDumpCfgAppend() const { 250 return dump_cfg_append_; 251 } 252 IsForceDeterminism()253 bool IsForceDeterminism() const { 254 return force_determinism_; 255 } 256 DeduplicateCode()257 bool DeduplicateCode() const { 258 return deduplicate_code_; 259 } 260 GetRegisterAllocationStrategy()261 RegisterAllocator::Strategy GetRegisterAllocationStrategy() const { 262 return register_allocation_strategy_; 263 } 264 GetPassesToRun()265 const std::vector<std::string>* GetPassesToRun() const { 266 return passes_to_run_; 267 } 268 GetDumpTimings()269 bool GetDumpTimings() const { 270 return dump_timings_; 271 } 272 GetDumpStats()273 bool GetDumpStats() const { 274 return dump_stats_; 275 } 276 CountHotnessInCompiledCode()277 bool CountHotnessInCompiledCode() const { 278 return count_hotness_in_compiled_code_; 279 } 280 281 private: 282 bool ParseDumpInitFailures(const std::string& option, std::string* error_msg); 283 void ParseDumpCfgPasses(const StringPiece& option, UsageFn Usage); 284 void ParseInlineMaxCodeUnits(const StringPiece& option, UsageFn Usage); 285 void ParseNumDexMethods(const StringPiece& option, UsageFn Usage); 286 void ParseTinyMethodMax(const StringPiece& option, UsageFn Usage); 287 void ParseSmallMethodMax(const StringPiece& option, UsageFn Usage); 288 void ParseLargeMethodMax(const StringPiece& option, UsageFn Usage); 289 void ParseHugeMethodMax(const StringPiece& option, UsageFn Usage); 290 bool ParseRegisterAllocationStrategy(const std::string& option, std::string* error_msg); 291 292 CompilerFilter::Filter compiler_filter_; 293 size_t huge_method_threshold_; 294 size_t large_method_threshold_; 295 size_t small_method_threshold_; 296 size_t tiny_method_threshold_; 297 size_t num_dex_methods_threshold_; 298 size_t inline_max_code_units_; 299 300 // Dex files from which we should not inline code. 301 // This is usually a very short list (i.e. a single dex file), so we 302 // prefer vector<> over a lookup-oriented container, such as set<>. 303 const std::vector<const DexFile*>* no_inline_from_; 304 305 bool boot_image_; 306 bool core_image_; 307 bool app_image_; 308 // When using a profile file only the top K% of the profiled samples will be compiled. 309 double top_k_profile_threshold_; 310 bool debuggable_; 311 bool generate_debug_info_; 312 bool generate_mini_debug_info_; 313 bool generate_build_id_; 314 bool implicit_null_checks_; 315 bool implicit_so_checks_; 316 bool implicit_suspend_checks_; 317 bool compile_pic_; 318 bool dump_timings_; 319 bool dump_stats_; 320 321 // Vector of methods to have verbose output enabled for. 322 std::vector<std::string> verbose_methods_; 323 324 // Abort compilation with an error if we find a class that fails verification with a hard 325 // failure. 326 bool abort_on_hard_verifier_failure_; 327 // Same for soft failures. 328 bool abort_on_soft_verifier_failure_; 329 330 // Log initialization of initialization failures to this stream if not null. 331 std::unique_ptr<std::ostream> init_failure_output_; 332 333 std::string dump_cfg_file_name_; 334 bool dump_cfg_append_; 335 336 // Whether the compiler should trade performance for determinism to guarantee exactly reproducible 337 // outcomes. 338 bool force_determinism_; 339 340 // Whether code should be deduplicated. 341 bool deduplicate_code_; 342 343 // Whether compiled code should increment the hotness count of ArtMethod. Note that the increments 344 // won't be atomic for performance reasons, so we accept races, just like in interpreter. 345 bool count_hotness_in_compiled_code_; 346 347 RegisterAllocator::Strategy register_allocation_strategy_; 348 349 // If not null, specifies optimization passes which will be run instead of defaults. 350 // Note that passes_to_run_ is not checked for correctness and providing an incorrect 351 // list of passes can lead to unexpected compiler behaviour. This is caused by dependencies 352 // between passes. Failing to satisfy them can for example lead to compiler crashes. 353 // Passing pass names which are not recognized by the compiler will result in 354 // compiler-dependant behavior. 355 const std::vector<std::string>* passes_to_run_; 356 357 friend class Dex2Oat; 358 friend class DexToDexDecompilerTest; 359 friend class CommonCompilerTest; 360 friend class verifier::VerifierDepsTest; 361 362 template <class Base> 363 friend bool ReadCompilerOptions(Base& map, CompilerOptions* options, std::string* error_msg); 364 365 DISALLOW_COPY_AND_ASSIGN(CompilerOptions); 366 }; 367 368 } // namespace art 369 370 #endif // ART_COMPILER_DRIVER_COMPILER_OPTIONS_H_ 371