// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_HEAP_MEMORY_REDUCER_H_
#define V8_HEAP_MEMORY_REDUCER_H_

#include "include/v8-platform.h"
#include "src/base/macros.h"
#include "src/common/globals.h"
#include "src/tasks/cancelable-task.h"

namespace v8 {
namespace internal {

namespace heap {
class HeapTester;
}  // namespace heap

class Heap;


// The goal of the MemoryReducer class is to detect transition of the mutator
// from high allocation phase to low allocation phase and to collect potential
// garbage created in the high allocation phase.
//
// The class implements an automaton with the following states and transitions.
//
// States:
// - DONE <last_gc_time_ms>
// - WAIT <started_gcs> <next_gc_start_ms> <last_gc_time_ms>
// - RUN <started_gcs> <last_gc_time_ms>
// The <started_gcs> is an integer in range from 0..kMaxNumberOfGCs that stores
// the number of GCs initiated by the MemoryReducer since it left the DONE
// state.
// The <next_gc_start_ms> is a double that stores the earliest time the next GC
// can be initiated by the MemoryReducer.
// The <last_gc_start_ms> is a double that stores the time of the last full GC.
// The DONE state means that the MemoryReducer is not active.
// The WAIT state means that the MemoryReducer is waiting for mutator allocation
// rate to drop. The check for the allocation rate happens in the timer task
// callback. If the allocation rate does not drop in watchdog_delay_ms since
// the last GC then transition to the RUN state is forced.
// The RUN state means that the MemoryReducer started incremental marking and is
// waiting for it to finish. Incremental marking steps are performed as usual
// in the idle notification and in the mutator.
//
// Transitions:
// DONE t -> WAIT 0 (now_ms + long_delay_ms) t' happens:
//     - on context disposal.
//     - at the end of mark-compact GC initiated by the mutator.
// This signals that there is potential garbage to be collected.
//
// WAIT n x t -> WAIT n (now_ms + long_delay_ms) t' happens:
//     - on mark-compact GC initiated by the mutator,
//     - in the timer callback if the mutator allocation rate is high or
//       incremental GC is in progress or (now_ms - t < watchdog_delay_ms)
//
// WAIT n x t -> WAIT (n+1) t happens:
//     - on background idle notification, which signals that we can start
//       incremental marking even if the allocation rate is high.
// The MemoryReducer starts incremental marking on this transition but still
// has a pending timer task.
//
// WAIT n x t -> DONE t happens:
//     - in the timer callback if n >= kMaxNumberOfGCs.
//
// WAIT n x t -> RUN (n+1) t happens:
//     - in the timer callback if the mutator allocation rate is low
//       and now_ms >= x and there is no incremental GC in progress.
//     - in the timer callback if (now_ms - t > watchdog_delay_ms) and
//       and now_ms >= x and there is no incremental GC in progress.
// The MemoryReducer starts incremental marking on this transition.
//
// RUN n t -> DONE now_ms happens:
//     - at end of the incremental GC initiated by the MemoryReducer if
//       (n > 1 and there is no more garbage to be collected) or
//       n == kMaxNumberOfGCs.
// RUN n t -> WAIT n (now_ms + short_delay_ms) now_ms happens:
//     - at end of the incremental GC initiated by the MemoryReducer if
//       (n == 1 or there is more garbage to be collected) and
//       n < kMaxNumberOfGCs.
//
// now_ms is the current time,
// t' is t if the current event is not a GC event and is now_ms otherwise,
// long_delay_ms, short_delay_ms, and watchdog_delay_ms are constants.
class V8_EXPORT_PRIVATE MemoryReducer {
 public:
  enum Action { kDone, kWait, kRun };

  struct State {
    State(Action action, int started_gcs, double next_gc_start_ms,
          double last_gc_time_ms, size_t committed_memory_at_last_run)
        : action(action),
          started_gcs(started_gcs),
          next_gc_start_ms(next_gc_start_ms),
          last_gc_time_ms(last_gc_time_ms),
          committed_memory_at_last_run(committed_memory_at_last_run) {}
    Action action;
    int started_gcs;
    double next_gc_start_ms;
    double last_gc_time_ms;
    size_t committed_memory_at_last_run;
  };

  enum EventType { kTimer, kMarkCompact, kPossibleGarbage };

  struct Event {
    EventType type;
    double time_ms;
    size_t committed_memory;
    bool next_gc_likely_to_collect_more;
    bool should_start_incremental_gc;
    bool can_start_incremental_gc;
  };

  explicit MemoryReducer(Heap* heap);
  // Callbacks.
  void NotifyMarkCompact(const Event& event);
  void NotifyPossibleGarbage(const Event& event);
  void NotifyBackgroundIdleNotification(const Event& event);
  // The step function that computes the next state from the current state and
  // the incoming event.
  static State Step(const State& state, const Event& event);
  // Posts a timer task that will call NotifyTimer after the given delay.
  void ScheduleTimer(double delay_ms);
  void TearDown();
  static const int kLongDelayMs;
  static const int kShortDelayMs;
  static const int kWatchdogDelayMs;
  static const int kMaxNumberOfGCs;
  // The committed memory has to increase by at least this factor since the
  // last run in order to trigger a new run after mark-compact.
  static const double kCommittedMemoryFactor;
  // The committed memory has to increase by at least this amount since the
  // last run in order to trigger a new run after mark-compact.
  static const size_t kCommittedMemoryDelta;

  Heap* heap() { return heap_; }

  bool ShouldGrowHeapSlowly() {
    return state_.action == kDone && state_.started_gcs > 0;
  }

 private:
  class TimerTask : public v8::internal::CancelableTask {
   public:
    explicit TimerTask(MemoryReducer* memory_reducer);

   private:
    // v8::internal::CancelableTask overrides.
    void RunInternal() override;
    MemoryReducer* memory_reducer_;
    DISALLOW_COPY_AND_ASSIGN(TimerTask);
  };

  void NotifyTimer(const Event& event);

  static bool WatchdogGC(const State& state, const Event& event);

  Heap* heap_;
  std::shared_ptr<v8::TaskRunner> taskrunner_;
  State state_;
  unsigned int js_calls_counter_;
  double js_calls_sample_time_ms_;

  // Used in cctest.
  friend class heap::HeapTester;
  DISALLOW_COPY_AND_ASSIGN(MemoryReducer);
};

}  // namespace internal
}  // namespace v8

#endif  // V8_HEAP_MEMORY_REDUCER_H_
