/*
 * 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 <ostream>
#include <string>

namespace art {

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();

  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),
    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,
      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),
    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_;
  }
  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_
        << ", 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_;
  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_
