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/compiler_filter.h" 26 #include "base/globals.h" 27 #include "base/hash_set.h" 28 #include "base/macros.h" 29 #include "base/stl_util.h" 30 #include "base/utils.h" 31 #include "optimizing/register_allocator.h" 32 33 namespace art HIDDEN { 34 35 namespace jit { 36 class JitCompiler; 37 } // namespace jit 38 39 namespace verifier { 40 class VerifierDepsTest; 41 } // namespace verifier 42 43 namespace linker { 44 class Arm64RelativePatcherTest; 45 } // namespace linker 46 47 class ArtMethod; 48 class DexFile; 49 enum class InstructionSet; 50 class InstructionSetFeatures; 51 class ProfileCompilationInfo; 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 kDefaultNumDexMethodsThreshold = 900; 66 static constexpr double kDefaultTopKProfileThreshold = 90.0; 67 static const bool kDefaultGenerateDebugInfo = false; 68 static const bool kDefaultGenerateMiniDebugInfo = true; 69 static const size_t kDefaultInlineMaxCodeUnits = 32; 70 static constexpr size_t kUnsetInlineMaxCodeUnits = -1; 71 72 enum class CompilerType : uint8_t { 73 kAotCompiler, // AOT compiler. 74 kJitCompiler, // Normal JIT compiler. 75 kSharedCodeJitCompiler, // Zygote JIT producing code in the shared region area, putting 76 // restrictions on, for example, how literals are being generated. 77 }; 78 79 enum class ImageType : uint8_t { 80 kNone, // JIT or AOT app compilation producing only an oat file but no image. 81 kBootImage, // Creating boot image. 82 kBootImageExtension, // Creating boot image extension. 83 kAppImage, // Creating app image. 84 }; 85 86 EXPORT CompilerOptions(); 87 EXPORT ~CompilerOptions(); 88 GetCompilerFilter()89 CompilerFilter::Filter GetCompilerFilter() const { 90 return compiler_filter_; 91 } 92 SetCompilerFilter(CompilerFilter::Filter compiler_filter)93 void SetCompilerFilter(CompilerFilter::Filter compiler_filter) { 94 compiler_filter_ = compiler_filter; 95 } 96 IsAotCompilationEnabled()97 bool IsAotCompilationEnabled() const { 98 return CompilerFilter::IsAotCompilationEnabled(compiler_filter_); 99 } 100 IsJniCompilationEnabled()101 bool IsJniCompilationEnabled() const { 102 return CompilerFilter::IsJniCompilationEnabled(compiler_filter_); 103 } 104 IsVerificationEnabled()105 bool IsVerificationEnabled() const { 106 return CompilerFilter::IsVerificationEnabled(compiler_filter_); 107 } 108 AssumeDexFilesAreVerified()109 bool AssumeDexFilesAreVerified() const { 110 return compiler_filter_ == CompilerFilter::kAssumeVerified; 111 } 112 AssumeClassesAreVerified()113 bool AssumeClassesAreVerified() const { 114 return compiler_filter_ == CompilerFilter::kAssumeVerified; 115 } 116 IsAnyCompilationEnabled()117 bool IsAnyCompilationEnabled() const { 118 return CompilerFilter::IsAnyCompilationEnabled(compiler_filter_) && 119 // TODO(riscv64): remove this when we have compiler support for RISC-V 120 GetInstructionSet() != InstructionSet::kRiscv64; 121 } 122 GetHugeMethodThreshold()123 size_t GetHugeMethodThreshold() const { 124 return huge_method_threshold_; 125 } 126 GetLargeMethodThreshold()127 size_t GetLargeMethodThreshold() const { 128 return large_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 GetNumDexMethodsThreshold()139 size_t GetNumDexMethodsThreshold() const { 140 return num_dex_methods_threshold_; 141 } 142 GetInlineMaxCodeUnits()143 size_t GetInlineMaxCodeUnits() const { 144 return inline_max_code_units_; 145 } SetInlineMaxCodeUnits(size_t units)146 void SetInlineMaxCodeUnits(size_t units) { 147 inline_max_code_units_ = units; 148 } 149 GetTopKProfileThreshold()150 double GetTopKProfileThreshold() const { 151 return top_k_profile_threshold_; 152 } 153 GetDebuggable()154 bool GetDebuggable() const { 155 return debuggable_; 156 } 157 SetDebuggable(bool value)158 void SetDebuggable(bool value) { 159 debuggable_ = value; 160 } 161 GetNativeDebuggable()162 bool GetNativeDebuggable() const { 163 return GetDebuggable() && GetGenerateDebugInfo(); 164 } 165 166 // This flag controls whether the compiler collects debugging information. 167 // The other flags control how the information is written to disk. GenerateAnyDebugInfo()168 bool GenerateAnyDebugInfo() const { 169 return GetGenerateDebugInfo() || GetGenerateMiniDebugInfo(); 170 } 171 GetGenerateDebugInfo()172 bool GetGenerateDebugInfo() const { 173 return generate_debug_info_; 174 } 175 GetGenerateMiniDebugInfo()176 bool GetGenerateMiniDebugInfo() const { 177 return generate_mini_debug_info_; 178 } 179 180 // Should run-time checks be emitted in debug mode? 181 bool EmitRunTimeChecksInDebugMode() const; 182 GetGenerateBuildId()183 bool GetGenerateBuildId() const { 184 return generate_build_id_; 185 } 186 GetImplicitNullChecks()187 bool GetImplicitNullChecks() const { 188 return implicit_null_checks_; 189 } 190 GetImplicitStackOverflowChecks()191 bool GetImplicitStackOverflowChecks() const { 192 return implicit_so_checks_; 193 } 194 IsAotCompiler()195 bool IsAotCompiler() const { 196 return compiler_type_ == CompilerType::kAotCompiler; 197 } 198 IsJitCompiler()199 bool IsJitCompiler() const { 200 return compiler_type_ == CompilerType::kJitCompiler || 201 compiler_type_ == CompilerType::kSharedCodeJitCompiler; 202 } 203 IsJitCompilerForSharedCode()204 bool IsJitCompilerForSharedCode() const { 205 return compiler_type_ == CompilerType::kSharedCodeJitCompiler; 206 } 207 GetImplicitSuspendChecks()208 bool GetImplicitSuspendChecks() const { 209 return implicit_suspend_checks_; 210 } 211 IsGeneratingImage()212 bool IsGeneratingImage() const { 213 return IsBootImage() || IsBootImageExtension() || IsAppImage(); 214 } 215 216 // Are we compiling a boot image? IsBootImage()217 bool IsBootImage() const { 218 return image_type_ == ImageType::kBootImage; 219 } 220 221 // Are we compiling a boot image extension? IsBootImageExtension()222 bool IsBootImageExtension() const { 223 return image_type_ == ImageType::kBootImageExtension; 224 } 225 IsBaseline()226 bool IsBaseline() const { 227 return baseline_; 228 } 229 230 // Are we compiling an app image? IsAppImage()231 bool IsAppImage() const { 232 return image_type_ == ImageType::kAppImage; 233 } 234 IsMultiImage()235 bool IsMultiImage() const { 236 return multi_image_; 237 } 238 239 // Returns whether we are running ART tests. 240 // The compiler will use that information for checking invariants. CompileArtTest()241 bool CompileArtTest() const { 242 return compile_art_test_; 243 } 244 245 // Should the code be compiled as position independent? GetCompilePic()246 bool GetCompilePic() const { 247 return compile_pic_; 248 } 249 GetProfileCompilationInfo()250 const ProfileCompilationInfo* GetProfileCompilationInfo() const { 251 return profile_compilation_info_; 252 } 253 HasVerboseMethods()254 bool HasVerboseMethods() const { 255 return !verbose_methods_.empty(); 256 } 257 IsVerboseMethod(const std::string & pretty_method)258 bool IsVerboseMethod(const std::string& pretty_method) const { 259 for (const std::string& cur_method : verbose_methods_) { 260 if (pretty_method.find(cur_method) != std::string::npos) { 261 return true; 262 } 263 } 264 return false; 265 } 266 GetInitFailureOutput()267 std::ostream* GetInitFailureOutput() const { 268 return init_failure_output_.get(); 269 } 270 AbortOnHardVerifierFailure()271 bool AbortOnHardVerifierFailure() const { 272 return abort_on_hard_verifier_failure_; 273 } AbortOnSoftVerifierFailure()274 bool AbortOnSoftVerifierFailure() const { 275 return abort_on_soft_verifier_failure_; 276 } 277 GetInstructionSet()278 InstructionSet GetInstructionSet() const { 279 return instruction_set_; 280 } 281 GetInstructionSetFeatures()282 const InstructionSetFeatures* GetInstructionSetFeatures() const { 283 return instruction_set_features_.get(); 284 } 285 286 GetNoInlineFromDexFile()287 const std::vector<const DexFile*>& GetNoInlineFromDexFile() const { 288 return no_inline_from_; 289 } 290 GetDexFilesForOatFile()291 const std::vector<const DexFile*>& GetDexFilesForOatFile() const { 292 return dex_files_for_oat_file_; 293 } 294 GetImageClasses()295 const HashSet<std::string>& GetImageClasses() const { 296 return image_classes_; 297 } 298 299 EXPORT bool IsImageClass(const char* descriptor) const; 300 301 // Returns whether the given `pretty_descriptor` is in the list of preloaded 302 // classes. `pretty_descriptor` should be the result of calling `PrettyDescriptor`. 303 EXPORT bool IsPreloadedClass(const char* pretty_descriptor) const; 304 305 bool ParseCompilerOptions(const std::vector<std::string>& options, 306 bool ignore_unrecognized, 307 std::string* error_msg); 308 SetNonPic()309 void SetNonPic() { 310 compile_pic_ = false; 311 } 312 GetDumpCfgFileName()313 const std::string& GetDumpCfgFileName() const { 314 return dump_cfg_file_name_; 315 } 316 GetDumpCfgAppend()317 bool GetDumpCfgAppend() const { 318 return dump_cfg_append_; 319 } 320 IsForceDeterminism()321 bool IsForceDeterminism() const { 322 return force_determinism_; 323 } 324 IsCheckLinkageConditions()325 bool IsCheckLinkageConditions() const { 326 return check_linkage_conditions_; 327 } 328 IsCrashOnLinkageViolation()329 bool IsCrashOnLinkageViolation() const { 330 return crash_on_linkage_violation_; 331 } 332 DeduplicateCode()333 bool DeduplicateCode() const { 334 return deduplicate_code_; 335 } 336 GetRegisterAllocationStrategy()337 RegisterAllocator::Strategy GetRegisterAllocationStrategy() const { 338 return register_allocation_strategy_; 339 } 340 GetPassesToRun()341 const std::vector<std::string>* GetPassesToRun() const { 342 return passes_to_run_; 343 } 344 GetDumpTimings()345 bool GetDumpTimings() const { 346 return dump_timings_; 347 } 348 GetDumpPassTimings()349 bool GetDumpPassTimings() const { 350 return dump_pass_timings_; 351 } 352 GetDumpStats()353 bool GetDumpStats() const { 354 return dump_stats_; 355 } 356 CountHotnessInCompiledCode()357 bool CountHotnessInCompiledCode() const { 358 return count_hotness_in_compiled_code_; 359 } 360 ResolveStartupConstStrings()361 bool ResolveStartupConstStrings() const { 362 return resolve_startup_const_strings_; 363 } 364 CheckProfiledMethodsCompiled()365 ProfileMethodsCheck CheckProfiledMethodsCompiled() const { 366 return check_profiled_methods_; 367 } 368 MaxImageBlockSize()369 uint32_t MaxImageBlockSize() const { 370 return max_image_block_size_; 371 } 372 SetMaxImageBlockSize(uint32_t size)373 void SetMaxImageBlockSize(uint32_t size) { 374 max_image_block_size_ = size; 375 } 376 InitializeAppImageClasses()377 bool InitializeAppImageClasses() const { 378 return initialize_app_image_classes_; 379 } 380 381 // Returns true if `dex_file` is within an oat file we're producing right now. WithinOatFile(const DexFile * dex_file)382 bool WithinOatFile(const DexFile* dex_file) const { 383 return ContainsElement(GetDexFilesForOatFile(), dex_file); 384 } 385 386 // If this is a static non-constructor method in the boot classpath, and its class isn't 387 // initialized at compile-time, or won't be initialized by the zygote, add 388 // initialization checks at entry. This will avoid the need of trampolines 389 // which at runtime we will need to dirty after initialization. 390 EXPORT bool ShouldCompileWithClinitCheck(ArtMethod* method) const; 391 392 private: 393 EXPORT bool ParseDumpInitFailures(const std::string& option, std::string* error_msg); 394 EXPORT bool ParseRegisterAllocationStrategy(const std::string& option, std::string* error_msg); 395 396 CompilerFilter::Filter compiler_filter_; 397 size_t huge_method_threshold_; 398 size_t large_method_threshold_; 399 size_t num_dex_methods_threshold_; 400 size_t inline_max_code_units_; 401 402 InstructionSet instruction_set_; 403 std::unique_ptr<const InstructionSetFeatures> instruction_set_features_; 404 405 // Dex files from which we should not inline code. Does not own the dex files. 406 // This is usually a very short list (i.e. a single dex file), so we 407 // prefer vector<> over a lookup-oriented container, such as set<>. 408 std::vector<const DexFile*> no_inline_from_; 409 410 // List of dex files associated with the oat file, empty for JIT. 411 std::vector<const DexFile*> dex_files_for_oat_file_; 412 413 // Image classes, specifies the classes that will be included in the image if creating an image. 414 // Must not be empty for real boot image, only for tests pretending to compile boot image. 415 HashSet<std::string> image_classes_; 416 417 // Classes listed in the preloaded-classes file, used for boot image and 418 // boot image extension compilation. 419 HashSet<std::string> preloaded_classes_; 420 421 CompilerType compiler_type_; 422 ImageType image_type_; 423 bool multi_image_; 424 bool compile_art_test_; 425 bool baseline_; 426 bool debuggable_; 427 bool generate_debug_info_; 428 bool generate_mini_debug_info_; 429 bool generate_build_id_; 430 bool implicit_null_checks_; 431 bool implicit_so_checks_; 432 bool implicit_suspend_checks_; 433 bool compile_pic_; 434 bool dump_timings_; 435 bool dump_pass_timings_; 436 bool dump_stats_; 437 438 // When using a profile file only the top K% of the profiled samples will be compiled. 439 double top_k_profile_threshold_; 440 441 // Info for profile guided compilation. 442 const ProfileCompilationInfo* profile_compilation_info_; 443 444 // Vector of methods to have verbose output enabled for. 445 std::vector<std::string> verbose_methods_; 446 447 // Abort compilation with an error if we find a class that fails verification with a hard 448 // failure. 449 bool abort_on_hard_verifier_failure_; 450 // Same for soft failures. 451 bool abort_on_soft_verifier_failure_; 452 453 // Log initialization of initialization failures to this stream if not null. 454 std::unique_ptr<std::ostream> init_failure_output_; 455 456 std::string dump_cfg_file_name_; 457 bool dump_cfg_append_; 458 459 // Whether the compiler should trade performance for determinism to guarantee exactly reproducible 460 // outcomes. 461 bool force_determinism_; 462 463 // Whether the compiler should check for violation of the conditions required to perform AOT 464 // "linkage". 465 bool check_linkage_conditions_; 466 // Whether the compiler should crash when encountering a violation of one of 467 // the conditions required to perform AOT "linkage". 468 bool crash_on_linkage_violation_; 469 470 // Whether code should be deduplicated. 471 bool deduplicate_code_; 472 473 // Whether compiled code should increment the hotness count of ArtMethod. Note that the increments 474 // won't be atomic for performance reasons, so we accept races, just like in interpreter. 475 bool count_hotness_in_compiled_code_; 476 477 // Whether we eagerly resolve all of the const strings that are loaded from startup methods in the 478 // profile. 479 bool resolve_startup_const_strings_; 480 481 // Whether we attempt to run class initializers for app image classes. 482 bool initialize_app_image_classes_; 483 484 // When running profile-guided compilation, check that methods intended to be compiled end 485 // up compiled and are not punted. 486 ProfileMethodsCheck check_profiled_methods_; 487 488 // Maximum solid block size in the generated image. 489 uint32_t max_image_block_size_; 490 491 RegisterAllocator::Strategy register_allocation_strategy_; 492 493 // If not null, specifies optimization passes which will be run instead of defaults. 494 // Note that passes_to_run_ is not checked for correctness and providing an incorrect 495 // list of passes can lead to unexpected compiler behaviour. This is caused by dependencies 496 // between passes. Failing to satisfy them can for example lead to compiler crashes. 497 // Passing pass names which are not recognized by the compiler will result in 498 // compiler-dependant behavior. 499 const std::vector<std::string>* passes_to_run_; 500 501 friend class Dex2Oat; 502 friend class CommonCompilerDriverTest; 503 friend class CommonCompilerTestImpl; 504 friend class jit::JitCompiler; 505 friend class verifier::VerifierDepsTest; 506 friend class linker::Arm64RelativePatcherTest; 507 508 template <class Base> 509 friend bool ReadCompilerOptions(Base& map, CompilerOptions* options, std::string* error_msg); 510 511 DISALLOW_COPY_AND_ASSIGN(CompilerOptions); 512 }; 513 514 } // namespace art 515 516 #endif // ART_COMPILER_DRIVER_COMPILER_OPTIONS_H_ 517