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 "globals.h"
26 
27 namespace art {
28 
29 class PassManagerOptions;
30 
31 class CompilerOptions FINAL {
32  public:
33   enum CompilerFilter {
34     kVerifyNone,          // Skip verification and compile nothing except JNI stubs.
35     kInterpretOnly,       // Verify, and compile only JNI stubs.
36     kVerifyAtRuntime,     // Only compile JNI stubs and verify at runtime.
37     kSpace,               // Maximize space savings.
38     kBalanced,            // Try to get the best performance return on compilation investment.
39     kSpeed,               // Maximize runtime performance.
40     kEverything,          // Force compilation of everything capable of being compiled.
41     kTime,                // Compile methods, but minimize compilation time.
42   };
43 
44   // Guide heuristics to determine whether to compile method if profile data not available.
45   static const CompilerFilter kDefaultCompilerFilter = kSpeed;
46   static const size_t kDefaultHugeMethodThreshold = 10000;
47   static const size_t kDefaultLargeMethodThreshold = 600;
48   static const size_t kDefaultSmallMethodThreshold = 60;
49   static const size_t kDefaultTinyMethodThreshold = 20;
50   static const size_t kDefaultNumDexMethodsThreshold = 900;
51   static constexpr double kDefaultTopKProfileThreshold = 90.0;
52   static const bool kDefaultGenerateDebugInfo = kIsDebugBuild;
53   static const bool kDefaultIncludePatchInformation = false;
54   static const size_t kDefaultInlineDepthLimit = 5;
55   static const size_t kDefaultInlineMaxCodeUnits = 100;
56 
57   // Default inlining settings when the space filter is used.
58   static constexpr size_t kSpaceFilterInlineDepthLimit = 5;
59   static constexpr size_t kSpaceFilterInlineMaxCodeUnits = 10;
60 
61   CompilerOptions();
62   ~CompilerOptions();
63 
64   CompilerOptions(CompilerFilter compiler_filter,
65                   size_t huge_method_threshold,
66                   size_t large_method_threshold,
67                   size_t small_method_threshold,
68                   size_t tiny_method_threshold,
69                   size_t num_dex_methods_threshold,
70                   size_t inline_depth_limit,
71                   size_t inline_max_code_units,
72                   bool include_patch_information,
73                   double top_k_profile_threshold,
74                   bool debuggable,
75                   bool generate_debug_info,
76                   bool implicit_null_checks,
77                   bool implicit_so_checks,
78                   bool implicit_suspend_checks,
79                   bool compile_pic,
80                   const std::vector<std::string>* verbose_methods,
81                   PassManagerOptions* pass_manager_options,
82                   std::ostream* init_failure_output,
83                   bool abort_on_hard_verifier_failure);
84 
GetCompilerFilter()85   CompilerFilter GetCompilerFilter() const {
86     return compiler_filter_;
87   }
88 
SetCompilerFilter(CompilerFilter compiler_filter)89   void SetCompilerFilter(CompilerFilter compiler_filter) {
90     compiler_filter_ = compiler_filter;
91   }
92 
VerifyAtRuntime()93   bool VerifyAtRuntime() const {
94     return compiler_filter_ == CompilerOptions::kVerifyAtRuntime;
95   }
96 
IsCompilationEnabled()97   bool IsCompilationEnabled() const {
98     return compiler_filter_ != CompilerOptions::kVerifyNone &&
99         compiler_filter_ != CompilerOptions::kInterpretOnly &&
100         compiler_filter_ != CompilerOptions::kVerifyAtRuntime;
101   }
102 
IsVerificationEnabled()103   bool IsVerificationEnabled() const {
104     return compiler_filter_ != CompilerOptions::kVerifyNone &&
105         compiler_filter_ != CompilerOptions::kVerifyAtRuntime;
106   }
107 
NeverVerify()108   bool NeverVerify() const {
109     return compiler_filter_ == CompilerOptions::kVerifyNone;
110   }
111 
GetHugeMethodThreshold()112   size_t GetHugeMethodThreshold() const {
113     return huge_method_threshold_;
114   }
115 
GetLargeMethodThreshold()116   size_t GetLargeMethodThreshold() const {
117     return large_method_threshold_;
118   }
119 
GetSmallMethodThreshold()120   size_t GetSmallMethodThreshold() const {
121     return small_method_threshold_;
122   }
123 
GetTinyMethodThreshold()124   size_t GetTinyMethodThreshold() const {
125     return tiny_method_threshold_;
126   }
127 
IsHugeMethod(size_t num_dalvik_instructions)128   bool IsHugeMethod(size_t num_dalvik_instructions) const {
129     return num_dalvik_instructions > huge_method_threshold_;
130   }
131 
IsLargeMethod(size_t num_dalvik_instructions)132   bool IsLargeMethod(size_t num_dalvik_instructions) const {
133     return num_dalvik_instructions > large_method_threshold_;
134   }
135 
IsSmallMethod(size_t num_dalvik_instructions)136   bool IsSmallMethod(size_t num_dalvik_instructions) const {
137     return num_dalvik_instructions > small_method_threshold_;
138   }
139 
IsTinyMethod(size_t num_dalvik_instructions)140   bool IsTinyMethod(size_t num_dalvik_instructions) const {
141     return num_dalvik_instructions > tiny_method_threshold_;
142   }
143 
GetNumDexMethodsThreshold()144   size_t GetNumDexMethodsThreshold() const {
145     return num_dex_methods_threshold_;
146   }
147 
GetInlineDepthLimit()148   size_t GetInlineDepthLimit() const {
149     return inline_depth_limit_;
150   }
151 
GetInlineMaxCodeUnits()152   size_t GetInlineMaxCodeUnits() const {
153     return inline_max_code_units_;
154   }
155 
GetTopKProfileThreshold()156   double GetTopKProfileThreshold() const {
157     return top_k_profile_threshold_;
158   }
159 
GetDebuggable()160   bool GetDebuggable() const {
161     return debuggable_;
162   }
163 
GetGenerateDebugInfo()164   bool GetGenerateDebugInfo() const {
165     return generate_debug_info_;
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 
GetIncludePatchInformation()180   bool GetIncludePatchInformation() const {
181     return include_patch_information_;
182   }
183 
184   // Should the code be compiled as position independent?
GetCompilePic()185   bool GetCompilePic() const {
186     return compile_pic_;
187   }
188 
HasVerboseMethods()189   bool HasVerboseMethods() const {
190     return verbose_methods_ != nullptr && !verbose_methods_->empty();
191   }
192 
IsVerboseMethod(const std::string & pretty_method)193   bool IsVerboseMethod(const std::string& pretty_method) const {
194     for (const std::string& cur_method : *verbose_methods_) {
195       if (pretty_method.find(cur_method) != std::string::npos) {
196         return true;
197       }
198     }
199     return false;
200   }
201 
GetInitFailureOutput()202   std::ostream* GetInitFailureOutput() const {
203     return init_failure_output_;
204   }
205 
GetPassManagerOptions()206   const PassManagerOptions* GetPassManagerOptions() const {
207     return pass_manager_options_.get();
208   }
209 
AbortOnHardVerifierFailure()210   bool AbortOnHardVerifierFailure() const {
211     return abort_on_hard_verifier_failure_;
212   }
213 
214  private:
215   CompilerFilter compiler_filter_;
216   const size_t huge_method_threshold_;
217   const size_t large_method_threshold_;
218   const size_t small_method_threshold_;
219   const size_t tiny_method_threshold_;
220   const size_t num_dex_methods_threshold_;
221   const size_t inline_depth_limit_;
222   const size_t inline_max_code_units_;
223   const bool include_patch_information_;
224   // When using a profile file only the top K% of the profiled samples will be compiled.
225   const double top_k_profile_threshold_;
226   const bool debuggable_;
227   const bool generate_debug_info_;
228   const bool implicit_null_checks_;
229   const bool implicit_so_checks_;
230   const bool implicit_suspend_checks_;
231   const bool compile_pic_;
232 
233   // Vector of methods to have verbose output enabled for.
234   const std::vector<std::string>* const verbose_methods_;
235 
236   std::unique_ptr<PassManagerOptions> pass_manager_options_;
237 
238   // Abort compilation with an error if we find a class that fails verification with a hard
239   // failure.
240   const bool abort_on_hard_verifier_failure_;
241 
242   // Log initialization of initialization failures to this stream if not null.
243   std::ostream* const init_failure_output_;
244 
245   DISALLOW_COPY_AND_ASSIGN(CompilerOptions);
246 };
247 std::ostream& operator<<(std::ostream& os, const CompilerOptions::CompilerFilter& rhs);
248 
249 }  // namespace art
250 
251 #endif  // ART_COMPILER_DRIVER_COMPILER_OPTIONS_H_
252