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