Home | History | Annotate | Download | only in driver
      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 
     84   CompilerFilter::Filter GetCompilerFilter() const {
     85     return compiler_filter_;
     86   }
     87 
     88   void SetCompilerFilter(CompilerFilter::Filter compiler_filter) {
     89     compiler_filter_ = compiler_filter;
     90   }
     91 
     92   bool IsAotCompilationEnabled() const {
     93     return CompilerFilter::IsAotCompilationEnabled(compiler_filter_);
     94   }
     95 
     96   bool IsJniCompilationEnabled() const {
     97     return CompilerFilter::IsJniCompilationEnabled(compiler_filter_);
     98   }
     99 
    100   bool IsQuickeningCompilationEnabled() const {
    101     return CompilerFilter::IsQuickeningCompilationEnabled(compiler_filter_);
    102   }
    103 
    104   bool IsVerificationEnabled() const {
    105     return CompilerFilter::IsVerificationEnabled(compiler_filter_);
    106   }
    107 
    108   bool AssumeClassesAreVerified() const {
    109     return compiler_filter_ == CompilerFilter::kAssumeVerified;
    110   }
    111 
    112   bool VerifyAtRuntime() const {
    113     return compiler_filter_ == CompilerFilter::kExtract;
    114   }
    115 
    116   bool IsAnyCompilationEnabled() const {
    117     return CompilerFilter::IsAnyCompilationEnabled(compiler_filter_);
    118   }
    119 
    120   size_t GetHugeMethodThreshold() const {
    121     return huge_method_threshold_;
    122   }
    123 
    124   size_t GetLargeMethodThreshold() const {
    125     return large_method_threshold_;
    126   }
    127 
    128   size_t GetSmallMethodThreshold() const {
    129     return small_method_threshold_;
    130   }
    131 
    132   size_t GetTinyMethodThreshold() const {
    133     return tiny_method_threshold_;
    134   }
    135 
    136   bool IsHugeMethod(size_t num_dalvik_instructions) const {
    137     return num_dalvik_instructions > huge_method_threshold_;
    138   }
    139 
    140   bool IsLargeMethod(size_t num_dalvik_instructions) const {
    141     return num_dalvik_instructions > large_method_threshold_;
    142   }
    143 
    144   bool IsSmallMethod(size_t num_dalvik_instructions) const {
    145     return num_dalvik_instructions > small_method_threshold_;
    146   }
    147 
    148   bool IsTinyMethod(size_t num_dalvik_instructions) const {
    149     return num_dalvik_instructions > tiny_method_threshold_;
    150   }
    151 
    152   size_t GetNumDexMethodsThreshold() const {
    153     return num_dex_methods_threshold_;
    154   }
    155 
    156   size_t GetInlineMaxCodeUnits() const {
    157     return inline_max_code_units_;
    158   }
    159   void SetInlineMaxCodeUnits(size_t units) {
    160     inline_max_code_units_ = units;
    161   }
    162 
    163   double GetTopKProfileThreshold() const {
    164     return top_k_profile_threshold_;
    165   }
    166 
    167   bool GetDebuggable() const {
    168     return debuggable_;
    169   }
    170 
    171   void SetDebuggable(bool value) {
    172     debuggable_ = value;
    173   }
    174 
    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.
    181   bool GenerateAnyDebugInfo() const {
    182     return GetGenerateDebugInfo() || GetGenerateMiniDebugInfo();
    183   }
    184 
    185   bool GetGenerateDebugInfo() const {
    186     return generate_debug_info_;
    187   }
    188 
    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 
    196   bool GetGenerateBuildId() const {
    197     return generate_build_id_;
    198   }
    199 
    200   bool GetImplicitNullChecks() const {
    201     return implicit_null_checks_;
    202   }
    203 
    204   bool GetImplicitStackOverflowChecks() const {
    205     return implicit_so_checks_;
    206   }
    207 
    208   bool GetImplicitSuspendChecks() const {
    209     return implicit_suspend_checks_;
    210   }
    211 
    212   // Are we compiling a boot image?
    213   bool IsBootImage() const {
    214     return image_type_ == ImageType::kBootImage || image_type_ == ImageType::kApexBootImage;
    215   }
    216 
    217   bool IsApexBootImage() const {
    218     return image_type_ == ImageType::kApexBootImage;
    219   }
    220 
    221   bool IsBaseline() const {
    222     return baseline_;
    223   }
    224 
    225   // Are we compiling an app image?
    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.
    233   bool CompilingWithCoreImage() const {
    234     return compiling_with_core_image_;
    235   }
    236 
    237   // Should the code be compiled as position independent?
    238   bool GetCompilePic() const {
    239     return compile_pic_;
    240   }
    241 
    242   const ProfileCompilationInfo* GetProfileCompilationInfo() const {
    243     return profile_compilation_info_;
    244   }
    245 
    246   bool HasVerboseMethods() const {
    247     return !verbose_methods_.empty();
    248   }
    249 
    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 
    259   std::ostream* GetInitFailureOutput() const {
    260     return init_failure_output_.get();
    261   }
    262 
    263   bool AbortOnHardVerifierFailure() const {
    264     return abort_on_hard_verifier_failure_;
    265   }
    266   bool AbortOnSoftVerifierFailure() const {
    267     return abort_on_soft_verifier_failure_;
    268   }
    269 
    270   InstructionSet GetInstructionSet() const {
    271     return instruction_set_;
    272   }
    273 
    274   const InstructionSetFeatures* GetInstructionSetFeatures() const {
    275     return instruction_set_features_.get();
    276   }
    277 
    278 
    279   const std::vector<const DexFile*>& GetNoInlineFromDexFile() const {
    280     return no_inline_from_;
    281   }
    282 
    283   const std::vector<const DexFile*>& GetDexFilesForOatFile() const {
    284     return dex_files_for_oat_file_;
    285   }
    286 
    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 
    307   void SetNonPic() {
    308     compile_pic_ = false;
    309   }
    310 
    311   const std::string& GetDumpCfgFileName() const {
    312     return dump_cfg_file_name_;
    313   }
    314 
    315   bool GetDumpCfgAppend() const {
    316     return dump_cfg_append_;
    317   }
    318 
    319   bool IsForceDeterminism() const {
    320     return force_determinism_;
    321   }
    322 
    323   bool DeduplicateCode() const {
    324     return deduplicate_code_;
    325   }
    326 
    327   RegisterAllocator::Strategy GetRegisterAllocationStrategy() const {
    328     return register_allocation_strategy_;
    329   }
    330 
    331   const std::vector<std::string>* GetPassesToRun() const {
    332     return passes_to_run_;
    333   }
    334 
    335   bool GetDumpTimings() const {
    336     return dump_timings_;
    337   }
    338 
    339   bool GetDumpPassTimings() const {
    340     return dump_pass_timings_;
    341   }
    342 
    343   bool GetDumpStats() const {
    344     return dump_stats_;
    345   }
    346 
    347   bool CountHotnessInCompiledCode() const {
    348     return count_hotness_in_compiled_code_;
    349   }
    350 
    351   bool ResolveStartupConstStrings() const {
    352     return resolve_startup_const_strings_;
    353   }
    354 
    355   ProfileMethodsCheck CheckProfiledMethodsCompiled() const {
    356     return check_profiled_methods_;
    357   }
    358 
    359   uint32_t MaxImageBlockSize() const {
    360     return max_image_block_size_;
    361   }
    362 
    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