/* -*- 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/. */

#include "vm/Stopwatch.h"

#include "mozilla/ArrayUtils.h"
#include "mozilla/IntegerTypeTraits.h"
#include "mozilla/unused.h"

#if defined(XP_WIN)
#include <processthreadsapi.h>
#include <windows.h>
#endif // defined(XP_WIN)

#include "jscompartment.h"

#include "gc/Zone.h"
#include "vm/Runtime.h"

namespace js {

bool
PerformanceMonitoring::addRecentGroup(PerformanceGroup* group)
{
    if (group->isUsedInThisIteration())
        return true;

    group->setIsUsedInThisIteration(true);
    return recentGroups_.append(group);
}

void
PerformanceMonitoring::reset()
{
    // All ongoing measures are dependent on the current iteration#.
    // By incrementing it, we mark all data as stale. Stale data will
    // be overwritten progressively during the execution.
    ++iteration_;
    recentGroups_.clear();
}

void
PerformanceMonitoring::start()
{
    if (!isMonitoringJank_)
        return;

    if (iteration_ == startedAtIteration_) {
        // The stopwatch is already started for this iteration.
        return;
    }

    startedAtIteration_ = iteration_;
    if (stopwatchStartCallback)
        stopwatchStartCallback(iteration_, stopwatchStartClosure);
}

// Commit the data that has been collected during the iteration
// into the actual `PerformanceData`.
//
// We use the proportion of cycles-spent-in-group over
// cycles-spent-in-toplevel-group as an approximation to allocate
// system (kernel) time and user (CPU) time to each group. Note
// that cycles are not an exact measure:
//
// 1. if the computer has gone to sleep, the clock may be reset to 0;
// 2. if the process is moved between CPUs/cores, it may end up on a CPU
//    or core with an unsynchronized clock;
// 3. the mapping between clock cycles and walltime varies with the current
//    frequency of the CPU;
// 4. other threads/processes using the same CPU will also increment
//    the counter.
//
// ** Effect of 1. (computer going to sleep)
//
// We assume that this will happen very seldom. Since the final numbers
// are bounded by the CPU time and Kernel time reported by `getresources`,
// the effect will be contained to a single iteration of the event loop.
//
// ** Effect of 2. (moving between CPUs/cores)
//
// On platforms that support it, we only measure the number of cycles
// if we start and end execution of a group on the same
// CPU/core. While there is a small window (a few cycles) during which
// the thread can be migrated without us noticing, we expect that this
// will happen rarely enough that this won't affect the statistics
// meaningfully.
//
// On other platforms, assuming that the probability of jumping
// between CPUs/cores during a given (real) cycle is constant, and
// that the distribution of differences between clocks is even, the
// probability that the number of cycles reported by a measure is
// modified by X cycles should be a gaussian distribution, with groups
// with longer execution having a larger amplitude than groups with
// shorter execution. Since we discard measures that result in a
// negative number of cycles, this distribution is actually skewed
// towards over-estimating the number of cycles of groups that already
// have many cycles and under-estimating the number of cycles that
// already have fewer cycles.
//
// Since the final numbers are bounded by the CPU time and Kernel time
// reported by `getresources`, we accept this bias.
//
// ** Effect of 3. (mapping between clock cycles and walltime)
//
// Assuming that this is evenly distributed, we expect that this will
// eventually balance out.
//
// ** Effect of 4. (cycles increase with system activity)
//
// Assuming that, within an iteration of the event loop, this happens
// unformly over time, this will skew towards over-estimating the number
// of cycles of groups that already have many cycles and under-estimating
// the number of cycles that already have fewer cycles.
//
// Since the final numbers are bounded by the CPU time and Kernel time
// reported by `getresources`, we accept this bias.
//
// ** Big picture
//
// Computing the number of cycles is fast and should be accurate
// enough in practice. Alternatives (such as calling `getresources`
// all the time or sampling from another thread) are very expensive
// in system calls and/or battery and not necessarily more accurate.
bool
PerformanceMonitoring::commit()
{
#if !defined(MOZ_HAVE_RDTSC)
    // The AutoStopwatch is only executed if `MOZ_HAVE_RDTSC`.
    return false;
#endif // !defined(MOZ_HAVE_RDTSC)

    if (!isMonitoringJank_) {
        // Either we have not started monitoring or monitoring has
        // been cancelled during the iteration.
        return true;
    }

    if (startedAtIteration_ != iteration_) {
        // No JS code has been monitored during this iteration.
        return true;
    }

    GroupVector recentGroups;
    recentGroups_.swap(recentGroups);

    bool success = true;
    if (stopwatchCommitCallback)
        success = stopwatchCommitCallback(iteration_, recentGroups, stopwatchCommitClosure);

    // Reset immediately, to make sure that we're not hit by the end
    // of a nested event loop (which would cause `commit` to be called
    // twice in succession).
    reset();
    return success;
}

void
PerformanceMonitoring::dispose(JSRuntime* rt)
{
    reset();
    for (CompartmentsIter c(rt, SkipAtoms); !c.done(); c.next()) {
        c->performanceMonitoring.unlink();
    }
}

PerformanceGroupHolder::~PerformanceGroupHolder()
{
    unlink();
}

void
PerformanceGroupHolder::unlink()
{
    initialized_ = false;
    groups_.clear();
}

const GroupVector*
PerformanceGroupHolder::getGroups(JSContext* cx)
{
    if (initialized_)
        return &groups_;

    if (!runtime_->performanceMonitoring.getGroupsCallback)
        return nullptr;

    if (!runtime_->performanceMonitoring.getGroupsCallback(cx, groups_, runtime_->performanceMonitoring.getGroupsClosure))
        return nullptr;

    initialized_ = true;
    return &groups_;
}

AutoStopwatch::AutoStopwatch(JSContext* cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
  : cx_(cx)
  , iteration_(0)
  , isMonitoringJank_(false)
  , isMonitoringCPOW_(false)
  , cyclesStart_(0)
  , CPOWTimeStart_(0)
{
    MOZ_GUARD_OBJECT_NOTIFIER_INIT;

    JSCompartment* compartment = cx_->compartment();
    if (compartment->scheduledForDestruction)
        return;

    JSRuntime* runtime = cx_->runtime();
    iteration_ = runtime->performanceMonitoring.iteration();

    const GroupVector* groups = compartment->performanceMonitoring.getGroups(cx);
    if (!groups) {
      // Either the embedding has not provided any performance
      // monitoring logistics or there was an error that prevents
      // performance monitoring.
      return;
    }
    for (auto group = groups->begin(); group < groups->end(); group++) {
      auto acquired = acquireGroup(*group);
      if (acquired)
        groups_.append(acquired);
    }
    if (groups_.length() == 0) {
      // We are not in charge of monitoring anything.
      return;
    }

    // Now that we are sure that JS code is being executed,
    // initialize the stopwatch for this iteration, lazily.
    runtime->performanceMonitoring.start();
    enter();
}

AutoStopwatch::~AutoStopwatch()
{
    if (groups_.length() == 0) {
        // We are not in charge of monitoring anything.
        return;
    }

    JSCompartment* compartment = cx_->compartment();
    if (compartment->scheduledForDestruction)
        return;

    JSRuntime* runtime = cx_->runtime();
    if (iteration_ != runtime->performanceMonitoring.iteration()) {
        // We have entered a nested event loop at some point.
        // Any information we may have is obsolete.
        return;
    }

#if defined(STARBOARD)
    auto unused = exit();
    SB_UNREFERENCED_PARAMETER(unused);
#else
    mozilla::Unused << exit(); // Sadly, there is nothing we can do about an error at this point.
#endif

    for (auto group = groups_.begin(); group < groups_.end(); group++)
        releaseGroup(*group);
}

void
AutoStopwatch::enter()
{
    JSRuntime* runtime = cx_->runtime();

    if (runtime->performanceMonitoring.isMonitoringCPOW()) {
        CPOWTimeStart_ = runtime->performanceMonitoring.totalCPOWTime;
        isMonitoringCPOW_ = true;
    }

    if (runtime->performanceMonitoring.isMonitoringJank()) {
        cyclesStart_ = this->getCycles();
        cpuStart_ = this->getCPU();
        isMonitoringJank_ = true;
    }
}

bool
AutoStopwatch::exit()
{
    JSRuntime* runtime = cx_->runtime();

    uint64_t cyclesDelta = 0;
    if (isMonitoringJank_ && runtime->performanceMonitoring.isMonitoringJank()) {
        // We were monitoring jank when we entered and we still are.

        // If possible, discard results when we don't end on the
        // same CPU as we started.  Note that we can be
        // rescheduled to another CPU beween `getCycles()` and
        // `getCPU()`.  We hope that this will happen rarely
        // enough that the impact on our statistics will remain
        // limited.
        const cpuid_t cpuEnd = this->getCPU();
        if (isSameCPU(cpuStart_, cpuEnd)) {
            const uint64_t cyclesEnd = getCycles();
            cyclesDelta = getDelta(cyclesEnd, cyclesStart_);
        }
#if WINVER >= 0x600
        updateTelemetry(cpuStart_, cpuEnd);
#elif defined(__linux__)
        updateTelemetry(cpuStart_, cpuEnd);
#endif // WINVER >= 0x600 || _linux__
    }

    uint64_t CPOWTimeDelta = 0;
    if (isMonitoringCPOW_ && runtime->performanceMonitoring.isMonitoringCPOW()) {
        // We were monitoring CPOW when we entered and we still are.
        const uint64_t CPOWTimeEnd = runtime->performanceMonitoring.totalCPOWTime;
        CPOWTimeDelta = getDelta(CPOWTimeEnd, CPOWTimeStart_);
    }
    return addToGroups(cyclesDelta, CPOWTimeDelta);
}

void
AutoStopwatch::updateTelemetry(const cpuid_t& cpuStart_, const cpuid_t& cpuEnd)
{
  JSRuntime* runtime = cx_->runtime();

    if (isSameCPU(cpuStart_, cpuEnd))
        runtime->performanceMonitoring.testCpuRescheduling.stayed += 1;
    else
        runtime->performanceMonitoring.testCpuRescheduling.moved += 1;
}

PerformanceGroup*
AutoStopwatch::acquireGroup(PerformanceGroup* group)
{
    MOZ_ASSERT(group);

    if (group->isAcquired(iteration_))
        return nullptr;

    if (!group->isActive())
        return nullptr;

    group->acquire(iteration_, this);
    return group;
}

void
AutoStopwatch::releaseGroup(PerformanceGroup* group)
{
    MOZ_ASSERT(group);
        group->release(iteration_, this);
}

bool
AutoStopwatch::addToGroups(uint64_t cyclesDelta, uint64_t CPOWTimeDelta)
{
  JSRuntime* runtime = cx_->runtime();

    for (auto group = groups_.begin(); group < groups_.end(); ++group) {
      if (!addToGroup(runtime, cyclesDelta, CPOWTimeDelta, *group))
        return false;
    }
    return true;
}

bool
AutoStopwatch::addToGroup(JSRuntime* runtime, uint64_t cyclesDelta, uint64_t CPOWTimeDelta, PerformanceGroup* group)
{
    MOZ_ASSERT(group);
    MOZ_ASSERT(group->isAcquired(iteration_, this));

    if (!runtime->performanceMonitoring.addRecentGroup(group))
      return false;
    group->addRecentTicks(iteration_, 1);
    group->addRecentCycles(iteration_, cyclesDelta);
    group->addRecentCPOW(iteration_, CPOWTimeDelta);
    return true;
}

uint64_t
AutoStopwatch::getDelta(const uint64_t end, const uint64_t start) const
{
    if (start >= end)
      return 0;
    return end - start;
}

uint64_t
AutoStopwatch::getCycles() const
{
#if defined(MOZ_HAVE_RDTSC)
    return ReadTimestampCounter();
#else
    return 0;
#endif // defined(MOZ_HAVE_RDTSC)
}

cpuid_t inline
AutoStopwatch::getCPU() const
{
#if defined(XP_WIN) && WINVER >= _WIN32_WINNT_VISTA
    PROCESSOR_NUMBER proc;
    GetCurrentProcessorNumberEx(&proc);

    cpuid_t result(proc.Group, proc.Number);
    return result;
#elif defined(XP_LINUX)
    return sched_getcpu();
#else
    return {};
#endif // defined(XP_WIN) || defined(XP_LINUX)
}

bool inline
AutoStopwatch::isSameCPU(const cpuid_t& a, const cpuid_t& b) const
{
#if defined(XP_WIN)  && WINVER >= _WIN32_WINNT_VISTA
    return a.group_ == b.group_ && a.number_ == b.number_;
#elif defined(XP_LINUX)
    return a == b;
#else
    return true;
#endif
}

PerformanceGroup::PerformanceGroup()
    : recentCycles_(0)
    , recentTicks_(0)
    , recentCPOW_(0)
    , iteration_(0)
    , isActive_(false)
    , isUsedInThisIteration_(false)
    , owner_(nullptr)
    , refCount_(0)
{ }

uint64_t
PerformanceGroup::iteration() const
{
    return iteration_;
}


bool
PerformanceGroup::isAcquired(uint64_t it) const
{
    return owner_ != nullptr && iteration_ == it;
}

bool
PerformanceGroup::isAcquired(uint64_t it, const AutoStopwatch* owner) const
{
    return owner_ == owner && iteration_ == it;
}

void
PerformanceGroup::acquire(uint64_t it, const AutoStopwatch* owner)
{
    if (iteration_ != it) {
        // Any data that pretends to be recent is actually bound
        // to an older iteration and therefore stale.
        resetRecentData();
    }
    iteration_ = it;
    owner_ = owner;
}

void
PerformanceGroup::release(uint64_t it, const AutoStopwatch* owner)
{
    if (iteration_ != it)
        return;

    MOZ_ASSERT(owner == owner_ || owner_ == nullptr);
    owner_ = nullptr;
}

void
PerformanceGroup::resetRecentData()
{
    recentCycles_ = 0;
    recentTicks_ = 0;
    recentCPOW_ = 0;
    isUsedInThisIteration_ = false;
}


uint64_t
PerformanceGroup::recentCycles(uint64_t iteration) const
{
    MOZ_ASSERT(iteration == iteration_);
    return recentCycles_;
}

void
PerformanceGroup::addRecentCycles(uint64_t iteration, uint64_t cycles)
{
    MOZ_ASSERT(iteration == iteration_);
    recentCycles_ += cycles;
}

uint64_t
PerformanceGroup::recentTicks(uint64_t iteration) const
{
    MOZ_ASSERT(iteration == iteration_);
    return recentTicks_;
}

void
PerformanceGroup::addRecentTicks(uint64_t iteration, uint64_t ticks)
{
    MOZ_ASSERT(iteration == iteration_);
    recentTicks_ += ticks;
}


uint64_t
PerformanceGroup::recentCPOW(uint64_t iteration) const
{
    MOZ_ASSERT(iteration == iteration_);
    return recentCPOW_;
}

void
PerformanceGroup::addRecentCPOW(uint64_t iteration, uint64_t CPOW)
{
    MOZ_ASSERT(iteration == iteration_);
    recentCPOW_ += CPOW;
}


bool
PerformanceGroup::isActive() const
{
    return isActive_;
}

void
PerformanceGroup::setIsActive(bool value)
{
  isActive_ = value;
}

void
PerformanceGroup::setIsUsedInThisIteration(bool value)
{
  isUsedInThisIteration_ = value;
}
bool
PerformanceGroup::isUsedInThisIteration() const
{
  return isUsedInThisIteration_;
}

void
PerformanceGroup::AddRef()
{
    ++refCount_;
}

void
PerformanceGroup::Release()
{
    MOZ_ASSERT(refCount_ > 0);
    --refCount_;
    if (refCount_ > 0)
        return;

    this->Delete();
}

JS_PUBLIC_API(bool) SetStopwatchStartCallback(JSRuntime* rt, StopwatchStartCallback cb, void* closure)
{
    rt->performanceMonitoring.setStopwatchStartCallback(cb, closure);
    return true;
}

JS_PUBLIC_API(bool) SetStopwatchCommitCallback(JSRuntime* rt, StopwatchCommitCallback cb, void* closure)
{
    rt->performanceMonitoring.setStopwatchCommitCallback(cb, closure);
    return true;
}

JS_PUBLIC_API(bool) SetGetPerformanceGroupsCallback(JSRuntime* rt, GetGroupsCallback cb, void* closure)
{
    rt->performanceMonitoring.setGetGroupsCallback(cb, closure);
    return true;
}

JS_PUBLIC_API(bool)
FlushPerformanceMonitoring(JSRuntime* rt)
{
    return rt->performanceMonitoring.commit();
}
JS_PUBLIC_API(void)
ResetPerformanceMonitoring(JSRuntime* rt)
{
    return rt->performanceMonitoring.reset();
}
JS_PUBLIC_API(void)
DisposePerformanceMonitoring(JSRuntime* rt)
{
    return rt->performanceMonitoring.dispose(rt);
}

JS_PUBLIC_API(bool)
SetStopwatchIsMonitoringJank(JSRuntime* rt, bool value)
{
    return rt->performanceMonitoring.setIsMonitoringJank(value);
}
JS_PUBLIC_API(bool)
GetStopwatchIsMonitoringJank(JSRuntime* rt)
{
    return rt->performanceMonitoring.isMonitoringJank();
}

JS_PUBLIC_API(bool)
SetStopwatchIsMonitoringCPOW(JSRuntime* rt, bool value)
{
    return rt->performanceMonitoring.setIsMonitoringCPOW(value);
}
JS_PUBLIC_API(bool)
GetStopwatchIsMonitoringCPOW(JSRuntime* rt)
{
    return rt->performanceMonitoring.isMonitoringCPOW();
}

JS_PUBLIC_API(void)
GetPerfMonitoringTestCpuRescheduling(JSRuntime* rt, uint64_t* stayed, uint64_t* moved)
{
    *stayed = rt->performanceMonitoring.testCpuRescheduling.stayed;
    *moved = rt->performanceMonitoring.testCpuRescheduling.moved;
}

JS_PUBLIC_API(void)
AddCPOWPerformanceDelta(JSRuntime* rt, uint64_t delta)
{
    rt->performanceMonitoring.totalCPOWTime += delta;
}


} // namespace js

