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 <ostream>
     21 #include <string>
     22 #include <vector>
     23 
     24 #include "base/macros.h"
     25 #include "compiler_filter.h"
     26 #include "globals.h"
     27 #include "optimizing/register_allocator.h"
     28 #include "utils.h"
     29 
     30 namespace art {
     31 
     32 namespace verifier {
     33   class VerifierDepsTest;
     34 }  // namespace verifier
     35 
     36 class DexFile;
     37 
     38 class CompilerOptions FINAL {
     39  public:
     40   // Guide heuristics to determine whether to compile method if profile data not available.
     41   static const size_t kDefaultHugeMethodThreshold = 10000;
     42   static const size_t kDefaultLargeMethodThreshold = 600;
     43   static const size_t kDefaultSmallMethodThreshold = 60;
     44   static const size_t kDefaultTinyMethodThreshold = 20;
     45   static const size_t kDefaultNumDexMethodsThreshold = 900;
     46   static constexpr double kDefaultTopKProfileThreshold = 90.0;
     47   static const bool kDefaultGenerateDebugInfo = false;
     48   static const bool kDefaultGenerateMiniDebugInfo = false;
     49   static const size_t kDefaultInlineMaxCodeUnits = 32;
     50   static constexpr size_t kUnsetInlineMaxCodeUnits = -1;
     51 
     52   CompilerOptions();
     53   ~CompilerOptions();
     54 
     55   CompilerFilter::Filter GetCompilerFilter() const {
     56     return compiler_filter_;
     57   }
     58 
     59   void SetCompilerFilter(CompilerFilter::Filter compiler_filter) {
     60     compiler_filter_ = compiler_filter;
     61   }
     62 
     63   bool IsAotCompilationEnabled() const {
     64     return CompilerFilter::IsAotCompilationEnabled(compiler_filter_);
     65   }
     66 
     67   bool IsJniCompilationEnabled() const {
     68     return CompilerFilter::IsJniCompilationEnabled(compiler_filter_);
     69   }
     70 
     71   bool IsQuickeningCompilationEnabled() const {
     72     return CompilerFilter::IsQuickeningCompilationEnabled(compiler_filter_);
     73   }
     74 
     75   bool IsVerificationEnabled() const {
     76     return CompilerFilter::IsVerificationEnabled(compiler_filter_);
     77   }
     78 
     79   bool AssumeClassesAreVerified() const {
     80     return compiler_filter_ == CompilerFilter::kAssumeVerified;
     81   }
     82 
     83   bool VerifyAtRuntime() const {
     84     return compiler_filter_ == CompilerFilter::kExtract;
     85   }
     86 
     87   bool IsAnyCompilationEnabled() const {
     88     return CompilerFilter::IsAnyCompilationEnabled(compiler_filter_);
     89   }
     90 
     91   size_t GetHugeMethodThreshold() const {
     92     return huge_method_threshold_;
     93   }
     94 
     95   size_t GetLargeMethodThreshold() const {
     96     return large_method_threshold_;
     97   }
     98 
     99   size_t GetSmallMethodThreshold() const {
    100     return small_method_threshold_;
    101   }
    102 
    103   size_t GetTinyMethodThreshold() const {
    104     return tiny_method_threshold_;
    105   }
    106 
    107   bool IsHugeMethod(size_t num_dalvik_instructions) const {
    108     return num_dalvik_instructions > huge_method_threshold_;
    109   }
    110 
    111   bool IsLargeMethod(size_t num_dalvik_instructions) const {
    112     return num_dalvik_instructions > large_method_threshold_;
    113   }
    114 
    115   bool IsSmallMethod(size_t num_dalvik_instructions) const {
    116     return num_dalvik_instructions > small_method_threshold_;
    117   }
    118 
    119   bool IsTinyMethod(size_t num_dalvik_instructions) const {
    120     return num_dalvik_instructions > tiny_method_threshold_;
    121   }
    122 
    123   size_t GetNumDexMethodsThreshold() const {
    124     return num_dex_methods_threshold_;
    125   }
    126 
    127   size_t GetInlineMaxCodeUnits() const {
    128     return inline_max_code_units_;
    129   }
    130   void SetInlineMaxCodeUnits(size_t units) {
    131     inline_max_code_units_ = units;
    132   }
    133 
    134   double GetTopKProfileThreshold() const {
    135     return top_k_profile_threshold_;
    136   }
    137 
    138   bool GetDebuggable() const {
    139     return debuggable_;
    140   }
    141 
    142   void SetDebuggable(bool value) {
    143     debuggable_ = value;
    144   }
    145 
    146   bool GetNativeDebuggable() const {
    147     return GetDebuggable() && GetGenerateDebugInfo();
    148   }
    149 
    150   // This flag controls whether the compiler collects debugging information.
    151   // The other flags control how the information is written to disk.
    152   bool GenerateAnyDebugInfo() const {
    153     return GetGenerateDebugInfo() || GetGenerateMiniDebugInfo();
    154   }
    155 
    156   bool GetGenerateDebugInfo() const {
    157     return generate_debug_info_;
    158   }
    159 
    160   bool GetGenerateMiniDebugInfo() const {
    161     return generate_mini_debug_info_;
    162   }
    163 
    164   bool GetGenerateBuildId() const {
    165     return generate_build_id_;
    166   }
    167 
    168   bool GetImplicitNullChecks() const {
    169     return implicit_null_checks_;
    170   }
    171 
    172   bool GetImplicitStackOverflowChecks() const {
    173     return implicit_so_checks_;
    174   }
    175 
    176   bool GetImplicitSuspendChecks() const {
    177     return implicit_suspend_checks_;
    178   }
    179 
    180   bool IsBootImage() const {
    181     return boot_image_;
    182   }
    183 
    184   bool IsAppImage() const {
    185     return app_image_;
    186   }
    187 
    188   void DisableAppImage() {
    189     app_image_ = false;
    190   }
    191 
    192   // Should the code be compiled as position independent?
    193   bool GetCompilePic() const {
    194     return compile_pic_;
    195   }
    196 
    197   bool HasVerboseMethods() const {
    198     return !verbose_methods_.empty();
    199   }
    200 
    201   bool IsVerboseMethod(const std::string& pretty_method) const {
    202     for (const std::string& cur_method : verbose_methods_) {
    203       if (pretty_method.find(cur_method) != std::string::npos) {
    204         return true;
    205       }
    206     }
    207     return false;
    208   }
    209 
    210   std::ostream* GetInitFailureOutput() const {
    211     return init_failure_output_.get();
    212   }
    213 
    214   bool AbortOnHardVerifierFailure() const {
    215     return abort_on_hard_verifier_failure_;
    216   }
    217 
    218   const std::vector<const DexFile*>* GetNoInlineFromDexFile() const {
    219     return no_inline_from_;
    220   }
    221 
    222   bool ParseCompilerOption(const StringPiece& option, UsageFn Usage);
    223 
    224   void SetNonPic() {
    225     compile_pic_ = false;
    226   }
    227 
    228   const std::string& GetDumpCfgFileName() const {
    229     return dump_cfg_file_name_;
    230   }
    231 
    232   bool GetDumpCfgAppend() const {
    233     return dump_cfg_append_;
    234   }
    235 
    236   bool IsForceDeterminism() const {
    237     return force_determinism_;
    238   }
    239 
    240   RegisterAllocator::Strategy GetRegisterAllocationStrategy() const {
    241     return register_allocation_strategy_;
    242   }
    243 
    244   const std::vector<std::string>* GetPassesToRun() const {
    245     return passes_to_run_;
    246   }
    247 
    248  private:
    249   void ParseDumpInitFailures(const StringPiece& option, UsageFn Usage);
    250   void ParseDumpCfgPasses(const StringPiece& option, UsageFn Usage);
    251   void ParseInlineMaxCodeUnits(const StringPiece& option, UsageFn Usage);
    252   void ParseNumDexMethods(const StringPiece& option, UsageFn Usage);
    253   void ParseTinyMethodMax(const StringPiece& option, UsageFn Usage);
    254   void ParseSmallMethodMax(const StringPiece& option, UsageFn Usage);
    255   void ParseLargeMethodMax(const StringPiece& option, UsageFn Usage);
    256   void ParseHugeMethodMax(const StringPiece& option, UsageFn Usage);
    257   void ParseRegisterAllocationStrategy(const StringPiece& option, UsageFn Usage);
    258 
    259   CompilerFilter::Filter compiler_filter_;
    260   size_t huge_method_threshold_;
    261   size_t large_method_threshold_;
    262   size_t small_method_threshold_;
    263   size_t tiny_method_threshold_;
    264   size_t num_dex_methods_threshold_;
    265   size_t inline_max_code_units_;
    266 
    267   // Dex files from which we should not inline code.
    268   // This is usually a very short list (i.e. a single dex file), so we
    269   // prefer vector<> over a lookup-oriented container, such as set<>.
    270   const std::vector<const DexFile*>* no_inline_from_;
    271 
    272   bool boot_image_;
    273   bool app_image_;
    274   // When using a profile file only the top K% of the profiled samples will be compiled.
    275   double top_k_profile_threshold_;
    276   bool debuggable_;
    277   bool generate_debug_info_;
    278   bool generate_mini_debug_info_;
    279   bool generate_build_id_;
    280   bool implicit_null_checks_;
    281   bool implicit_so_checks_;
    282   bool implicit_suspend_checks_;
    283   bool compile_pic_;
    284 
    285   // Vector of methods to have verbose output enabled for.
    286   std::vector<std::string> verbose_methods_;
    287 
    288   // Abort compilation with an error if we find a class that fails verification with a hard
    289   // failure.
    290   bool abort_on_hard_verifier_failure_;
    291 
    292   // Log initialization of initialization failures to this stream if not null.
    293   std::unique_ptr<std::ostream> init_failure_output_;
    294 
    295   std::string dump_cfg_file_name_;
    296   bool dump_cfg_append_;
    297 
    298   // Whether the compiler should trade performance for determinism to guarantee exactly reproducible
    299   // outcomes.
    300   bool force_determinism_;
    301 
    302   RegisterAllocator::Strategy register_allocation_strategy_;
    303 
    304   // If not null, specifies optimization passes which will be run instead of defaults.
    305   // Note that passes_to_run_ is not checked for correctness and providing an incorrect
    306   // list of passes can lead to unexpected compiler behaviour. This is caused by dependencies
    307   // between passes. Failing to satisfy them can for example lead to compiler crashes.
    308   // Passing pass names which are not recognized by the compiler will result in
    309   // compiler-dependant behavior.
    310   const std::vector<std::string>* passes_to_run_;
    311 
    312   friend class Dex2Oat;
    313   friend class DexToDexDecompilerTest;
    314   friend class CommonCompilerTest;
    315   friend class verifier::VerifierDepsTest;
    316 
    317   DISALLOW_COPY_AND_ASSIGN(CompilerOptions);
    318 };
    319 
    320 }  // namespace art
    321 
    322 #endif  // ART_COMPILER_DRIVER_COMPILER_OPTIONS_H_
    323