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