/*
 * Copyright (C) 2016 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
 * * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ART_RUNTIME_JIT_PROFILE_SAVER_OPTIONS_H_
#define ART_RUNTIME_JIT_PROFILE_SAVER_OPTIONS_H_

#include <cstdint>
#include <ostream>
#include <string>

namespace art HIDDEN {

struct ProfileSaverOptions {
 public:
  static constexpr uint32_t kMinSavePeriodMs = 40 * 1000;  // 40 seconds
  // Default value for the min save period on first use, indicating that the
  // period is not configured.
  static constexpr uint32_t kMinFirstSaveMsNotSet = 0;
  static constexpr uint32_t kSaveResolvedClassesDelayMs = 5 * 1000;  // 5 seconds
  // Minimum number of JIT samples during launch to mark a method as hot in the profile.
  static constexpr uint32_t kHotStartupMethodSamples = 1;
  static constexpr uint32_t kHotStartupMethodSamplesLowRam = 256;
  static constexpr uint32_t kMinMethodsToSave = 10;
  static constexpr uint32_t kMinClassesToSave = 10;
  static constexpr uint32_t kMinNotificationBeforeWake = 10;
  static constexpr uint32_t kMaxNotificationBeforeWake = 50;
  static constexpr uint32_t kHotStartupMethodSamplesNotSet = std::numeric_limits<uint32_t>::max();
  static constexpr uint16_t kInlineCacheThreshold = 4000;

  ProfileSaverOptions() :
    enabled_(false),
    min_save_period_ms_(kMinSavePeriodMs),
    min_first_save_ms_(kMinFirstSaveMsNotSet),
    save_resolved_classes_delay_ms_(kSaveResolvedClassesDelayMs),
    hot_startup_method_samples_(kHotStartupMethodSamplesNotSet),
    min_methods_to_save_(kMinMethodsToSave),
    min_classes_to_save_(kMinClassesToSave),
    min_notification_before_wake_(kMinNotificationBeforeWake),
    max_notification_before_wake_(kMaxNotificationBeforeWake),
    inline_cache_threshold_(kInlineCacheThreshold),
    profile_path_(""),
    profile_boot_class_path_(false),
    profile_aot_code_(false),
    wait_for_jit_notifications_to_save_(true) {}

  ProfileSaverOptions(
      bool enabled,
      uint32_t min_save_period_ms,
      uint32_t min_first_save_ms,
      uint32_t save_resolved_classes_delay_ms,
      uint32_t hot_startup_method_samples,
      uint32_t min_methods_to_save,
      uint32_t min_classes_to_save,
      uint32_t min_notification_before_wake,
      uint32_t max_notification_before_wake,
      uint16_t inline_cache_threshold,
      const std::string& profile_path,
      bool profile_boot_class_path,
      bool profile_aot_code = false,
      bool wait_for_jit_notifications_to_save = true)
  : enabled_(enabled),
    min_save_period_ms_(min_save_period_ms),
    min_first_save_ms_(min_first_save_ms),
    save_resolved_classes_delay_ms_(save_resolved_classes_delay_ms),
    hot_startup_method_samples_(hot_startup_method_samples),
    min_methods_to_save_(min_methods_to_save),
    min_classes_to_save_(min_classes_to_save),
    min_notification_before_wake_(min_notification_before_wake),
    max_notification_before_wake_(max_notification_before_wake),
    inline_cache_threshold_(inline_cache_threshold),
    profile_path_(profile_path),
    profile_boot_class_path_(profile_boot_class_path),
    profile_aot_code_(profile_aot_code),
    wait_for_jit_notifications_to_save_(wait_for_jit_notifications_to_save) {}

  bool IsEnabled() const {
    return enabled_;
  }
  void SetEnabled(bool enabled) {
    enabled_ = enabled;
  }

  uint32_t GetMinSavePeriodMs() const {
    return min_save_period_ms_;
  }
  uint32_t GetMinFirstSaveMs() const {
    return min_first_save_ms_;
  }
  uint32_t GetSaveResolvedClassesDelayMs() const {
    return save_resolved_classes_delay_ms_;
  }
  uint32_t GetHotStartupMethodSamples(bool is_low_ram) const {
    uint32_t ret = hot_startup_method_samples_;
    if (ret == kHotStartupMethodSamplesNotSet) {
      ret = is_low_ram ? kHotStartupMethodSamplesLowRam : kHotStartupMethodSamples;
    }
    return ret;
  }
  uint32_t GetMinMethodsToSave() const {
    return min_methods_to_save_;
  }
  uint32_t GetMinClassesToSave() const {
    return min_classes_to_save_;
  }
  uint32_t GetMinNotificationBeforeWake() const {
    return min_notification_before_wake_;
  }
  uint32_t GetMaxNotificationBeforeWake() const {
    return max_notification_before_wake_;
  }
  uint16_t GetInlineCacheThreshold() const {
    return inline_cache_threshold_;
  }
  std::string GetProfilePath() const {
    return profile_path_;
  }
  bool GetProfileBootClassPath() const {
    return profile_boot_class_path_;
  }
  bool GetProfileAOTCode() const {
    return profile_aot_code_;
  }
  bool GetWaitForJitNotificationsToSave() const {
    return wait_for_jit_notifications_to_save_;
  }
  void SetWaitForJitNotificationsToSave(bool value) {
    wait_for_jit_notifications_to_save_ = value;
  }

  friend std::ostream & operator<<(std::ostream &os, const ProfileSaverOptions& pso) {
    os << "enabled_" << pso.enabled_
        << ", min_save_period_ms_" << pso.min_save_period_ms_
        << ", min_first_save_ms_" << pso.min_first_save_ms_
        << ", save_resolved_classes_delay_ms_" << pso.save_resolved_classes_delay_ms_
        << ", hot_startup_method_samples_" << pso.hot_startup_method_samples_
        << ", min_methods_to_save_" << pso.min_methods_to_save_
        << ", min_classes_to_save_" << pso.min_classes_to_save_
        << ", min_notification_before_wake_" << pso.min_notification_before_wake_
        << ", max_notification_before_wake_" << pso.max_notification_before_wake_
        << ", inline_cache_threshold_" << pso.inline_cache_threshold_
        << ", profile_boot_class_path_" << pso.profile_boot_class_path_
        << ", profile_aot_code_" << pso.profile_aot_code_
        << ", wait_for_jit_notifications_to_save_" << pso.wait_for_jit_notifications_to_save_;
    return os;
  }

  bool enabled_;
  uint32_t min_save_period_ms_;
  uint32_t min_first_save_ms_;
  uint32_t save_resolved_classes_delay_ms_;
  // Do not access hot_startup_method_samples_ directly for reading since it may be set to the
  // placeholder default.
  uint32_t hot_startup_method_samples_;
  uint32_t min_methods_to_save_;
  uint32_t min_classes_to_save_;
  uint32_t min_notification_before_wake_;
  uint32_t max_notification_before_wake_;
  uint16_t inline_cache_threshold_;
  std::string profile_path_;
  bool profile_boot_class_path_;
  bool profile_aot_code_;
  bool wait_for_jit_notifications_to_save_;
};

}  // namespace art

#endif  // ART_RUNTIME_JIT_PROFILE_SAVER_OPTIONS_H_
