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