/*
 * 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
  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),
    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 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),
    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 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_
        << ", 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 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_
