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