• 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 <memory>
21 #include <ostream>
22 #include <string>
23 #include <vector>
24 
25 #include "base/compiler_filter.h"
26 #include "base/globals.h"
27 #include "base/hash_set.h"
28 #include "base/macros.h"
29 #include "base/stl_util.h"
30 #include "base/utils.h"
31 #include "optimizing/register_allocator.h"
32 
33 namespace art HIDDEN {
34 
35 namespace jit {
36 class JitCompiler;
37 }  // namespace jit
38 
39 namespace verifier {
40 class VerifierDepsTest;
41 }  // namespace verifier
42 
43 namespace linker {
44 class Arm64RelativePatcherTest;
45 class Thumb2RelativePatcherTest;
46 }  // namespace linker
47 
48 class ArtMethod;
49 class DexFile;
50 enum class InstructionSet;
51 class InstructionSetFeatures;
52 class ProfileCompilationInfo;
53 
54 // Enum for CheckProfileMethodsCompiled. Outside CompilerOptions so it can be forward-declared.
55 enum class ProfileMethodsCheck : uint8_t {
56   kNone,
57   kLog,
58   kAbort,
59 };
60 
61 class CompilerOptions final {
62  public:
63   // Default values for parameters set via flags.
64   static constexpr bool kDefaultGenerateDebugInfo = false;
65   static constexpr bool kDefaultGenerateMiniDebugInfo = true;
66   static constexpr size_t kDefaultHugeMethodThreshold = 10000;
67   static constexpr size_t kDefaultInlineMaxCodeUnits = 32;
68   // Token to represent no value set for `inline_max_code_units_`.
69   static constexpr size_t kUnsetInlineMaxCodeUnits = -1;
70   // We set a lower inlining threshold for baseline to reduce code size and compilation time. This
71   // cannot be changed via flags.
72   static constexpr size_t kBaselineInlineMaxCodeUnits = 14;
73 
74   enum class CompilerType : uint8_t {
75     kAotCompiler,             // AOT compiler.
76     kJitCompiler,             // Normal JIT compiler.
77     kSharedCodeJitCompiler,   // Zygote JIT producing code in the shared region area, putting
78                               // restrictions on, for example, how literals are being generated.
79   };
80 
81   enum class ImageType : uint8_t {
82     kNone,                    // JIT or AOT app compilation producing only an oat file but no image.
83     kBootImage,               // Creating boot image.
84     kBootImageExtension,      // Creating boot image extension.
85     kAppImage,                // Creating app image.
86   };
87 
88   EXPORT CompilerOptions();
89   EXPORT ~CompilerOptions();
90 
GetCompilerFilter()91   CompilerFilter::Filter GetCompilerFilter() const {
92     return compiler_filter_;
93   }
94 
SetCompilerFilter(CompilerFilter::Filter compiler_filter)95   void SetCompilerFilter(CompilerFilter::Filter compiler_filter) {
96     compiler_filter_ = compiler_filter;
97   }
98 
IsAotCompilationEnabled()99   bool IsAotCompilationEnabled() const {
100     return CompilerFilter::IsAotCompilationEnabled(compiler_filter_);
101   }
102 
IsJniCompilationEnabled()103   bool IsJniCompilationEnabled() const {
104 #ifdef ART_USE_RESTRICTED_MODE
105     // TODO(Simulator): Support JNICompiler.
106     // Without the JNI compiler, GenericJNITrampoline will be used for JNI calls.
107     return false;
108 #else
109     return CompilerFilter::IsJniCompilationEnabled(compiler_filter_);
110 #endif
111   }
112 
IsVerificationEnabled()113   bool IsVerificationEnabled() const {
114     return CompilerFilter::IsVerificationEnabled(compiler_filter_);
115   }
116 
AssumeDexFilesAreVerified()117   bool AssumeDexFilesAreVerified() const {
118     return compiler_filter_ == CompilerFilter::kAssumeVerified;
119   }
120 
AssumeClassesAreVerified()121   bool AssumeClassesAreVerified() const {
122     return compiler_filter_ == CompilerFilter::kAssumeVerified;
123   }
124 
IsAnyCompilationEnabled()125   bool IsAnyCompilationEnabled() const {
126     return CompilerFilter::IsAnyCompilationEnabled(compiler_filter_);
127   }
128 
GetHugeMethodThreshold()129   size_t GetHugeMethodThreshold() const {
130     return huge_method_threshold_;
131   }
132 
IsHugeMethod(size_t num_dalvik_instructions)133   bool IsHugeMethod(size_t num_dalvik_instructions) const {
134     return num_dalvik_instructions > huge_method_threshold_;
135   }
136 
GetInlineMaxCodeUnits()137   size_t GetInlineMaxCodeUnits() const {
138     return inline_max_code_units_;
139   }
SetInlineMaxCodeUnits(size_t units)140   void SetInlineMaxCodeUnits(size_t units) {
141     inline_max_code_units_ = units;
142   }
143 
EmitReadBarrier()144   bool EmitReadBarrier() const {
145     return emit_read_barrier_;
146   }
147 
GetDebuggable()148   bool GetDebuggable() const {
149     return debuggable_;
150   }
151 
SetDebuggable(bool value)152   void SetDebuggable(bool value) {
153     debuggable_ = value;
154   }
155 
GetNativeDebuggable()156   bool GetNativeDebuggable() const {
157     return GetDebuggable() && GetGenerateDebugInfo();
158   }
159 
160   // This flag controls whether the compiler collects debugging information.
161   // The other flags control how the information is written to disk.
GenerateAnyDebugInfo()162   bool GenerateAnyDebugInfo() const {
163     return GetGenerateDebugInfo() || GetGenerateMiniDebugInfo();
164   }
165 
GetGenerateDebugInfo()166   bool GetGenerateDebugInfo() const {
167     return generate_debug_info_;
168   }
169 
GetGenerateMiniDebugInfo()170   bool GetGenerateMiniDebugInfo() const {
171     return generate_mini_debug_info_;
172   }
173 
174   // Should run-time checks be emitted in debug mode?
175   bool EmitRunTimeChecksInDebugMode() const;
176 
GetGenerateBuildId()177   bool GetGenerateBuildId() const {
178     return generate_build_id_;
179   }
180 
GetImplicitNullChecks()181   bool GetImplicitNullChecks() const {
182     return implicit_null_checks_;
183   }
184 
GetImplicitStackOverflowChecks()185   bool GetImplicitStackOverflowChecks() const {
186     return implicit_so_checks_;
187   }
188 
IsAotCompiler()189   bool IsAotCompiler() const {
190     return compiler_type_ == CompilerType::kAotCompiler;
191   }
192 
IsJitCompiler()193   bool IsJitCompiler() const {
194     return compiler_type_ == CompilerType::kJitCompiler ||
195            compiler_type_ == CompilerType::kSharedCodeJitCompiler;
196   }
197 
IsJitCompilerForSharedCode()198   bool IsJitCompilerForSharedCode() const {
199     return compiler_type_ == CompilerType::kSharedCodeJitCompiler;
200   }
201 
GetImplicitSuspendChecks()202   bool GetImplicitSuspendChecks() const {
203     return implicit_suspend_checks_;
204   }
205 
IsGeneratingImage()206   bool IsGeneratingImage() const {
207     return IsBootImage() || IsBootImageExtension() || IsAppImage();
208   }
209 
210   // Are we compiling a boot image?
IsBootImage()211   bool IsBootImage() const {
212     return image_type_ == ImageType::kBootImage;
213   }
214 
215   // Are we compiling a boot image extension?
IsBootImageExtension()216   bool IsBootImageExtension() const {
217     return image_type_ == ImageType::kBootImageExtension;
218   }
219 
IsBaseline()220   bool IsBaseline() const {
221     return baseline_;
222   }
223 
ProfileBranches()224   bool ProfileBranches() const {
225     return profile_branches_;
226   }
227 
228   // Are we compiling an app image?
IsAppImage()229   bool IsAppImage() const {
230     return image_type_ == ImageType::kAppImage;
231   }
232 
IsMultiImage()233   bool IsMultiImage() const {
234     return multi_image_;
235   }
236 
237   // Returns whether we are running ART tests.
238   // The compiler will use that information for checking invariants.
CompileArtTest()239   bool CompileArtTest() const {
240     return compile_art_test_;
241   }
242 
243   // Should the code be compiled as position independent?
GetCompilePic()244   bool GetCompilePic() const {
245     return compile_pic_;
246   }
247 
GetProfileCompilationInfo()248   const ProfileCompilationInfo* GetProfileCompilationInfo() const {
249     return profile_compilation_info_;
250   }
251 
HasVerboseMethods()252   bool HasVerboseMethods() const {
253     return !verbose_methods_.empty();
254   }
255 
IsVerboseMethod(const std::string & pretty_method)256   bool IsVerboseMethod(const std::string& pretty_method) const {
257     for (const std::string& cur_method : verbose_methods_) {
258       if (pretty_method.find(cur_method) != std::string::npos) {
259         return true;
260       }
261     }
262     return false;
263   }
264 
GetInitFailureOutput()265   std::ostream* GetInitFailureOutput() const {
266     return init_failure_output_.get();
267   }
268 
AbortOnHardVerifierFailure()269   bool AbortOnHardVerifierFailure() const {
270     return abort_on_hard_verifier_failure_;
271   }
AbortOnSoftVerifierFailure()272   bool AbortOnSoftVerifierFailure() const {
273     return abort_on_soft_verifier_failure_;
274   }
275 
GetInstructionSet()276   InstructionSet GetInstructionSet() const {
277     return instruction_set_;
278   }
279 
GetInstructionSetFeatures()280   const InstructionSetFeatures* GetInstructionSetFeatures() const {
281     return instruction_set_features_.get();
282   }
283 
284 
GetNoInlineFromDexFile()285   const std::vector<const DexFile*>& GetNoInlineFromDexFile() const {
286     return no_inline_from_;
287   }
288 
GetDexFilesForOatFile()289   const std::vector<const DexFile*>& GetDexFilesForOatFile() const {
290     return dex_files_for_oat_file_;
291   }
292 
GetImageClasses()293   const HashSet<std::string>& GetImageClasses() const {
294     return image_classes_;
295   }
296 
297   EXPORT bool IsImageClass(const char* descriptor) const;
298 
299   // Returns whether the given `pretty_descriptor` is in the list of preloaded
300   // classes. `pretty_descriptor` should be the result of calling `PrettyDescriptor`.
301   EXPORT bool IsPreloadedClass(std::string_view pretty_descriptor) const;
302 
303   bool ParseCompilerOptions(const std::vector<std::string>& options,
304                             bool ignore_unrecognized,
305                             std::string* error_msg);
306 
SetNonPic()307   void SetNonPic() {
308     compile_pic_ = false;
309   }
310 
GetDumpCfgFileName()311   const std::string& GetDumpCfgFileName() const {
312     return dump_cfg_file_name_;
313   }
314 
GetDumpCfgAppend()315   bool GetDumpCfgAppend() const {
316     return dump_cfg_append_;
317   }
318 
IsForceDeterminism()319   bool IsForceDeterminism() const {
320     return force_determinism_;
321   }
322 
IsCheckLinkageConditions()323   bool IsCheckLinkageConditions() const {
324     return check_linkage_conditions_;
325   }
326 
IsCrashOnLinkageViolation()327   bool IsCrashOnLinkageViolation() const {
328     return crash_on_linkage_violation_;
329   }
330 
DeduplicateCode()331   bool DeduplicateCode() const {
332     return deduplicate_code_;
333   }
334 
GetPassesToRun()335   const std::vector<std::string>* GetPassesToRun() const {
336     return passes_to_run_;
337   }
338 
GetDumpTimings()339   bool GetDumpTimings() const {
340     return dump_timings_;
341   }
342 
GetDumpPassTimings()343   bool GetDumpPassTimings() const {
344     return dump_pass_timings_;
345   }
346 
GetDumpStats()347   bool GetDumpStats() const {
348     return dump_stats_;
349   }
350 
CountHotnessInCompiledCode()351   bool CountHotnessInCompiledCode() const {
352     return count_hotness_in_compiled_code_;
353   }
354 
ResolveStartupConstStrings()355   bool ResolveStartupConstStrings() const {
356     return resolve_startup_const_strings_;
357   }
358 
CheckProfiledMethodsCompiled()359   ProfileMethodsCheck CheckProfiledMethodsCompiled() const {
360     return check_profiled_methods_;
361   }
362 
MaxImageBlockSize()363   uint32_t MaxImageBlockSize() const {
364     return max_image_block_size_;
365   }
366 
SetMaxImageBlockSize(uint32_t size)367   void SetMaxImageBlockSize(uint32_t size) {
368     max_image_block_size_ = size;
369   }
370 
InitializeAppImageClasses()371   bool InitializeAppImageClasses() const {
372     return initialize_app_image_classes_;
373   }
374 
375   // Returns true if `dex_file` is within an oat file we're producing right now.
WithinOatFile(const DexFile * dex_file)376   bool WithinOatFile(const DexFile* dex_file) const {
377     return ContainsElement(GetDexFilesForOatFile(), dex_file);
378   }
379 
380   // If this is a static non-constructor method in the boot classpath, and its class isn't
381   // initialized at compile-time, or won't be initialized by the zygote, add
382   // initialization checks at entry. This will avoid the need of trampolines
383   // which at runtime we will need to dirty after initialization.
384   EXPORT bool ShouldCompileWithClinitCheck(ArtMethod* method) const;
385 
386  private:
387   EXPORT bool ParseDumpInitFailures(const std::string& option, std::string* error_msg);
388 
389   CompilerFilter::Filter compiler_filter_;
390   size_t huge_method_threshold_;
391   size_t inline_max_code_units_;
392 
393   InstructionSet instruction_set_;
394   std::unique_ptr<const InstructionSetFeatures> instruction_set_features_;
395 
396   // Dex files from which we should not inline code. Does not own the dex files.
397   // This is usually a very short list (i.e. a single dex file), so we
398   // prefer vector<> over a lookup-oriented container, such as set<>.
399   std::vector<const DexFile*> no_inline_from_;
400 
401   // List of dex files associated with the oat file, empty for JIT.
402   std::vector<const DexFile*> dex_files_for_oat_file_;
403 
404   // Image classes, specifies the classes that will be included in the image if creating an image.
405   // Must not be empty for real boot image, only for tests pretending to compile boot image.
406   HashSet<std::string> image_classes_;
407 
408   // Classes listed in the preloaded-classes file, used for boot image and
409   // boot image extension compilation.
410   HashSet<std::string> preloaded_classes_;
411 
412   CompilerType compiler_type_;
413   ImageType image_type_;
414   bool multi_image_;
415   bool compile_art_test_;
416   bool emit_read_barrier_;
417   bool baseline_;
418   bool debuggable_;
419   bool generate_debug_info_;
420   bool generate_mini_debug_info_;
421   bool generate_build_id_;
422   bool implicit_null_checks_;
423   bool implicit_so_checks_;
424   bool implicit_suspend_checks_;
425   bool compile_pic_;
426   bool dump_timings_;
427   bool dump_pass_timings_;
428   bool dump_stats_;
429   bool profile_branches_;
430 
431   // Info for profile guided compilation.
432   const ProfileCompilationInfo* profile_compilation_info_;
433 
434   // Vector of methods to have verbose output enabled for.
435   std::vector<std::string> verbose_methods_;
436 
437   // Abort compilation with an error if we find a class that fails verification with a hard
438   // failure.
439   bool abort_on_hard_verifier_failure_;
440   // Same for soft failures.
441   bool abort_on_soft_verifier_failure_;
442 
443   // Log initialization of initialization failures to this stream if not null.
444   std::unique_ptr<std::ostream> init_failure_output_;
445 
446   std::string dump_cfg_file_name_;
447   bool dump_cfg_append_;
448 
449   // Whether the compiler should trade performance for determinism to guarantee exactly reproducible
450   // outcomes.
451   bool force_determinism_;
452 
453   // Whether the compiler should check for violation of the conditions required to perform AOT
454   // "linkage".
455   bool check_linkage_conditions_;
456   // Whether the compiler should crash when encountering a violation of one of
457   // the conditions required to perform AOT "linkage".
458   bool crash_on_linkage_violation_;
459 
460   // Whether code should be deduplicated.
461   bool deduplicate_code_;
462 
463   // Whether compiled code should increment the hotness count of ArtMethod. Note that the increments
464   // won't be atomic for performance reasons, so we accept races, just like in interpreter.
465   bool count_hotness_in_compiled_code_;
466 
467   // Whether we eagerly resolve all of the const strings that are loaded from startup methods in the
468   // profile.
469   bool resolve_startup_const_strings_;
470 
471   // Whether we attempt to run class initializers for app image classes.
472   bool initialize_app_image_classes_;
473 
474   // When running profile-guided compilation, check that methods intended to be compiled end
475   // up compiled and are not punted.
476   ProfileMethodsCheck check_profiled_methods_;
477 
478   // Maximum solid block size in the generated image.
479   uint32_t max_image_block_size_;
480 
481   // If not null, specifies optimization passes which will be run instead of defaults.
482   // Note that passes_to_run_ is not checked for correctness and providing an incorrect
483   // list of passes can lead to unexpected compiler behaviour. This is caused by dependencies
484   // between passes. Failing to satisfy them can for example lead to compiler crashes.
485   // Passing pass names which are not recognized by the compiler will result in
486   // compiler-dependant behavior.
487   const std::vector<std::string>* passes_to_run_;
488 
489   friend class Dex2Oat;
490   friend class CommonCompilerDriverTest;
491   friend class CommonCompilerTestImpl;
492   friend class jit::JitCompiler;
493   friend class verifier::VerifierDepsTest;
494   friend class linker::Arm64RelativePatcherTest;
495   friend class linker::Thumb2RelativePatcherTest;
496 
497   template <class Base>
498   friend bool ReadCompilerOptions(Base& map, CompilerOptions* options, std::string* error_msg);
499 
500   DISALLOW_COPY_AND_ASSIGN(CompilerOptions);
501 };
502 
503 }  // namespace art
504 
505 #endif  // ART_COMPILER_DRIVER_COMPILER_OPTIONS_H_
506