// Copyright 2014 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_GC_TRACER_H_
#define V8_HEAP_GC_TRACER_H_

namespace v8 {
namespace internal {

// A simple ring buffer class with maximum size known at compile time.
// The class only implements the functionality required in GCTracer.
template <typename T, size_t MAX_SIZE>
class RingBuffer {
 public:
  class const_iterator {
   public:
    const_iterator() : index_(0), elements_(NULL) {}

    const_iterator(size_t index, const T* elements)
        : index_(index), elements_(elements) {}

    bool operator==(const const_iterator& rhs) const {
      return elements_ == rhs.elements_ && index_ == rhs.index_;
    }

    bool operator!=(const const_iterator& rhs) const {
      return elements_ != rhs.elements_ || index_ != rhs.index_;
    }

    operator const T*() const { return elements_ + index_; }

    const T* operator->() const { return elements_ + index_; }

    const T& operator*() const { return elements_[index_]; }

    const_iterator& operator++() {
      index_ = (index_ + 1) % (MAX_SIZE + 1);
      return *this;
    }

    const_iterator& operator--() {
      index_ = (index_ + MAX_SIZE) % (MAX_SIZE + 1);
      return *this;
    }

   private:
    size_t index_;
    const T* elements_;
  };

  RingBuffer() : begin_(0), end_(0) {}

  bool empty() const { return begin_ == end_; }
  size_t size() const {
    return (end_ - begin_ + MAX_SIZE + 1) % (MAX_SIZE + 1);
  }
  const_iterator begin() const { return const_iterator(begin_, elements_); }
  const_iterator end() const { return const_iterator(end_, elements_); }
  const_iterator back() const { return --end(); }
  void push_back(const T& element) {
    elements_[end_] = element;
    end_ = (end_ + 1) % (MAX_SIZE + 1);
    if (end_ == begin_) begin_ = (begin_ + 1) % (MAX_SIZE + 1);
  }
  void push_front(const T& element) {
    begin_ = (begin_ + MAX_SIZE) % (MAX_SIZE + 1);
    if (begin_ == end_) end_ = (end_ + MAX_SIZE) % (MAX_SIZE + 1);
    elements_[begin_] = element;
  }

 private:
  T elements_[MAX_SIZE + 1];
  size_t begin_;
  size_t end_;

  DISALLOW_COPY_AND_ASSIGN(RingBuffer);
};


// GCTracer collects and prints ONE line after each garbage collector
// invocation IFF --trace_gc is used.
// TODO(ernstm): Unit tests.
class GCTracer BASE_EMBEDDED {
 public:
  class Scope BASE_EMBEDDED {
   public:
    enum ScopeId {
      EXTERNAL,
      MC_MARK,
      MC_SWEEP,
      MC_SWEEP_NEWSPACE,
      MC_SWEEP_OLDSPACE,
      MC_SWEEP_CODE,
      MC_SWEEP_CELL,
      MC_SWEEP_MAP,
      MC_EVACUATE_PAGES,
      MC_UPDATE_NEW_TO_NEW_POINTERS,
      MC_UPDATE_ROOT_TO_NEW_POINTERS,
      MC_UPDATE_OLD_TO_NEW_POINTERS,
      MC_UPDATE_POINTERS_TO_EVACUATED,
      MC_UPDATE_POINTERS_BETWEEN_EVACUATED,
      MC_UPDATE_MISC_POINTERS,
      MC_WEAKCOLLECTION_PROCESS,
      MC_WEAKCOLLECTION_CLEAR,
      MC_WEAKCOLLECTION_ABORT,
      MC_FLUSH_CODE,
      NUMBER_OF_SCOPES
    };

    Scope(GCTracer* tracer, ScopeId scope) : tracer_(tracer), scope_(scope) {
      start_time_ = base::OS::TimeCurrentMillis();
    }

    ~Scope() {
      DCHECK(scope_ < NUMBER_OF_SCOPES);  // scope_ is unsigned.
      tracer_->current_.scopes[scope_] +=
          base::OS::TimeCurrentMillis() - start_time_;
    }

   private:
    GCTracer* tracer_;
    ScopeId scope_;
    double start_time_;

    DISALLOW_COPY_AND_ASSIGN(Scope);
  };


  class Event {
   public:
    enum Type { SCAVENGER = 0, MARK_COMPACTOR = 1, START = 2 };

    // Default constructor leaves the event uninitialized.
    Event() {}

    Event(Type type, const char* gc_reason, const char* collector_reason);

    // Returns a string describing the event type.
    const char* TypeName(bool short_name) const;

    // Type of event
    Type type;

    const char* gc_reason;
    const char* collector_reason;

    // Timestamp set in the constructor.
    double start_time;

    // Timestamp set in the destructor.
    double end_time;

    // Size of objects in heap set in constructor.
    intptr_t start_object_size;

    // Size of objects in heap set in destructor.
    intptr_t end_object_size;

    // Size of memory allocated from OS set in constructor.
    intptr_t start_memory_size;

    // Size of memory allocated from OS set in destructor.
    intptr_t end_memory_size;

    // Total amount of space either wasted or contained in one of free lists
    // before the current GC.
    intptr_t start_holes_size;

    // Total amount of space either wasted or contained in one of free lists
    // after the current GC.
    intptr_t end_holes_size;

    // Number of incremental marking steps since creation of tracer.
    // (value at start of event)
    int cumulative_incremental_marking_steps;

    // Incremental marking steps since
    // - last event for SCAVENGER events
    // - last MARK_COMPACTOR event for MARK_COMPACTOR events
    int incremental_marking_steps;

    // Bytes marked since creation of tracer (value at start of event).
    intptr_t cumulative_incremental_marking_bytes;

    // Bytes marked since
    // - last event for SCAVENGER events
    // - last MARK_COMPACTOR event for MARK_COMPACTOR events
    intptr_t incremental_marking_bytes;

    // Cumulative duration of incremental marking steps since creation of
    // tracer. (value at start of event)
    double cumulative_incremental_marking_duration;

    // Duration of incremental marking steps since
    // - last event for SCAVENGER events
    // - last MARK_COMPACTOR event for MARK_COMPACTOR events
    double incremental_marking_duration;

    // Cumulative pure duration of incremental marking steps since creation of
    // tracer. (value at start of event)
    double cumulative_pure_incremental_marking_duration;

    // Duration of pure incremental marking steps since
    // - last event for SCAVENGER events
    // - last MARK_COMPACTOR event for MARK_COMPACTOR events
    double pure_incremental_marking_duration;

    // Longest incremental marking step since start of marking.
    // (value at start of event)
    double longest_incremental_marking_step;

    // Amounts of time spent in different scopes during GC.
    double scopes[Scope::NUMBER_OF_SCOPES];
  };

  static const int kRingBufferMaxSize = 10;

  typedef RingBuffer<Event, kRingBufferMaxSize> EventBuffer;

  explicit GCTracer(Heap* heap);

  // Start collecting data.
  void Start(GarbageCollector collector, const char* gc_reason,
             const char* collector_reason);

  // Stop collecting data and print results.
  void Stop();

  // Log an incremental marking step.
  void AddIncrementalMarkingStep(double duration, intptr_t bytes);

  // Log time spent in marking.
  void AddMarkingTime(double duration) {
    cumulative_marking_duration_ += duration;
  }

  // Time spent in marking.
  double cumulative_marking_duration() const {
    return cumulative_marking_duration_;
  }

  // Log time spent in sweeping on main thread.
  void AddSweepingTime(double duration) {
    cumulative_sweeping_duration_ += duration;
  }

  // Time spent in sweeping on main thread.
  double cumulative_sweeping_duration() const {
    return cumulative_sweeping_duration_;
  }

  // Compute the mean duration of the last scavenger events. Returns 0 if no
  // events have been recorded.
  double MeanScavengerDuration() const {
    return MeanDuration(scavenger_events_);
  }

  // Compute the max duration of the last scavenger events. Returns 0 if no
  // events have been recorded.
  double MaxScavengerDuration() const { return MaxDuration(scavenger_events_); }

  // Compute the mean duration of the last mark compactor events. Returns 0 if
  // no events have been recorded.
  double MeanMarkCompactorDuration() const {
    return MeanDuration(mark_compactor_events_);
  }

  // Compute the max duration of the last mark compactor events. Return 0 if no
  // events have been recorded.
  double MaxMarkCompactorDuration() const {
    return MaxDuration(mark_compactor_events_);
  }

  // Compute the mean step duration of the last incremental marking round.
  // Returns 0 if no incremental marking round has been completed.
  double MeanIncrementalMarkingDuration() const;

  // Compute the max step duration of the last incremental marking round.
  // Returns 0 if no incremental marking round has been completed.
  double MaxIncrementalMarkingDuration() const;

  // Compute the average incremental marking speed in bytes/second. Returns 0 if
  // no events have been recorded.
  intptr_t IncrementalMarkingSpeedInBytesPerMillisecond() const;

 private:
  // Print one detailed trace line in name=value format.
  // TODO(ernstm): Move to Heap.
  void PrintNVP() const;

  // Print one trace line.
  // TODO(ernstm): Move to Heap.
  void Print() const;

  // Compute the mean duration of the events in the given ring buffer.
  double MeanDuration(const EventBuffer& events) const;

  // Compute the max duration of the events in the given ring buffer.
  double MaxDuration(const EventBuffer& events) const;

  // Pointer to the heap that owns this tracer.
  Heap* heap_;

  // Current tracer event. Populated during Start/Stop cycle. Valid after Stop()
  // has returned.
  Event current_;

  // Previous tracer event.
  Event previous_;

  // Previous MARK_COMPACTOR event.
  Event previous_mark_compactor_event_;

  // RingBuffers for SCAVENGER events.
  EventBuffer scavenger_events_;

  // RingBuffers for MARK_COMPACTOR events.
  EventBuffer mark_compactor_events_;

  // Cumulative number of incremental marking steps since creation of tracer.
  int cumulative_incremental_marking_steps_;

  // Cumulative size of incremental marking steps (in bytes) since creation of
  // tracer.
  intptr_t cumulative_incremental_marking_bytes_;

  // Cumulative duration of incremental marking steps since creation of tracer.
  double cumulative_incremental_marking_duration_;

  // Cumulative duration of pure incremental marking steps since creation of
  // tracer.
  double cumulative_pure_incremental_marking_duration_;

  // Longest incremental marking step since start of marking.
  double longest_incremental_marking_step_;

  // Total marking time.
  // This timer is precise when run with --print-cumulative-gc-stat
  double cumulative_marking_duration_;

  // Total sweeping time on the main thread.
  // This timer is precise when run with --print-cumulative-gc-stat
  // TODO(hpayer): Account for sweeping time on sweeper threads. Add a
  // different field for that.
  // TODO(hpayer): This timer right now just holds the sweeping time
  // of the initial atomic sweeping pause. Make sure that it accumulates
  // all sweeping operations performed on the main thread.
  double cumulative_sweeping_duration_;

  DISALLOW_COPY_AND_ASSIGN(GCTracer);
};
}
}  // namespace v8::internal

#endif  // V8_HEAP_GC_TRACER_H_
