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 
GetCompilerFilter()79   CompilerFilter::Filter GetCompilerFilter() const {
80     return compiler_filter_;
81   }
82 
SetCompilerFilter(CompilerFilter::Filter compiler_filter)83   void SetCompilerFilter(CompilerFilter::Filter compiler_filter) {
84     compiler_filter_ = compiler_filter;
85   }
86 
IsAotCompilationEnabled()87   bool IsAotCompilationEnabled() const {
88     return CompilerFilter::IsAotCompilationEnabled(compiler_filter_);
89   }
90 
IsJniCompilationEnabled()91   bool IsJniCompilationEnabled() const {
92     return CompilerFilter::IsJniCompilationEnabled(compiler_filter_);
93   }
94 
IsQuickeningCompilationEnabled()95   bool IsQuickeningCompilationEnabled() const {
96     return CompilerFilter::IsQuickeningCompilationEnabled(compiler_filter_);
97   }
98 
IsVerificationEnabled()99   bool IsVerificationEnabled() const {
100     return CompilerFilter::IsVerificationEnabled(compiler_filter_);
101   }
102 
AssumeClassesAreVerified()103   bool AssumeClassesAreVerified() const {
104     return compiler_filter_ == CompilerFilter::kAssumeVerified;
105   }
106 
VerifyAtRuntime()107   bool VerifyAtRuntime() const {
108     return compiler_filter_ == CompilerFilter::kExtract;
109   }
110 
IsAnyCompilationEnabled()111   bool IsAnyCompilationEnabled() const {
112     return CompilerFilter::IsAnyCompilationEnabled(compiler_filter_);
113   }
114 
GetHugeMethodThreshold()115   size_t GetHugeMethodThreshold() const {
116     return huge_method_threshold_;
117   }
118 
GetLargeMethodThreshold()119   size_t GetLargeMethodThreshold() const {
120     return large_method_threshold_;
121   }
122 
GetSmallMethodThreshold()123   size_t GetSmallMethodThreshold() const {
124     return small_method_threshold_;
125   }
126 
GetTinyMethodThreshold()127   size_t GetTinyMethodThreshold() const {
128     return tiny_method_threshold_;
129   }
130 
IsHugeMethod(size_t num_dalvik_instructions)131   bool IsHugeMethod(size_t num_dalvik_instructions) const {
132     return num_dalvik_instructions > huge_method_threshold_;
133   }
134 
IsLargeMethod(size_t num_dalvik_instructions)135   bool IsLargeMethod(size_t num_dalvik_instructions) const {
136     return num_dalvik_instructions > large_method_threshold_;
137   }
138 
IsSmallMethod(size_t num_dalvik_instructions)139   bool IsSmallMethod(size_t num_dalvik_instructions) const {
140     return num_dalvik_instructions > small_method_threshold_;
141   }
142 
IsTinyMethod(size_t num_dalvik_instructions)143   bool IsTinyMethod(size_t num_dalvik_instructions) const {
144     return num_dalvik_instructions > tiny_method_threshold_;
145   }
146 
GetNumDexMethodsThreshold()147   size_t GetNumDexMethodsThreshold() const {
148     return num_dex_methods_threshold_;
149   }
150 
GetInlineMaxCodeUnits()151   size_t GetInlineMaxCodeUnits() const {
152     return inline_max_code_units_;
153   }
SetInlineMaxCodeUnits(size_t units)154   void SetInlineMaxCodeUnits(size_t units) {
155     inline_max_code_units_ = units;
156   }
157 
GetTopKProfileThreshold()158   double GetTopKProfileThreshold() const {
159     return top_k_profile_threshold_;
160   }
161 
GetDebuggable()162   bool GetDebuggable() const {
163     return debuggable_;
164   }
165 
GetNativeDebuggable()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.
GenerateAnyDebugInfo()172   bool GenerateAnyDebugInfo() const {
173     return GetGenerateDebugInfo() || GetGenerateMiniDebugInfo();
174   }
175 
GetGenerateDebugInfo()176   bool GetGenerateDebugInfo() const {
177     return generate_debug_info_;
178   }
179 
GetGenerateMiniDebugInfo()180   bool GetGenerateMiniDebugInfo() const {
181     return generate_mini_debug_info_;
182   }
183 
GetGenerateBuildId()184   bool GetGenerateBuildId() const {
185     return generate_build_id_;
186   }
187 
GetImplicitNullChecks()188   bool GetImplicitNullChecks() const {
189     return implicit_null_checks_;
190   }
191 
GetImplicitStackOverflowChecks()192   bool GetImplicitStackOverflowChecks() const {
193     return implicit_so_checks_;
194   }
195 
GetImplicitSuspendChecks()196   bool GetImplicitSuspendChecks() const {
197     return implicit_suspend_checks_;
198   }
199 
IsBootImage()200   bool IsBootImage() const {
201     return boot_image_;
202   }
203 
IsAppImage()204   bool IsAppImage() const {
205     return app_image_;
206   }
207 
208   // Should the code be compiled as position independent?
GetCompilePic()209   bool GetCompilePic() const {
210     return compile_pic_;
211   }
212 
HasVerboseMethods()213   bool HasVerboseMethods() const {
214     return verbose_methods_ != nullptr && !verbose_methods_->empty();
215   }
216 
IsVerboseMethod(const std::string & pretty_method)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 
GetInitFailureOutput()226   std::ostream* GetInitFailureOutput() const {
227     return init_failure_output_.get();
228   }
229 
AbortOnHardVerifierFailure()230   bool AbortOnHardVerifierFailure() const {
231     return abort_on_hard_verifier_failure_;
232   }
233 
GetNoInlineFromDexFile()234   const std::vector<const DexFile*>* GetNoInlineFromDexFile() const {
235     return no_inline_from_;
236   }
237 
238   bool ParseCompilerOption(const StringPiece& option, UsageFn Usage);
239 
GetDumpCfgFileName()240   const std::string& GetDumpCfgFileName() const {
241     return dump_cfg_file_name_;
242   }
243 
GetDumpCfgAppend()244   bool GetDumpCfgAppend() const {
245     return dump_cfg_append_;
246   }
247 
IsForceDeterminism()248   bool IsForceDeterminism() const {
249     return force_determinism_;
250   }
251 
GetRegisterAllocationStrategy()252   RegisterAllocator::Strategy GetRegisterAllocationStrategy() const {
253     return register_allocation_strategy_;
254   }
255 
GetPassesToRun()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