/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ART_COMPILER_DRIVER_COMPILER_OPTIONS_H_
#define ART_COMPILER_DRIVER_COMPILER_OPTIONS_H_

#include <memory>
#include <ostream>
#include <string>
#include <vector>

#include "base/globals.h"
#include "base/hash_set.h"
#include "base/macros.h"
#include "base/utils.h"
#include "compiler_filter.h"
#include "optimizing/register_allocator.h"

namespace art {

namespace jit {
class JitCompiler;
}  // namespace jit

namespace verifier {
class VerifierDepsTest;
}  // namespace verifier

namespace linker {
class Arm64RelativePatcherTest;
}  // namespace linker

class DexFile;
enum class InstructionSet;
class InstructionSetFeatures;
class ProfileCompilationInfo;
class VerificationResults;
class VerifiedMethod;

// Enum for CheckProfileMethodsCompiled. Outside CompilerOptions so it can be forward-declared.
enum class ProfileMethodsCheck : uint8_t {
  kNone,
  kLog,
  kAbort,
};

class CompilerOptions final {
 public:
  // Guide heuristics to determine whether to compile method if profile data not available.
  static const size_t kDefaultHugeMethodThreshold = 10000;
  static const size_t kDefaultLargeMethodThreshold = 600;
  static const size_t kDefaultSmallMethodThreshold = 60;
  static const size_t kDefaultTinyMethodThreshold = 20;
  static const size_t kDefaultNumDexMethodsThreshold = 900;
  static constexpr double kDefaultTopKProfileThreshold = 90.0;
  static const bool kDefaultGenerateDebugInfo = false;
  static const bool kDefaultGenerateMiniDebugInfo = false;
  static const size_t kDefaultInlineMaxCodeUnits = 32;
  static constexpr size_t kUnsetInlineMaxCodeUnits = -1;

  enum class ImageType : uint8_t {
    kNone,                // JIT or AOT app compilation producing only an oat file but no image.
    kBootImage,           // Creating boot image.
    kAppImage,            // Creating app image.
    kApexBootImage,       // Creating the apex image for jit/zygote experiment b/119800099.
  };

  CompilerOptions();
  ~CompilerOptions();

  CompilerFilter::Filter GetCompilerFilter() const {
    return compiler_filter_;
  }

  void SetCompilerFilter(CompilerFilter::Filter compiler_filter) {
    compiler_filter_ = compiler_filter;
  }

  bool IsAotCompilationEnabled() const {
    return CompilerFilter::IsAotCompilationEnabled(compiler_filter_);
  }

  bool IsJniCompilationEnabled() const {
    return CompilerFilter::IsJniCompilationEnabled(compiler_filter_);
  }

  bool IsQuickeningCompilationEnabled() const {
    return CompilerFilter::IsQuickeningCompilationEnabled(compiler_filter_);
  }

  bool IsVerificationEnabled() const {
    return CompilerFilter::IsVerificationEnabled(compiler_filter_);
  }

  bool AssumeClassesAreVerified() const {
    return compiler_filter_ == CompilerFilter::kAssumeVerified;
  }

  bool VerifyAtRuntime() const {
    return compiler_filter_ == CompilerFilter::kExtract;
  }

  bool IsAnyCompilationEnabled() const {
    return CompilerFilter::IsAnyCompilationEnabled(compiler_filter_);
  }

  size_t GetHugeMethodThreshold() const {
    return huge_method_threshold_;
  }

  size_t GetLargeMethodThreshold() const {
    return large_method_threshold_;
  }

  size_t GetSmallMethodThreshold() const {
    return small_method_threshold_;
  }

  size_t GetTinyMethodThreshold() const {
    return tiny_method_threshold_;
  }

  bool IsHugeMethod(size_t num_dalvik_instructions) const {
    return num_dalvik_instructions > huge_method_threshold_;
  }

  bool IsLargeMethod(size_t num_dalvik_instructions) const {
    return num_dalvik_instructions > large_method_threshold_;
  }

  bool IsSmallMethod(size_t num_dalvik_instructions) const {
    return num_dalvik_instructions > small_method_threshold_;
  }

  bool IsTinyMethod(size_t num_dalvik_instructions) const {
    return num_dalvik_instructions > tiny_method_threshold_;
  }

  size_t GetNumDexMethodsThreshold() const {
    return num_dex_methods_threshold_;
  }

  size_t GetInlineMaxCodeUnits() const {
    return inline_max_code_units_;
  }
  void SetInlineMaxCodeUnits(size_t units) {
    inline_max_code_units_ = units;
  }

  double GetTopKProfileThreshold() const {
    return top_k_profile_threshold_;
  }

  bool GetDebuggable() const {
    return debuggable_;
  }

  void SetDebuggable(bool value) {
    debuggable_ = value;
  }

  bool GetNativeDebuggable() const {
    return GetDebuggable() && GetGenerateDebugInfo();
  }

  // This flag controls whether the compiler collects debugging information.
  // The other flags control how the information is written to disk.
  bool GenerateAnyDebugInfo() const {
    return GetGenerateDebugInfo() || GetGenerateMiniDebugInfo();
  }

  bool GetGenerateDebugInfo() const {
    return generate_debug_info_;
  }

  bool GetGenerateMiniDebugInfo() const {
    return generate_mini_debug_info_;
  }

  // Should run-time checks be emitted in debug mode?
  bool EmitRunTimeChecksInDebugMode() const;

  bool GetGenerateBuildId() const {
    return generate_build_id_;
  }

  bool GetImplicitNullChecks() const {
    return implicit_null_checks_;
  }

  bool GetImplicitStackOverflowChecks() const {
    return implicit_so_checks_;
  }

  bool GetImplicitSuspendChecks() const {
    return implicit_suspend_checks_;
  }

  // Are we compiling a boot image?
  bool IsBootImage() const {
    return image_type_ == ImageType::kBootImage || image_type_ == ImageType::kApexBootImage;
  }

  bool IsApexBootImage() const {
    return image_type_ == ImageType::kApexBootImage;
  }

  bool IsBaseline() const {
    return baseline_;
  }

  // Are we compiling an app image?
  bool IsAppImage() const {
    return image_type_ == ImageType::kAppImage;
  }

  // Returns whether we are compiling against a "core" image, which
  // is an indicative we are running tests. The compiler will use that
  // information for checking invariants.
  bool CompilingWithCoreImage() const {
    return compiling_with_core_image_;
  }

  // Should the code be compiled as position independent?
  bool GetCompilePic() const {
    return compile_pic_;
  }

  const ProfileCompilationInfo* GetProfileCompilationInfo() const {
    return profile_compilation_info_;
  }

  bool HasVerboseMethods() const {
    return !verbose_methods_.empty();
  }

  bool IsVerboseMethod(const std::string& pretty_method) const {
    for (const std::string& cur_method : verbose_methods_) {
      if (pretty_method.find(cur_method) != std::string::npos) {
        return true;
      }
    }
    return false;
  }

  std::ostream* GetInitFailureOutput() const {
    return init_failure_output_.get();
  }

  bool AbortOnHardVerifierFailure() const {
    return abort_on_hard_verifier_failure_;
  }
  bool AbortOnSoftVerifierFailure() const {
    return abort_on_soft_verifier_failure_;
  }

  InstructionSet GetInstructionSet() const {
    return instruction_set_;
  }

  const InstructionSetFeatures* GetInstructionSetFeatures() const {
    return instruction_set_features_.get();
  }


  const std::vector<const DexFile*>& GetNoInlineFromDexFile() const {
    return no_inline_from_;
  }

  const std::vector<const DexFile*>& GetDexFilesForOatFile() const {
    return dex_files_for_oat_file_;
  }

  const HashSet<std::string>& GetImageClasses() const {
    return image_classes_;
  }

  bool IsImageClass(const char* descriptor) const;

  const VerificationResults* GetVerificationResults() const;

  const VerifiedMethod* GetVerifiedMethod(const DexFile* dex_file, uint32_t method_idx) const;

  // Checks if the specified method has been verified without failures. Returns
  // false if the method is not in the verification results (GetVerificationResults).
  bool IsMethodVerifiedWithoutFailures(uint32_t method_idx,
                                       uint16_t class_def_idx,
                                       const DexFile& dex_file) const;

  bool ParseCompilerOptions(const std::vector<std::string>& options,
                            bool ignore_unrecognized,
                            std::string* error_msg);

  void SetNonPic() {
    compile_pic_ = false;
  }

  const std::string& GetDumpCfgFileName() const {
    return dump_cfg_file_name_;
  }

  bool GetDumpCfgAppend() const {
    return dump_cfg_append_;
  }

  bool IsForceDeterminism() const {
    return force_determinism_;
  }

  bool DeduplicateCode() const {
    return deduplicate_code_;
  }

  RegisterAllocator::Strategy GetRegisterAllocationStrategy() const {
    return register_allocation_strategy_;
  }

  const std::vector<std::string>* GetPassesToRun() const {
    return passes_to_run_;
  }

  bool GetDumpTimings() const {
    return dump_timings_;
  }

  bool GetDumpPassTimings() const {
    return dump_pass_timings_;
  }

  bool GetDumpStats() const {
    return dump_stats_;
  }

  bool CountHotnessInCompiledCode() const {
    return count_hotness_in_compiled_code_;
  }

  bool ResolveStartupConstStrings() const {
    return resolve_startup_const_strings_;
  }

  ProfileMethodsCheck CheckProfiledMethodsCompiled() const {
    return check_profiled_methods_;
  }

  uint32_t MaxImageBlockSize() const {
    return max_image_block_size_;
  }

  void SetMaxImageBlockSize(uint32_t size) {
    max_image_block_size_ = size;
  }

  // Is `boot_image_filename` the name of a core image (small boot
  // image used for ART testing only)?
  static bool IsCoreImageFilename(const std::string& boot_image_filename);

 private:
  bool ParseDumpInitFailures(const std::string& option, std::string* error_msg);
  bool ParseRegisterAllocationStrategy(const std::string& option, std::string* error_msg);

  CompilerFilter::Filter compiler_filter_;
  size_t huge_method_threshold_;
  size_t large_method_threshold_;
  size_t small_method_threshold_;
  size_t tiny_method_threshold_;
  size_t num_dex_methods_threshold_;
  size_t inline_max_code_units_;

  InstructionSet instruction_set_;
  std::unique_ptr<const InstructionSetFeatures> instruction_set_features_;

  // Dex files from which we should not inline code. Does not own the dex files.
  // This is usually a very short list (i.e. a single dex file), so we
  // prefer vector<> over a lookup-oriented container, such as set<>.
  std::vector<const DexFile*> no_inline_from_;

  // List of dex files associated with the oat file, empty for JIT.
  std::vector<const DexFile*> dex_files_for_oat_file_;

  // Image classes, specifies the classes that will be included in the image if creating an image.
  // Must not be empty for real boot image, only for tests pretending to compile boot image.
  HashSet<std::string> image_classes_;

  // Results of AOT verification.
  const VerificationResults* verification_results_;

  ImageType image_type_;
  bool compiling_with_core_image_;
  bool baseline_;
  bool debuggable_;
  bool generate_debug_info_;
  bool generate_mini_debug_info_;
  bool generate_build_id_;
  bool implicit_null_checks_;
  bool implicit_so_checks_;
  bool implicit_suspend_checks_;
  bool compile_pic_;
  bool dump_timings_;
  bool dump_pass_timings_;
  bool dump_stats_;

  // When using a profile file only the top K% of the profiled samples will be compiled.
  double top_k_profile_threshold_;

  // Info for profile guided compilation.
  const ProfileCompilationInfo* profile_compilation_info_;

  // Vector of methods to have verbose output enabled for.
  std::vector<std::string> verbose_methods_;

  // Abort compilation with an error if we find a class that fails verification with a hard
  // failure.
  bool abort_on_hard_verifier_failure_;
  // Same for soft failures.
  bool abort_on_soft_verifier_failure_;

  // Log initialization of initialization failures to this stream if not null.
  std::unique_ptr<std::ostream> init_failure_output_;

  std::string dump_cfg_file_name_;
  bool dump_cfg_append_;

  // Whether the compiler should trade performance for determinism to guarantee exactly reproducible
  // outcomes.
  bool force_determinism_;

  // Whether code should be deduplicated.
  bool deduplicate_code_;

  // Whether compiled code should increment the hotness count of ArtMethod. Note that the increments
  // won't be atomic for performance reasons, so we accept races, just like in interpreter.
  bool count_hotness_in_compiled_code_;

  // Whether we eagerly resolve all of the const strings that are loaded from startup methods in the
  // profile.
  bool resolve_startup_const_strings_;

  // When running profile-guided compilation, check that methods intended to be compiled end
  // up compiled and are not punted.
  ProfileMethodsCheck check_profiled_methods_;

  // Maximum solid block size in the generated image.
  uint32_t max_image_block_size_;

  RegisterAllocator::Strategy register_allocation_strategy_;

  // If not null, specifies optimization passes which will be run instead of defaults.
  // Note that passes_to_run_ is not checked for correctness and providing an incorrect
  // list of passes can lead to unexpected compiler behaviour. This is caused by dependencies
  // between passes. Failing to satisfy them can for example lead to compiler crashes.
  // Passing pass names which are not recognized by the compiler will result in
  // compiler-dependant behavior.
  const std::vector<std::string>* passes_to_run_;

  friend class Dex2Oat;
  friend class DexToDexDecompilerTest;
  friend class CommonCompilerDriverTest;
  friend class CommonCompilerTest;
  friend class jit::JitCompiler;
  friend class verifier::VerifierDepsTest;
  friend class linker::Arm64RelativePatcherTest;

  template <class Base>
  friend bool ReadCompilerOptions(Base& map, CompilerOptions* options, std::string* error_msg);

  DISALLOW_COPY_AND_ASSIGN(CompilerOptions);
};

}  // namespace art

#endif  // ART_COMPILER_DRIVER_COMPILER_OPTIONS_H_
