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 "utils.h"
     28 
     29 namespace art {
     30 
     31 class CompilerOptions FINAL {
     32  public:
     33   // Guide heuristics to determine whether to compile method if profile data not available.
     34   static const CompilerFilter::Filter kDefaultCompilerFilter = CompilerFilter::kSpeed;
     35   static const size_t kDefaultHugeMethodThreshold = 10000;
     36   static const size_t kDefaultLargeMethodThreshold = 600;
     37   static const size_t kDefaultSmallMethodThreshold = 60;
     38   static const size_t kDefaultTinyMethodThreshold = 20;
     39   static const size_t kDefaultNumDexMethodsThreshold = 900;
     40   static constexpr double kDefaultTopKProfileThreshold = 90.0;
     41   static const bool kDefaultGenerateDebugInfo = false;
     42   static const bool kDefaultGenerateMiniDebugInfo = false;
     43   static const bool kDefaultIncludePatchInformation = false;
     44   static const size_t kDefaultInlineDepthLimit = 3;
     45   static const size_t kDefaultInlineMaxCodeUnits = 32;
     46   static constexpr size_t kUnsetInlineDepthLimit = -1;
     47   static constexpr size_t kUnsetInlineMaxCodeUnits = -1;
     48 
     49   // Default inlining settings when the space filter is used.
     50   static constexpr size_t kSpaceFilterInlineDepthLimit = 3;
     51   static constexpr size_t kSpaceFilterInlineMaxCodeUnits = 10;
     52 
     53   CompilerOptions();
     54   ~CompilerOptions();
     55 
     56   CompilerOptions(CompilerFilter::Filter compiler_filter,
     57                   size_t huge_method_threshold,
     58                   size_t large_method_threshold,
     59                   size_t small_method_threshold,
     60                   size_t tiny_method_threshold,
     61                   size_t num_dex_methods_threshold,
     62                   size_t inline_depth_limit,
     63                   size_t inline_max_code_units,
     64                   const std::vector<const DexFile*>* no_inline_from,
     65                   bool include_patch_information,
     66                   double top_k_profile_threshold,
     67                   bool debuggable,
     68                   bool generate_debug_info,
     69                   bool implicit_null_checks,
     70                   bool implicit_so_checks,
     71                   bool implicit_suspend_checks,
     72                   bool compile_pic,
     73                   const std::vector<std::string>* verbose_methods,
     74                   std::ostream* init_failure_output,
     75                   bool abort_on_hard_verifier_failure,
     76                   const std::string& dump_cfg_file_name,
     77                   bool dump_cfg_append,
     78                   bool force_determinism);
     79 
     80   CompilerFilter::Filter GetCompilerFilter() const {
     81     return compiler_filter_;
     82   }
     83 
     84   void SetCompilerFilter(CompilerFilter::Filter compiler_filter) {
     85     compiler_filter_ = compiler_filter;
     86   }
     87 
     88   bool VerifyAtRuntime() const {
     89     return compiler_filter_ == CompilerFilter::kVerifyAtRuntime;
     90   }
     91 
     92   bool IsBytecodeCompilationEnabled() const {
     93     return CompilerFilter::IsBytecodeCompilationEnabled(compiler_filter_);
     94   }
     95 
     96   bool IsJniCompilationEnabled() const {
     97     return CompilerFilter::IsJniCompilationEnabled(compiler_filter_);
     98   }
     99 
    100   bool IsVerificationEnabled() const {
    101     return CompilerFilter::IsVerificationEnabled(compiler_filter_);
    102   }
    103 
    104   bool NeverVerify() const {
    105     return compiler_filter_ == CompilerFilter::kVerifyNone;
    106   }
    107 
    108   bool VerifyOnlyProfile() const {
    109     return compiler_filter_ == CompilerFilter::kVerifyProfile;
    110   }
    111 
    112   size_t GetHugeMethodThreshold() const {
    113     return huge_method_threshold_;
    114   }
    115 
    116   size_t GetLargeMethodThreshold() const {
    117     return large_method_threshold_;
    118   }
    119 
    120   size_t GetSmallMethodThreshold() const {
    121     return small_method_threshold_;
    122   }
    123 
    124   size_t GetTinyMethodThreshold() const {
    125     return tiny_method_threshold_;
    126   }
    127 
    128   bool IsHugeMethod(size_t num_dalvik_instructions) const {
    129     return num_dalvik_instructions > huge_method_threshold_;
    130   }
    131 
    132   bool IsLargeMethod(size_t num_dalvik_instructions) const {
    133     return num_dalvik_instructions > large_method_threshold_;
    134   }
    135 
    136   bool IsSmallMethod(size_t num_dalvik_instructions) const {
    137     return num_dalvik_instructions > small_method_threshold_;
    138   }
    139 
    140   bool IsTinyMethod(size_t num_dalvik_instructions) const {
    141     return num_dalvik_instructions > tiny_method_threshold_;
    142   }
    143 
    144   size_t GetNumDexMethodsThreshold() const {
    145     return num_dex_methods_threshold_;
    146   }
    147 
    148   size_t GetInlineDepthLimit() const {
    149     return inline_depth_limit_;
    150   }
    151   void SetInlineDepthLimit(size_t limit) {
    152     inline_depth_limit_ = limit;
    153   }
    154 
    155   size_t GetInlineMaxCodeUnits() const {
    156     return inline_max_code_units_;
    157   }
    158   void SetInlineMaxCodeUnits(size_t units) {
    159     inline_max_code_units_ = units;
    160   }
    161 
    162   double GetTopKProfileThreshold() const {
    163     return top_k_profile_threshold_;
    164   }
    165 
    166   bool GetDebuggable() const {
    167     return debuggable_;
    168   }
    169 
    170   bool GetNativeDebuggable() const {
    171     return GetDebuggable() && GetGenerateDebugInfo();
    172   }
    173 
    174   // This flag controls whether the compiler collects debugging information.
    175   // The other flags control how the information is written to disk.
    176   bool GenerateAnyDebugInfo() const {
    177     return GetGenerateDebugInfo() || GetGenerateMiniDebugInfo();
    178   }
    179 
    180   bool GetGenerateDebugInfo() const {
    181     return generate_debug_info_;
    182   }
    183 
    184   bool GetGenerateMiniDebugInfo() const {
    185     return generate_mini_debug_info_;
    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 GetIncludePatchInformation() const {
    201     return include_patch_information_;
    202   }
    203 
    204   // Should the code be compiled as position independent?
    205   bool GetCompilePic() const {
    206     return compile_pic_;
    207   }
    208 
    209   bool HasVerboseMethods() const {
    210     return verbose_methods_ != nullptr && !verbose_methods_->empty();
    211   }
    212 
    213   bool IsVerboseMethod(const std::string& pretty_method) const {
    214     for (const std::string& cur_method : *verbose_methods_) {
    215       if (pretty_method.find(cur_method) != std::string::npos) {
    216         return true;
    217       }
    218     }
    219     return false;
    220   }
    221 
    222   std::ostream* GetInitFailureOutput() const {
    223     return init_failure_output_.get();
    224   }
    225 
    226   bool AbortOnHardVerifierFailure() const {
    227     return abort_on_hard_verifier_failure_;
    228   }
    229 
    230   const std::vector<const DexFile*>* GetNoInlineFromDexFile() const {
    231     return no_inline_from_;
    232   }
    233 
    234   bool ParseCompilerOption(const StringPiece& option, UsageFn Usage);
    235 
    236   const std::string& GetDumpCfgFileName() const {
    237     return dump_cfg_file_name_;
    238   }
    239 
    240   bool GetDumpCfgAppend() const {
    241     return dump_cfg_append_;
    242   }
    243 
    244   bool IsForceDeterminism() const {
    245     return force_determinism_;
    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 ParseInlineDepthLimit(const StringPiece& option, UsageFn Usage);
    253   void ParseNumDexMethods(const StringPiece& option, UsageFn Usage);
    254   void ParseTinyMethodMax(const StringPiece& option, UsageFn Usage);
    255   void ParseSmallMethodMax(const StringPiece& option, UsageFn Usage);
    256   void ParseLargeMethodMax(const StringPiece& option, UsageFn Usage);
    257   void ParseHugeMethodMax(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_depth_limit_;
    266   size_t inline_max_code_units_;
    267 
    268   // Dex files from which we should not inline code.
    269   // This is usually a very short list (i.e. a single dex file), so we
    270   // prefer vector<> over a lookup-oriented container, such as set<>.
    271   const std::vector<const DexFile*>* no_inline_from_;
    272 
    273   bool include_patch_information_;
    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 implicit_null_checks_;
    280   bool implicit_so_checks_;
    281   bool implicit_suspend_checks_;
    282   bool compile_pic_;
    283 
    284   // Vector of methods to have verbose output enabled for.
    285   const std::vector<std::string>* verbose_methods_;
    286 
    287   // Abort compilation with an error if we find a class that fails verification with a hard
    288   // failure.
    289   bool abort_on_hard_verifier_failure_;
    290 
    291   // Log initialization of initialization failures to this stream if not null.
    292   std::unique_ptr<std::ostream> init_failure_output_;
    293 
    294   std::string dump_cfg_file_name_;
    295   bool dump_cfg_append_;
    296 
    297   // Whether the compiler should trade performance for determinism to guarantee exactly reproducable
    298   // outcomes.
    299   bool force_determinism_;
    300 
    301   friend class Dex2Oat;
    302 
    303   DISALLOW_COPY_AND_ASSIGN(CompilerOptions);
    304 };
    305 
    306 }  // namespace art
    307 
    308 #endif  // ART_COMPILER_DRIVER_COMPILER_OPTIONS_H_
    309