/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 * vim: set ts=8 sts=4 et sw=4 tw=99:
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef vm_Stopwatch_h
#define vm_Stopwatch_h

#include "mozilla/RefPtr.h"
#include "mozilla/Vector.h"

#include "jsapi.h"

/*
  An API for following in real-time the amount of CPU spent executing
  webpages, add-ons, etc.
*/

namespace js {

typedef mozilla::Vector<RefPtr<js::PerformanceGroup>> GroupVector;

/**
 * A container for performance groups.
 *
 * Performance monitoring deals with the execution duration of code
 * that belongs to components, for a notion of components defined by
 * the embedding.  Typically, in a web browser, a component may be a
 * webpage and/or a frame and/or a module and/or an add-on and/or a
 * sandbox and/or a process etc.
 *
 * A PerformanceGroupHolder is owned y a JSCompartment and maps that
 * compartment to all the components to which it belongs.
 */
struct PerformanceGroupHolder {

    /**
     * Get the groups to which this compartment belongs.
     *
     * Pre-condition: Execution must have entered the compartment.
     *
     * May return `nullptr` if the embedding has not initialized
     * support for performance groups.
     */
    const GroupVector* getGroups(JSContext*);

    explicit PerformanceGroupHolder(JSRuntime* runtime)
      : runtime_(runtime)
      , initialized_(false)
    {  }
    ~PerformanceGroupHolder();
    void unlink();
  private:
    JSRuntime* runtime_;

    // `true` once a call to `getGroups` has succeeded.
    bool initialized_;

    // The groups to which this compartment belongs. Filled if and only
    // if `initialized_` is `true`.
    GroupVector groups_;
};

/**
 * Container class for everything related to performance monitoring.
 */
struct PerformanceMonitoring {
    /**
     * The number of the current iteration of the event loop.
     */
    uint64_t iteration() {
        return iteration_;
    }

    explicit PerformanceMonitoring(JSRuntime* runtime)
      : totalCPOWTime(0)
      , stopwatchStartCallback(nullptr)
      , stopwatchStartClosure(nullptr)
      , stopwatchCommitCallback(nullptr)
      , stopwatchCommitClosure(nullptr)
      , getGroupsCallback(nullptr)
      , getGroupsClosure(nullptr)
      , isMonitoringJank_(false)
      , isMonitoringCPOW_(false)
      , iteration_(0)
      , startedAtIteration_(0)
    { }

    /**
     * Reset the stopwatch.
     *
     * This method is meant to be called whenever we start
     * processing an event, to ensure that we stop any ongoing
     * measurement that would otherwise provide irrelevant
     * results.
     */
    void reset();

    /**
     * Start the stopwatch.
     *
     * This method is meant to be called once we know that the
     * current event contains JavaScript code to execute. Calling
     * this several times during the same iteration is idempotent.
     */
    void start();

    /**
     * Commit the performance data collected since the last call
     * to `start()`, unless `reset()` has been called since then.
     */
    bool commit();

    /**
     * Liberate memory and references.
     */
    void dispose(JSRuntime* rtx);

    /**
     * Activate/deactivate stopwatch measurement of jank.
     *
     * Noop if `value` is `true` and the stopwatch is already
     * measuring jank, or if `value` is `false` and the stopwatch
     * is not measuring jank.
     *
     * Otherwise, any pending measurements are dropped, but previous
     * measurements remain stored.
     *
     * May return `false` if the underlying hashtable cannot be allocated.
     */
    bool setIsMonitoringJank(bool value) {
        if (isMonitoringJank_ != value)
            reset();

        isMonitoringJank_ = value;
        return true;
    }
    bool isMonitoringJank() const {
        return isMonitoringJank_;
    }

    /**
     * Mark that a group has been used in this iteration.
     */
    bool addRecentGroup(PerformanceGroup* group);

    /**
     * Activate/deactivate stopwatch measurement of CPOW.
     *
     * Noop if `value` is `true` and the stopwatch is already
     * measuring CPOW, or if `value` is `false` and the stopwatch
     * is not measuring CPOW.
     *
     * Otherwise, any pending measurements are dropped, but previous
     * measurements remain stored.
     *
     * May return `false` if the underlying hashtable cannot be allocated.
     */
    bool setIsMonitoringCPOW(bool value) {
        if (isMonitoringCPOW_ != value)
            reset();

        isMonitoringCPOW_ = value;
        return true;
    }

    bool isMonitoringCPOW() const {
        return isMonitoringCPOW_;
    }

    /**
     * Callbacks called when we start executing an event/when we have
     * run to completion (including enqueued microtasks).
     *
     * If there are no nested event loops, each call to
     * `stopwatchStartCallback` is followed by a call to
     * `stopwatchCommitCallback`. However, embedders should not assume
     * that this will always be the case, unless they take measures to
     * prevent nested event loops.
     *
     * In presence of nested event loops, several calls to
     * `stopwatchStartCallback` may occur before a call to
     * `stopwatchCommitCallback`. Embedders should assume that a
     * second call to `stopwatchStartCallback` cancels any measure
     * started by the previous calls to `stopwatchStartCallback` and
     * which have not been committed by `stopwatchCommitCallback`.
     */
    void setStopwatchStartCallback(js::StopwatchStartCallback cb, void* closure) {
        stopwatchStartCallback = cb;
        stopwatchStartClosure = closure;
    }
    void setStopwatchCommitCallback(js::StopwatchCommitCallback cb, void* closure) {
        stopwatchCommitCallback = cb;
        stopwatchCommitClosure = closure;
    }

    /**
     * Callback called to associate a JSCompartment to the set of
     * `PerformanceGroup`s that represent the components to which
     * it belongs.
     */
    void setGetGroupsCallback(js::GetGroupsCallback cb, void* closure) {
        getGroupsCallback = cb;
        getGroupsClosure = closure;
    }

    /**
     * The total amount of time spent waiting on CPOWs since the
     * start of the process, in microseconds.
     */
    uint64_t totalCPOWTime;

    /**
     * Data extracted by the AutoStopwatch to determine how often
     * we reschedule the process to a different CPU during the
     * execution of JS.
     *
     * Warning: These values are incremented *only* on platforms
     * that offer a syscall/libcall to check on which CPU a
     * process is currently executed.
     */
    struct TestCpuRescheduling
    {
        // Incremented once we have finished executing code
        // in a group, if the CPU on which we started
        // execution is the same as the CPU on which
        // we finished.
        uint64_t stayed;
        // Incremented once we have finished executing code
        // in a group, if the CPU on which we started
        // execution is different from the CPU on which
        // we finished.
        uint64_t moved;
        TestCpuRescheduling()
            : stayed(0),
              moved(0)
        { }
    };
    TestCpuRescheduling testCpuRescheduling;
  private:
    PerformanceMonitoring(const PerformanceMonitoring&) = delete;
    PerformanceMonitoring& operator=(const PerformanceMonitoring&) = delete;

  private:
    friend struct PerformanceGroupHolder;
    js::StopwatchStartCallback stopwatchStartCallback;
    void* stopwatchStartClosure;
    js::StopwatchCommitCallback stopwatchCommitCallback;
    void* stopwatchCommitClosure;

    js::GetGroupsCallback getGroupsCallback;
    void* getGroupsClosure;

    /**
     * `true` if stopwatch monitoring is active for Jank, `false` otherwise.
     */
    bool isMonitoringJank_;
    /**
     * `true` if stopwatch monitoring is active for CPOW, `false` otherwise.
     */
    bool isMonitoringCPOW_;

    /**
     * The number of times we have entered the event loop.
     * Used to reset counters whenever we enter the loop,
     * which may be caused either by having completed the
     * previous run of the event loop, or by entering a
     * nested loop.
     *
     * Always incremented by 1, may safely overflow.
     */
    uint64_t iteration_;

    /**
     * The iteration at which the stopwatch was last started.
     *
     * Used both to avoid starting the stopwatch several times
     * during the same event loop and to avoid committing stale
     * stopwatch results.
     */
    uint64_t startedAtIteration_;

    /**
     * Groups used in the current iteration.
     */
    GroupVector recentGroups_;
};

#if WINVER >= 0x0600
struct cpuid_t {
    WORD group_;
    BYTE number_;
    cpuid_t(WORD group, BYTE number)
        : group_(group),
          number_(number)
    { }
    cpuid_t()
        : group_(0),
          number_(0)
    { }
};
#elif defined(__linux__)
    typedef int cpuid_t;
#else
    typedef struct {} cpuid_t;
#endif // defined(WINVER >= 0x0600) || defined(__linux__)

/**
 * RAII class to start/stop measuring performance when
 * entering/leaving a compartment.
 */
class AutoStopwatch final {
    // The context with which this object was initialized.
    // Non-null.
    JSContext* const cx_;

    // An indication of the number of times we have entered the event
    // loop.  Used only for comparison.
    uint64_t iteration_;

    // `true` if we are monitoring jank, `false` otherwise.
    bool isMonitoringJank_;
    // `true` if we are monitoring CPOW, `false` otherwise.
    bool isMonitoringCPOW_;

    // Timestamps captured while starting the stopwatch.
    uint64_t cyclesStart_;
    uint64_t CPOWTimeStart_;

    // The CPU on which we started the measure. Defined only
    // if `isMonitoringJank_` is `true`.
    cpuid_t cpuStart_;

    mozilla::Vector<RefPtr<js::PerformanceGroup>> groups_;

  public:
    // If the stopwatch is active, constructing an instance of
    // AutoStopwatch causes it to become the current owner of the
    // stopwatch.
    //
    // Previous owner is restored upon destruction.
    explicit AutoStopwatch(JSContext* cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
    ~AutoStopwatch();
  private:
    void inline enter();

    bool inline exit();

    // Attempt to acquire a group
    // If the group is inactive or if the group already has a stopwatch,
    // do nothing and return `null`.
    // Otherwise, bind the group to `this` for the current iteration
    // and return `group`.
    PerformanceGroup* acquireGroup(PerformanceGroup* group);

    // Release a group. Noop if `this` is not the stopwatch of
    // `group` for the current iteration.
    void releaseGroup(PerformanceGroup* group);

    // Add recent changes to all the groups owned by this stopwatch.
    // Mark the groups as changed recently.
    bool addToGroups(uint64_t cyclesDelta, uint64_t CPOWTimeDelta);

    // Add recent changes to a single group. Mark the group as changed recently.
    bool addToGroup(JSRuntime* runtime, uint64_t cyclesDelta, uint64_t CPOWTimeDelta, PerformanceGroup* group);

    // Update telemetry statistics.
    void updateTelemetry(const cpuid_t& a, const cpuid_t& b);

    // Perform a subtraction for a quantity that should be monotonic
    // but is not guaranteed to be so.
    //
    // If `start <= end`, return `end - start`.
    // Otherwise, return `0`.
    uint64_t inline getDelta(const uint64_t end, const uint64_t start) const;

    // Return the value of the Timestamp Counter, as provided by the CPU.
    // 0 on platforms for which we do not have access to a Timestamp Counter.
    uint64_t inline getCycles() const;


    // Return the identifier of the current CPU, on platforms for which we have
    // access to the current CPU.
    cpuid_t inline getCPU() const;

    // Compare two CPU identifiers.
    bool inline isSameCPU(const cpuid_t& a, const cpuid_t& b) const;
  private:
    MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER;
};


} // namespace js

#endif // vm_Stopwatch_h
