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