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
29namespace art {
30
31class 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