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