/* -*- 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_SPSProfiler_h
#define vm_SPSProfiler_h

#include <stddef.h>

#include "mozilla/DebugOnly.h"
#include "mozilla/GuardObjects.h"
#include "mozilla/HashFunctions.h"

#include "js/Utility.h"
#include "jsscript.h"

/*
 * SPS Profiler integration with the JS Engine
 * https://developer.mozilla.org/en/Performance/Profiling_with_the_Built-in_Profiler
 *
 * The SPS profiler (found in tools/profiler) is an implementation of a profiler
 * which has the ability to walk the C++ stack as well as use instrumentation to
 * gather information. When dealing with JS, however, SPS needs integration
 * with the engine because otherwise it is very difficult to figure out what
 * javascript is executing.
 *
 * The current method of integration with SPS is a form of instrumentation:
 * every time a JS function is entered, a bit of information is pushed onto a
 * stack that SPS owns and maintains. This information is then popped at the end
 * of the JS function. SPS informs the JS engine of this stack at runtime, and
 * it can by turned on/off dynamically.
 *
 * The SPS stack has three parameters: a base pointer, a size, and a maximum
 * size. The stack is the ProfileEntry stack which will have information written
 * to it. The size location is a pointer to an integer which represents the
 * current size of the stack (number of valid frames). This size will be
 * modified when JS functions are called. The maximum specified is the maximum
 * capacity of the ProfileEntry stack.
 *
 * Throughout execution, the size of the stack recorded in memory may exceed the
 * maximum. The JS engine will not write any information past the maximum limit,
 * but it will still maintain the size of the stack. SPS code is aware of this
 * and iterates the stack accordingly.
 *
 * There is some information pushed on the SPS stack for every JS function that
 * is entered. First is a char* pointer of a description of what function was
 * entered. Currently this string is of the form "function (file:line)" if
 * there's a function name, or just "file:line" if there's no function name
 * available. The other bit of information is the relevant C++ (native) stack
 * pointer. This stack pointer is what enables the interleaving of the C++ and
 * the JS stack. Finally, throughout execution of the function, some extra
 * information may be updated on the ProfileEntry structure.
 *
 * = Profile Strings
 *
 * The profile strings' allocations and deallocation must be carefully
 * maintained, and ideally at a very low overhead cost. For this reason, the JS
 * engine maintains a mapping of all known profile strings. These strings are
 * keyed in lookup by a JSScript*, but are serialized with a JSFunction*,
 * JSScript* pair. A JSScript will destroy its corresponding profile string when
 * the script is finalized.
 *
 * For this reason, a char* pointer pushed on the SPS stack is valid only while
 * it is on the SPS stack. SPS uses sampling to read off information from this
 * instrumented stack, and it therefore copies the string byte for byte when a
 * JS function is encountered during sampling.
 *
 * = Native Stack Pointer
 *
 * The actual value pushed as the native pointer is NULL for most JS functions.
 * The reason for this is that there's actually very little correlation between
 * the JS stack and the C++ stack because many JS functions all run in the same
 * C++ frame, or can even go backwards in C++ when going from the JIT back to
 * the interpreter.
 *
 * To alleviate this problem, all JS functions push NULL as their "native stack
 * pointer" to indicate that it's a JS function call. The function RunScript(),
 * however, pushes an actual C++ stack pointer onto the SPS stack. This way when
 * interleaving C++ and JS, if SPS sees a NULL native stack pointer on the SPS
 * stack, it looks backwards for the first non-NULL pointer and uses that for
 * all subsequent NULL native stack pointers.
 *
 * = Line Numbers
 *
 * One goal of sampling is to get both a backtrace of the JS stack, but also
 * know where within each function on the stack execution currently is. For
 * this, each ProfileEntry has a 'pc' field to tell where its execution
 * currently is. This field is updated whenever a call is made to another JS
 * function, and for the JIT it is also updated whenever the JIT is left.
 *
 * This field is in a union with a uint32_t 'line' so that C++ can make use of
 * the field as well. It was observed that tracking 'line' via PCToLineNumber in
 * JS was far too expensive, so that is why the pc instead of the translated
 * line number is stored.
 *
 * As an invariant, if the pc is NULL, then the JIT is currently executing
 * generated code. Otherwise execution is in another JS function or in C++. With
 * this in place, only the top entry of the stack can ever have NULL as its pc.
 * Additionally with this invariant, it is possible to maintain mappings of JIT
 * code to pc which can be accessed safely because they will only be accessed
 * from a signal handler when the JIT code is executing.
 */

class JSFunction;

namespace js {

class ProfileEntry;

typedef HashMap<JSScript*, const char*, DefaultHasher<JSScript*>, SystemAllocPolicy>
        ProfileStringMap;

class SPSEntryMarker;

class SPSProfiler
{
    friend class SPSEntryMarker;

    JSRuntime            *rt;
    ProfileStringMap     strings;
    ProfileEntry         *stack_;
    uint32_t             *size_;
    uint32_t             max_;
    bool                 slowAssertions;
    uint32_t             enabled_;

    const char *allocProfileString(JSContext *cx, JSScript *script,
                                   JSFunction *function);
    void push(const char *string, void *sp, JSScript *script, jsbytecode *pc);
    void pop();

  public:
    SPSProfiler(JSRuntime *rt);
    ~SPSProfiler();

    uint32_t **addressOfSizePointer() {
        return &size_;
    }

    uint32_t *addressOfMaxSize() {
        return &max_;
    }

    ProfileEntry **addressOfStack() {
        return &stack_;
    }

    uint32_t *sizePointer() { return size_; }
    uint32_t maxSize() { return max_; }
    ProfileEntry *stack() { return stack_; }

    /* management of whether instrumentation is on or off */
    bool enabled() { JS_ASSERT_IF(enabled_, installed()); return enabled_; }
    bool installed() { return stack_ != NULL && size_ != NULL; }
    void enable(bool enabled);
    void enableSlowAssertions(bool enabled) { slowAssertions = enabled; }
    bool slowAssertionsEnabled() { return slowAssertions; }

    /*
     * Functions which are the actual instrumentation to track run information
     *
     *   - enter: a function has started to execute
     *   - updatePC: updates the pc information about where a function
     *               is currently executing
     *   - exit: this function has ceased execution, and no further
     *           entries/exits will be made
     */
    bool enter(JSContext *cx, JSScript *script, JSFunction *maybeFun);
    void exit(JSContext *cx, JSScript *script, JSFunction *maybeFun);
    void updatePC(JSScript *script, jsbytecode *pc) {
        if (enabled() && *size_ - 1 < max_) {
            JS_ASSERT(*size_ > 0);
            JS_ASSERT(stack_[*size_ - 1].script() == script);
            stack_[*size_ - 1].setPC(pc);
        }
    }

    /* Enter a C++ function. */
    void enterNative(const char *string, void *sp);
    void exitNative() { pop(); }

    jsbytecode *ipToPC(JSScript *script, size_t ip) { return NULL; }

    void setProfilingStack(ProfileEntry *stack, uint32_t *size, uint32_t max);
    const char *profileString(JSContext *cx, JSScript *script, JSFunction *maybeFun);
    void onScriptFinalized(JSScript *script);

    /* meant to be used for testing, not recommended to call in normal code */
    size_t stringsCount() { return strings.count(); }
    void stringsReset() { strings.clear(); }

    uint32_t *addressOfEnabled() {
        return &enabled_;
    }
};

/*
 * This class is used in RunScript() to push the marker onto the sampling stack
 * that we're about to enter JS function calls. This is the only time in which a
 * valid stack pointer is pushed to the sampling stack.
 */
class SPSEntryMarker
{
  public:
    SPSEntryMarker(JSRuntime *rt
                   MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
    ~SPSEntryMarker();

  private:
    SPSProfiler *profiler;
    mozilla::DebugOnly<uint32_t> size_before;
    MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
};

/*
 * SPS is the profiling backend used by the JS engine to enable time profiling.
 * More information can be found in vm/SPSProfiler.{h,cpp}. This class manages
 * the instrumentation portion of the profiling for JIT code.
 *
 * The instrumentation tracks entry into functions, leaving those functions via
 * a function call, reentering the functions from a function call, and exiting
 * the functions from returning. This class also handles inline frames and
 * manages the instrumentation which needs to be attached to them as well.
 *
 * The basic methods which emit instrumentation are at the end of this class,
 * and the management functions are all described in the middle.
 */
template<class Assembler, class Register>
class SPSInstrumentation
{
    /* Because of inline frames, this is a nested structure in a vector */
    struct FrameState {
        JSScript *script; // script for this frame, NULL if not pushed yet
        bool skipNext;    // should the next call to reenter be skipped?
        int  left;        // number of leave() calls made without a matching reenter()
    };

    SPSProfiler *profiler_; // Instrumentation location management

    Vector<FrameState, 1, SystemAllocPolicy> frames;
    FrameState *frame;

  public:
    /*
     * Creates instrumentation which writes information out the the specified
     * profiler's stack and constituent fields.
     */
    SPSInstrumentation(SPSProfiler *profiler)
      : profiler_(profiler), frame(NULL)
    {
        enterInlineFrame();
    }

    /* Small proxies around SPSProfiler */
    bool enabled() { return profiler_ && profiler_->enabled(); }
    SPSProfiler *profiler() { JS_ASSERT(enabled()); return profiler_; }
    bool slowAssertions() { return enabled() && profiler_->slowAssertionsEnabled(); }

    /* Signals an inline function returned, reverting to the previous state */
    void leaveInlineFrame() {
        if (!enabled())
            return;
        JS_ASSERT(frame->left == 0);
        JS_ASSERT(frame->script != NULL);
        frames.shrinkBy(1);
        JS_ASSERT(frames.length() > 0);
        frame = &frames[frames.length() - 1];
    }

    /* Saves the current state and assumes a fresh one for the inline function */
    bool enterInlineFrame() {
        if (!enabled())
            return true;
        JS_ASSERT_IF(frame != NULL, frame->script != NULL);
        JS_ASSERT_IF(frame != NULL, frame->left == 1);
        if (!frames.growBy(1))
            return false;
        frame = &frames[frames.length() - 1];
        frame->script = NULL;
        frame->skipNext = false;
        frame->left = 0;
        return true;
    }

    /* Number of inline frames currently active (doesn't include original one) */
    unsigned inliningDepth() {
        return frames.length() - 1;
    }

    /*
     * When debugging or with slow assertions, sometimes a C++ method will be
     * invoked to perform the pop operation from the SPS stack. When we leave
     * JIT code, we need to record the current PC, but upon reentering JIT code,
     * no update back to NULL should happen. This method exists to flag this
     * behavior. The next leave() will emit instrumentation, but the following
     * reenter() will be a no-op.
     */
    void skipNextReenter() {
        /* If we've left the frame, the reenter will be skipped anyway */
        if (!enabled() || frame->left != 0)
            return;
        JS_ASSERT(frame->script);
        JS_ASSERT(!frame->skipNext);
        frame->skipNext = true;
    }

    /*
     * In some cases, a frame needs to be flagged as having been pushed, but no
     * instrumentation should be emitted. This updates internal state to flag
     * that further instrumentation should actually be emitted.
     */
    void setPushed(JSScript *script) {
        if (!enabled())
            return;
        JS_ASSERT(frame->left == 0);
        frame->script = script;
    }

    /*
     * Flags entry into a JS function for the first time. Before this is called,
     * no instrumentation is emitted, but after this instrumentation is emitted.
     */
    bool push(JSContext *cx, JSScript *script, Assembler &masm, Register scratch) {
        if (!enabled())
            return true;
        const char *string = profiler_->profileString(cx, script,
                                                      script->function());
        if (string == NULL)
            return false;
        masm.spsPushFrame(profiler_, string, script, scratch);
        setPushed(script);
        return true;
    }

    /*
     * Signifies that C++ performed the push() for this function. C++ always
     * sets the current PC to something non-null, however, so as soon as JIT
     * code is reentered this updates the current pc to NULL.
     */
    void pushManual(JSScript *script, Assembler &masm, Register scratch) {
        if (!enabled())
            return;
        masm.spsUpdatePCIdx(profiler_, ProfileEntry::NullPCIndex, scratch);
        setPushed(script);
    }

    /*
     * Signals that the current function is leaving for a function call. This
     * can happen both on JS function calls and also calls to C++. This
     * internally manages how many leave() calls have been seen, and only the
     * first leave() emits instrumentation. Similarly, only the last
     * corresponding reenter() actually emits instrumentation.
     */
    void leave(jsbytecode *pc, Assembler &masm, Register scratch) {
        if (enabled() && frame->script && frame->left++ == 0) {
            JS_ASSERT(frame->script->code <= pc &&
                      pc < frame->script->code + frame->script->length);
            masm.spsUpdatePCIdx(profiler_, pc - frame->script->code, scratch);
        }
    }

    /*
     * Flags that the leaving of the current function has returned. This tracks
     * state with leave() to only emit instrumentation at proper times.
     */
    void reenter(Assembler &masm, Register scratch) {
        if (!enabled() || !frame->script || frame->left-- != 1)
            return;
        if (frame->skipNext)
            frame->skipNext = false;
        else
            masm.spsUpdatePCIdx(profiler_, ProfileEntry::NullPCIndex, scratch);
    }

    /*
     * Signifies exiting a JS frame, popping the SPS entry. Because there can be
     * multiple return sites of a function, this does not cease instrumentation
     * emission.
     */
    void pop(Assembler &masm, Register scratch) {
        if (enabled()) {
            JS_ASSERT(frame->left == 0);
            JS_ASSERT(frame->script);
            masm.spsPopFrame(profiler_, scratch);
        }
    }
};

} /* namespace js */

#endif /* vm_SPSProfiler_h */
