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 <memory> 21 #include <ostream> 22 #include <string> 23 #include <vector> 24 25 #include "base/globals.h" 26 #include "base/hash_set.h" 27 #include "base/macros.h" 28 #include "base/utils.h" 29 #include "compiler_filter.h" 30 #include "optimizing/register_allocator.h" 31 32 namespace art { 33 34 namespace jit { 35 class JitCompiler; 36 } // namespace jit 37 38 namespace verifier { 39 class VerifierDepsTest; 40 } // namespace verifier 41 42 namespace linker { 43 class Arm64RelativePatcherTest; 44 } // namespace linker 45 46 class DexFile; 47 enum class InstructionSet; 48 class InstructionSetFeatures; 49 class ProfileCompilationInfo; 50 class VerificationResults; 51 class VerifiedMethod; 52 53 // Enum for CheckProfileMethodsCompiled. Outside CompilerOptions so it can be forward-declared. 54 enum class ProfileMethodsCheck : uint8_t { 55 kNone, 56 kLog, 57 kAbort, 58 }; 59 60 class CompilerOptions final { 61 public: 62 // Guide heuristics to determine whether to compile method if profile data not available. 63 static const size_t kDefaultHugeMethodThreshold = 10000; 64 static const size_t kDefaultLargeMethodThreshold = 600; 65 static const size_t kDefaultSmallMethodThreshold = 60; 66 static const size_t kDefaultTinyMethodThreshold = 20; 67 static const size_t kDefaultNumDexMethodsThreshold = 900; 68 static constexpr double kDefaultTopKProfileThreshold = 90.0; 69 static const bool kDefaultGenerateDebugInfo = false; 70 static const bool kDefaultGenerateMiniDebugInfo = false; 71 static const size_t kDefaultInlineMaxCodeUnits = 32; 72 static constexpr size_t kUnsetInlineMaxCodeUnits = -1; 73 74 enum class ImageType : uint8_t { 75 kNone, // JIT or AOT app compilation producing only an oat file but no image. 76 kBootImage, // Creating boot image. 77 kAppImage, // Creating app image. 78 kApexBootImage, // Creating the apex image for jit/zygote experiment b/119800099. 79 }; 80 81 CompilerOptions(); 82 ~CompilerOptions(); 83 GetCompilerFilter()84 CompilerFilter::Filter GetCompilerFilter() const { 85 return compiler_filter_; 86 } 87 SetCompilerFilter(CompilerFilter::Filter compiler_filter)88 void SetCompilerFilter(CompilerFilter::Filter compiler_filter) { 89 compiler_filter_ = compiler_filter; 90 } 91 IsAotCompilationEnabled()92 bool IsAotCompilationEnabled() const { 93 return CompilerFilter::IsAotCompilationEnabled(compiler_filter_); 94 } 95 IsJniCompilationEnabled()96 bool IsJniCompilationEnabled() const { 97 return CompilerFilter::IsJniCompilationEnabled(compiler_filter_); 98 } 99 IsQuickeningCompilationEnabled()100 bool IsQuickeningCompilationEnabled() const { 101 return CompilerFilter::IsQuickeningCompilationEnabled(compiler_filter_); 102 } 103 IsVerificationEnabled()104 bool IsVerificationEnabled() const { 105 return CompilerFilter::IsVerificationEnabled(compiler_filter_); 106 } 107 AssumeClassesAreVerified()108 bool AssumeClassesAreVerified() const { 109 return compiler_filter_ == CompilerFilter::kAssumeVerified; 110 } 111 VerifyAtRuntime()112 bool VerifyAtRuntime() const { 113 return compiler_filter_ == CompilerFilter::kExtract; 114 } 115 IsAnyCompilationEnabled()116 bool IsAnyCompilationEnabled() const { 117 return CompilerFilter::IsAnyCompilationEnabled(compiler_filter_); 118 } 119 GetHugeMethodThreshold()120 size_t GetHugeMethodThreshold() const { 121 return huge_method_threshold_; 122 } 123 GetLargeMethodThreshold()124 size_t GetLargeMethodThreshold() const { 125 return large_method_threshold_; 126 } 127 GetSmallMethodThreshold()128 size_t GetSmallMethodThreshold() const { 129 return small_method_threshold_; 130 } 131 GetTinyMethodThreshold()132 size_t GetTinyMethodThreshold() const { 133 return tiny_method_threshold_; 134 } 135 IsHugeMethod(size_t num_dalvik_instructions)136 bool IsHugeMethod(size_t num_dalvik_instructions) const { 137 return num_dalvik_instructions > huge_method_threshold_; 138 } 139 IsLargeMethod(size_t num_dalvik_instructions)140 bool IsLargeMethod(size_t num_dalvik_instructions) const { 141 return num_dalvik_instructions > large_method_threshold_; 142 } 143 IsSmallMethod(size_t num_dalvik_instructions)144 bool IsSmallMethod(size_t num_dalvik_instructions) const { 145 return num_dalvik_instructions > small_method_threshold_; 146 } 147 IsTinyMethod(size_t num_dalvik_instructions)148 bool IsTinyMethod(size_t num_dalvik_instructions) const { 149 return num_dalvik_instructions > tiny_method_threshold_; 150 } 151 GetNumDexMethodsThreshold()152 size_t GetNumDexMethodsThreshold() const { 153 return num_dex_methods_threshold_; 154 } 155 GetInlineMaxCodeUnits()156 size_t GetInlineMaxCodeUnits() const { 157 return inline_max_code_units_; 158 } SetInlineMaxCodeUnits(size_t units)159 void SetInlineMaxCodeUnits(size_t units) { 160 inline_max_code_units_ = units; 161 } 162 GetTopKProfileThreshold()163 double GetTopKProfileThreshold() const { 164 return top_k_profile_threshold_; 165 } 166 GetDebuggable()167 bool GetDebuggable() const { 168 return debuggable_; 169 } 170 SetDebuggable(bool value)171 void SetDebuggable(bool value) { 172 debuggable_ = value; 173 } 174 GetNativeDebuggable()175 bool GetNativeDebuggable() const { 176 return GetDebuggable() && GetGenerateDebugInfo(); 177 } 178 179 // This flag controls whether the compiler collects debugging information. 180 // The other flags control how the information is written to disk. GenerateAnyDebugInfo()181 bool GenerateAnyDebugInfo() const { 182 return GetGenerateDebugInfo() || GetGenerateMiniDebugInfo(); 183 } 184 GetGenerateDebugInfo()185 bool GetGenerateDebugInfo() const { 186 return generate_debug_info_; 187 } 188 GetGenerateMiniDebugInfo()189 bool GetGenerateMiniDebugInfo() const { 190 return generate_mini_debug_info_; 191 } 192 193 // Should run-time checks be emitted in debug mode? 194 bool EmitRunTimeChecksInDebugMode() const; 195 GetGenerateBuildId()196 bool GetGenerateBuildId() const { 197 return generate_build_id_; 198 } 199 GetImplicitNullChecks()200 bool GetImplicitNullChecks() const { 201 return implicit_null_checks_; 202 } 203 GetImplicitStackOverflowChecks()204 bool GetImplicitStackOverflowChecks() const { 205 return implicit_so_checks_; 206 } 207 GetImplicitSuspendChecks()208 bool GetImplicitSuspendChecks() const { 209 return implicit_suspend_checks_; 210 } 211 212 // Are we compiling a boot image? IsBootImage()213 bool IsBootImage() const { 214 return image_type_ == ImageType::kBootImage || image_type_ == ImageType::kApexBootImage; 215 } 216 IsApexBootImage()217 bool IsApexBootImage() const { 218 return image_type_ == ImageType::kApexBootImage; 219 } 220 IsBaseline()221 bool IsBaseline() const { 222 return baseline_; 223 } 224 225 // Are we compiling an app image? IsAppImage()226 bool IsAppImage() const { 227 return image_type_ == ImageType::kAppImage; 228 } 229 230 // Returns whether we are compiling against a "core" image, which 231 // is an indicative we are running tests. The compiler will use that 232 // information for checking invariants. CompilingWithCoreImage()233 bool CompilingWithCoreImage() const { 234 return compiling_with_core_image_; 235 } 236 237 // Should the code be compiled as position independent? GetCompilePic()238 bool GetCompilePic() const { 239 return compile_pic_; 240 } 241 GetProfileCompilationInfo()242 const ProfileCompilationInfo* GetProfileCompilationInfo() const { 243 return profile_compilation_info_; 244 } 245 HasVerboseMethods()246 bool HasVerboseMethods() const { 247 return !verbose_methods_.empty(); 248 } 249 IsVerboseMethod(const std::string & pretty_method)250 bool IsVerboseMethod(const std::string& pretty_method) const { 251 for (const std::string& cur_method : verbose_methods_) { 252 if (pretty_method.find(cur_method) != std::string::npos) { 253 return true; 254 } 255 } 256 return false; 257 } 258 GetInitFailureOutput()259 std::ostream* GetInitFailureOutput() const { 260 return init_failure_output_.get(); 261 } 262 AbortOnHardVerifierFailure()263 bool AbortOnHardVerifierFailure() const { 264 return abort_on_hard_verifier_failure_; 265 } AbortOnSoftVerifierFailure()266 bool AbortOnSoftVerifierFailure() const { 267 return abort_on_soft_verifier_failure_; 268 } 269 GetInstructionSet()270 InstructionSet GetInstructionSet() const { 271 return instruction_set_; 272 } 273 GetInstructionSetFeatures()274 const InstructionSetFeatures* GetInstructionSetFeatures() const { 275 return instruction_set_features_.get(); 276 } 277 278 GetNoInlineFromDexFile()279 const std::vector<const DexFile*>& GetNoInlineFromDexFile() const { 280 return no_inline_from_; 281 } 282 GetDexFilesForOatFile()283 const std::vector<const DexFile*>& GetDexFilesForOatFile() const { 284 return dex_files_for_oat_file_; 285 } 286 GetImageClasses()287 const HashSet<std::string>& GetImageClasses() const { 288 return image_classes_; 289 } 290 291 bool IsImageClass(const char* descriptor) const; 292 293 const VerificationResults* GetVerificationResults() const; 294 295 const VerifiedMethod* GetVerifiedMethod(const DexFile* dex_file, uint32_t method_idx) const; 296 297 // Checks if the specified method has been verified without failures. Returns 298 // false if the method is not in the verification results (GetVerificationResults). 299 bool IsMethodVerifiedWithoutFailures(uint32_t method_idx, 300 uint16_t class_def_idx, 301 const DexFile& dex_file) const; 302 303 bool ParseCompilerOptions(const std::vector<std::string>& options, 304 bool ignore_unrecognized, 305 std::string* error_msg); 306 SetNonPic()307 void SetNonPic() { 308 compile_pic_ = false; 309 } 310 GetDumpCfgFileName()311 const std::string& GetDumpCfgFileName() const { 312 return dump_cfg_file_name_; 313 } 314 GetDumpCfgAppend()315 bool GetDumpCfgAppend() const { 316 return dump_cfg_append_; 317 } 318 IsForceDeterminism()319 bool IsForceDeterminism() const { 320 return force_determinism_; 321 } 322 DeduplicateCode()323 bool DeduplicateCode() const { 324 return deduplicate_code_; 325 } 326 GetRegisterAllocationStrategy()327 RegisterAllocator::Strategy GetRegisterAllocationStrategy() const { 328 return register_allocation_strategy_; 329 } 330 GetPassesToRun()331 const std::vector<std::string>* GetPassesToRun() const { 332 return passes_to_run_; 333 } 334 GetDumpTimings()335 bool GetDumpTimings() const { 336 return dump_timings_; 337 } 338 GetDumpPassTimings()339 bool GetDumpPassTimings() const { 340 return dump_pass_timings_; 341 } 342 GetDumpStats()343 bool GetDumpStats() const { 344 return dump_stats_; 345 } 346 CountHotnessInCompiledCode()347 bool CountHotnessInCompiledCode() const { 348 return count_hotness_in_compiled_code_; 349 } 350 ResolveStartupConstStrings()351 bool ResolveStartupConstStrings() const { 352 return resolve_startup_const_strings_; 353 } 354 CheckProfiledMethodsCompiled()355 ProfileMethodsCheck CheckProfiledMethodsCompiled() const { 356 return check_profiled_methods_; 357 } 358 MaxImageBlockSize()359 uint32_t MaxImageBlockSize() const { 360 return max_image_block_size_; 361 } 362 SetMaxImageBlockSize(uint32_t size)363 void SetMaxImageBlockSize(uint32_t size) { 364 max_image_block_size_ = size; 365 } 366 367 // Is `boot_image_filename` the name of a core image (small boot 368 // image used for ART testing only)? 369 static bool IsCoreImageFilename(const std::string& boot_image_filename); 370 371 private: 372 bool ParseDumpInitFailures(const std::string& option, std::string* error_msg); 373 bool ParseRegisterAllocationStrategy(const std::string& option, std::string* error_msg); 374 375 CompilerFilter::Filter compiler_filter_; 376 size_t huge_method_threshold_; 377 size_t large_method_threshold_; 378 size_t small_method_threshold_; 379 size_t tiny_method_threshold_; 380 size_t num_dex_methods_threshold_; 381 size_t inline_max_code_units_; 382 383 InstructionSet instruction_set_; 384 std::unique_ptr<const InstructionSetFeatures> instruction_set_features_; 385 386 // Dex files from which we should not inline code. Does not own the dex files. 387 // This is usually a very short list (i.e. a single dex file), so we 388 // prefer vector<> over a lookup-oriented container, such as set<>. 389 std::vector<const DexFile*> no_inline_from_; 390 391 // List of dex files associated with the oat file, empty for JIT. 392 std::vector<const DexFile*> dex_files_for_oat_file_; 393 394 // Image classes, specifies the classes that will be included in the image if creating an image. 395 // Must not be empty for real boot image, only for tests pretending to compile boot image. 396 HashSet<std::string> image_classes_; 397 398 // Results of AOT verification. 399 const VerificationResults* verification_results_; 400 401 ImageType image_type_; 402 bool compiling_with_core_image_; 403 bool baseline_; 404 bool debuggable_; 405 bool generate_debug_info_; 406 bool generate_mini_debug_info_; 407 bool generate_build_id_; 408 bool implicit_null_checks_; 409 bool implicit_so_checks_; 410 bool implicit_suspend_checks_; 411 bool compile_pic_; 412 bool dump_timings_; 413 bool dump_pass_timings_; 414 bool dump_stats_; 415 416 // When using a profile file only the top K% of the profiled samples will be compiled. 417 double top_k_profile_threshold_; 418 419 // Info for profile guided compilation. 420 const ProfileCompilationInfo* profile_compilation_info_; 421 422 // Vector of methods to have verbose output enabled for. 423 std::vector<std::string> verbose_methods_; 424 425 // Abort compilation with an error if we find a class that fails verification with a hard 426 // failure. 427 bool abort_on_hard_verifier_failure_; 428 // Same for soft failures. 429 bool abort_on_soft_verifier_failure_; 430 431 // Log initialization of initialization failures to this stream if not null. 432 std::unique_ptr<std::ostream> init_failure_output_; 433 434 std::string dump_cfg_file_name_; 435 bool dump_cfg_append_; 436 437 // Whether the compiler should trade performance for determinism to guarantee exactly reproducible 438 // outcomes. 439 bool force_determinism_; 440 441 // Whether code should be deduplicated. 442 bool deduplicate_code_; 443 444 // Whether compiled code should increment the hotness count of ArtMethod. Note that the increments 445 // won't be atomic for performance reasons, so we accept races, just like in interpreter. 446 bool count_hotness_in_compiled_code_; 447 448 // Whether we eagerly resolve all of the const strings that are loaded from startup methods in the 449 // profile. 450 bool resolve_startup_const_strings_; 451 452 // When running profile-guided compilation, check that methods intended to be compiled end 453 // up compiled and are not punted. 454 ProfileMethodsCheck check_profiled_methods_; 455 456 // Maximum solid block size in the generated image. 457 uint32_t max_image_block_size_; 458 459 RegisterAllocator::Strategy register_allocation_strategy_; 460 461 // If not null, specifies optimization passes which will be run instead of defaults. 462 // Note that passes_to_run_ is not checked for correctness and providing an incorrect 463 // list of passes can lead to unexpected compiler behaviour. This is caused by dependencies 464 // between passes. Failing to satisfy them can for example lead to compiler crashes. 465 // Passing pass names which are not recognized by the compiler will result in 466 // compiler-dependant behavior. 467 const std::vector<std::string>* passes_to_run_; 468 469 friend class Dex2Oat; 470 friend class DexToDexDecompilerTest; 471 friend class CommonCompilerDriverTest; 472 friend class CommonCompilerTest; 473 friend class jit::JitCompiler; 474 friend class verifier::VerifierDepsTest; 475 friend class linker::Arm64RelativePatcherTest; 476 477 template <class Base> 478 friend bool ReadCompilerOptions(Base& map, CompilerOptions* options, std::string* error_msg); 479 480 DISALLOW_COPY_AND_ASSIGN(CompilerOptions); 481 }; 482 483 } // namespace art 484 485 #endif // ART_COMPILER_DRIVER_COMPILER_OPTIONS_H_ 486