• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
GetCompilerFilter()55   CompilerFilter::Filter GetCompilerFilter() const {
56     return compiler_filter_;
57   }
58 
SetCompilerFilter(CompilerFilter::Filter compiler_filter)59   void SetCompilerFilter(CompilerFilter::Filter compiler_filter) {
60     compiler_filter_ = compiler_filter;
61   }
62 
IsAotCompilationEnabled()63   bool IsAotCompilationEnabled() const {
64     return CompilerFilter::IsAotCompilationEnabled(compiler_filter_);
65   }
66 
IsJniCompilationEnabled()67   bool IsJniCompilationEnabled() const {
68     return CompilerFilter::IsJniCompilationEnabled(compiler_filter_);
69   }
70 
IsQuickeningCompilationEnabled()71   bool IsQuickeningCompilationEnabled() const {
72     return CompilerFilter::IsQuickeningCompilationEnabled(compiler_filter_);
73   }
74 
IsVerificationEnabled()75   bool IsVerificationEnabled() const {
76     return CompilerFilter::IsVerificationEnabled(compiler_filter_);
77   }
78 
AssumeClassesAreVerified()79   bool AssumeClassesAreVerified() const {
80     return compiler_filter_ == CompilerFilter::kAssumeVerified;
81   }
82 
VerifyAtRuntime()83   bool VerifyAtRuntime() const {
84     return compiler_filter_ == CompilerFilter::kExtract;
85   }
86 
IsAnyCompilationEnabled()87   bool IsAnyCompilationEnabled() const {
88     return CompilerFilter::IsAnyCompilationEnabled(compiler_filter_);
89   }
90 
GetHugeMethodThreshold()91   size_t GetHugeMethodThreshold() const {
92     return huge_method_threshold_;
93   }
94 
GetLargeMethodThreshold()95   size_t GetLargeMethodThreshold() const {
96     return large_method_threshold_;
97   }
98 
GetSmallMethodThreshold()99   size_t GetSmallMethodThreshold() const {
100     return small_method_threshold_;
101   }
102 
GetTinyMethodThreshold()103   size_t GetTinyMethodThreshold() const {
104     return tiny_method_threshold_;
105   }
106 
IsHugeMethod(size_t num_dalvik_instructions)107   bool IsHugeMethod(size_t num_dalvik_instructions) const {
108     return num_dalvik_instructions > huge_method_threshold_;
109   }
110 
IsLargeMethod(size_t num_dalvik_instructions)111   bool IsLargeMethod(size_t num_dalvik_instructions) const {
112     return num_dalvik_instructions > large_method_threshold_;
113   }
114 
IsSmallMethod(size_t num_dalvik_instructions)115   bool IsSmallMethod(size_t num_dalvik_instructions) const {
116     return num_dalvik_instructions > small_method_threshold_;
117   }
118 
IsTinyMethod(size_t num_dalvik_instructions)119   bool IsTinyMethod(size_t num_dalvik_instructions) const {
120     return num_dalvik_instructions > tiny_method_threshold_;
121   }
122 
GetNumDexMethodsThreshold()123   size_t GetNumDexMethodsThreshold() const {
124     return num_dex_methods_threshold_;
125   }
126 
GetInlineMaxCodeUnits()127   size_t GetInlineMaxCodeUnits() const {
128     return inline_max_code_units_;
129   }
SetInlineMaxCodeUnits(size_t units)130   void SetInlineMaxCodeUnits(size_t units) {
131     inline_max_code_units_ = units;
132   }
133 
GetTopKProfileThreshold()134   double GetTopKProfileThreshold() const {
135     return top_k_profile_threshold_;
136   }
137 
GetDebuggable()138   bool GetDebuggable() const {
139     return debuggable_;
140   }
141 
SetDebuggable(bool value)142   void SetDebuggable(bool value) {
143     debuggable_ = value;
144   }
145 
GetNativeDebuggable()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.
GenerateAnyDebugInfo()152   bool GenerateAnyDebugInfo() const {
153     return GetGenerateDebugInfo() || GetGenerateMiniDebugInfo();
154   }
155 
GetGenerateDebugInfo()156   bool GetGenerateDebugInfo() const {
157     return generate_debug_info_;
158   }
159 
GetGenerateMiniDebugInfo()160   bool GetGenerateMiniDebugInfo() const {
161     return generate_mini_debug_info_;
162   }
163 
GetGenerateBuildId()164   bool GetGenerateBuildId() const {
165     return generate_build_id_;
166   }
167 
GetImplicitNullChecks()168   bool GetImplicitNullChecks() const {
169     return implicit_null_checks_;
170   }
171 
GetImplicitStackOverflowChecks()172   bool GetImplicitStackOverflowChecks() const {
173     return implicit_so_checks_;
174   }
175 
GetImplicitSuspendChecks()176   bool GetImplicitSuspendChecks() const {
177     return implicit_suspend_checks_;
178   }
179 
IsBootImage()180   bool IsBootImage() const {
181     return boot_image_;
182   }
183 
IsAppImage()184   bool IsAppImage() const {
185     return app_image_;
186   }
187 
DisableAppImage()188   void DisableAppImage() {
189     app_image_ = false;
190   }
191 
192   // Should the code be compiled as position independent?
GetCompilePic()193   bool GetCompilePic() const {
194     return compile_pic_;
195   }
196 
HasVerboseMethods()197   bool HasVerboseMethods() const {
198     return !verbose_methods_.empty();
199   }
200 
IsVerboseMethod(const std::string & pretty_method)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 
GetInitFailureOutput()210   std::ostream* GetInitFailureOutput() const {
211     return init_failure_output_.get();
212   }
213 
AbortOnHardVerifierFailure()214   bool AbortOnHardVerifierFailure() const {
215     return abort_on_hard_verifier_failure_;
216   }
217 
GetNoInlineFromDexFile()218   const std::vector<const DexFile*>* GetNoInlineFromDexFile() const {
219     return no_inline_from_;
220   }
221 
222   bool ParseCompilerOption(const StringPiece& option, UsageFn Usage);
223 
SetNonPic()224   void SetNonPic() {
225     compile_pic_ = false;
226   }
227 
GetDumpCfgFileName()228   const std::string& GetDumpCfgFileName() const {
229     return dump_cfg_file_name_;
230   }
231 
GetDumpCfgAppend()232   bool GetDumpCfgAppend() const {
233     return dump_cfg_append_;
234   }
235 
IsForceDeterminism()236   bool IsForceDeterminism() const {
237     return force_determinism_;
238   }
239 
GetRegisterAllocationStrategy()240   RegisterAllocator::Strategy GetRegisterAllocationStrategy() const {
241     return register_allocation_strategy_;
242   }
243 
GetPassesToRun()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