/*
 * Copyright (C) 2008, 2013, 2015 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef SamplingTool_h
#define SamplingTool_h

#include "Strong.h"
#include "Opcode.h"
#include "SamplingCounter.h"
#include <wtf/Assertions.h>
#include <wtf/Atomics.h>
#include <wtf/HashMap.h>
#include <wtf/Lock.h>
#include <wtf/MainThread.h>
#include <wtf/Spectrum.h>
#include <wtf/Threading.h>

namespace JSC {

    class ScriptExecutable;

    class SamplingFlags {
    public:
        JS_EXPORT_PRIVATE static void start();
        JS_EXPORT_PRIVATE static void stop();

#if ENABLE(SAMPLING_FLAGS)
        static void setFlag(unsigned flag)
        {
            ASSERT(flag >= 1);
            ASSERT(flag <= 32);
            s_flags |= 1u << (flag - 1);
        }

        static void clearFlag(unsigned flag)
        {
            ASSERT(flag >= 1);
            ASSERT(flag <= 32);
            s_flags &= ~(1u << (flag - 1));
        }

        static void sample();

        class ScopedFlag {
        public:
            ScopedFlag(int flag)
                : m_flag(flag)
            {
                setFlag(flag);
            }

            ~ScopedFlag()
            {
                clearFlag(m_flag);
            }

        private:
            int m_flag;
        };
    
        static const void* addressOfFlags()
        {
            return &s_flags;
        }

#endif
    private:
        JS_EXPORTDATA static uint32_t s_flags;
#if ENABLE(SAMPLING_FLAGS)
        static uint64_t s_flagCounts[33];
#endif
    };

#if ENABLE(SAMPLING_REGIONS)
    class SamplingRegion {
    public:
        // Create a scoped sampling region using a C string constant name that describes
        // what you are doing. This must be a string constant that persists for the
        // lifetime of the process and is immutable.
        SamplingRegion(const char* name)
        {
            if (!isMainThread()) {
                m_name = 0;
                return;
            }
            
            m_name = name;
            exchangeCurrent(this, &m_previous);
            ASSERT(!m_previous || m_previous > this);
        }
        
        ~SamplingRegion()
        {
            if (!m_name)
                return;
            
            ASSERT(bitwise_cast<SamplingRegion*>(s_currentOrReserved & ~1) == this);
            exchangeCurrent(m_previous);
        }
        
        static void sample();
        
        JS_EXPORT_PRIVATE static void dump();
        
    private:
        const char* m_name;
        SamplingRegion* m_previous;

        static void exchangeCurrent(SamplingRegion* current, SamplingRegion** previousPtr = 0)
        {
            uintptr_t previous;
            while (true) {
                previous = s_currentOrReserved;
                
                // If it's reserved (i.e. sampling thread is reading it), loop around.
                if (previous & 1) {
#if OS(UNIX)
                    sched_yield();
#endif
                    continue;
                }
                
                // If we're going to CAS, then make sure previous is set.
                if (previousPtr)
                    *previousPtr = bitwise_cast<SamplingRegion*>(previous);
                
                if (WTF::weakCompareAndSwapUIntPtr(&s_currentOrReserved, previous, bitwise_cast<uintptr_t>(current)))
                    break;
            }
        }
        
        static void dumpInternal();

        class Locker {
        public:
            Locker();
            ~Locker();
        };

        static volatile uintptr_t s_currentOrReserved;
        
        // rely on identity hashing of string constants
        static Spectrum<const char*>* s_spectrum;
        
        static unsigned long s_noneOfTheAbove;
        
        static unsigned s_numberOfSamplesSinceDump;
    };
#else // ENABLE(SAMPLING_REGIONS)
    class SamplingRegion {
    public:
        SamplingRegion(const char*) { }
        JS_EXPORT_PRIVATE void dump();
    };
#endif // ENABLE(SAMPLING_REGIONS)

    class CodeBlock;
    class ExecState;
    class Interpreter;
    class ScopeNode;
    struct Instruction;

    struct ScriptSampleRecord {
        ScriptSampleRecord(VM& vm, ScriptExecutable* executable)
            : m_executable(vm, executable)
            , m_codeBlock(0)
            , m_sampleCount(0)
            , m_opcodeSampleCount(0)
            , m_samples(0)
            , m_size(0)
        {
        }
        
        ~ScriptSampleRecord()
        {
            if (m_samples)
                free(m_samples);
        }
        
        void sample(CodeBlock*, Instruction*);

        Strong<ScriptExecutable> m_executable;
        CodeBlock* m_codeBlock;
        int m_sampleCount;
        int m_opcodeSampleCount;
        int* m_samples;
        unsigned m_size;
    };

    typedef HashMap<ScriptExecutable*, std::unique_ptr<ScriptSampleRecord>> ScriptSampleRecordMap;

    class SamplingThread {
    public:
        // Sampling thread state.
        static bool s_running;
        static unsigned s_hertz;
        static ThreadIdentifier s_samplingThread;

        JS_EXPORT_PRIVATE static void start(unsigned hertz=10000);
        JS_EXPORT_PRIVATE static void stop();

        static void threadStartFunc(void*);
    };

    class SamplingTool {
        WTF_MAKE_FAST_ALLOCATED;
    public:
        friend struct CallRecord;
        
#if ENABLE(OPCODE_SAMPLING)
        class CallRecord {
            WTF_MAKE_NONCOPYABLE(CallRecord);
        public:
            CallRecord(SamplingTool* samplingTool, bool isHostCall = false)
                : m_samplingTool(samplingTool)
                , m_savedSample(samplingTool->m_sample)
                , m_savedCodeBlock(samplingTool->m_codeBlock)
            {
                if (isHostcall)
                    samplingTool->m_sample |= 0x1;
            }

            ~CallRecord()
            {
                m_samplingTool->m_sample = m_savedSample;
                m_samplingTool->m_codeBlock = m_savedCodeBlock;
            }

        private:
            SamplingTool* m_samplingTool;
            intptr_t m_savedSample;
            CodeBlock* m_savedCodeBlock;
        };
#else
        class CallRecord {
            WTF_MAKE_NONCOPYABLE(CallRecord);
        public:
            CallRecord(SamplingTool*, bool = false)
            {
            }
        };
#endif

        SamplingTool(Interpreter* interpreter)
            : m_interpreter(interpreter)
            , m_codeBlock(0)
            , m_sample(0)
            , m_sampleCount(0)
            , m_opcodeSampleCount(0)
#if ENABLE(CODEBLOCK_SAMPLING)
            , m_scopeSampleMap(std::make_unique<ScriptSampleRecordMap>)
#endif
        {
            memset(m_opcodeSamples, 0, sizeof(m_opcodeSamples));
            memset(m_opcodeSamplesInCTIFunctions, 0, sizeof(m_opcodeSamplesInCTIFunctions));
        }

        JS_EXPORT_PRIVATE void setup();
        void dump(ExecState*);

        void notifyOfScope(VM&, ScriptExecutable* scope);

        void sample(CodeBlock* codeBlock, Instruction* vPC)
        {
            ASSERT(!(reinterpret_cast<intptr_t>(vPC) & 0x3));
            m_codeBlock = codeBlock;
            m_sample = reinterpret_cast<intptr_t>(vPC);
        }

        CodeBlock** codeBlockSlot() { return &m_codeBlock; }
        intptr_t* sampleSlot() { return &m_sample; }

        void* encodeSample(Instruction* vPC, bool inCTIFunction = false, bool inHostFunction = false)
        {
            ASSERT(!(reinterpret_cast<intptr_t>(vPC) & 0x3));
            return reinterpret_cast<void*>(reinterpret_cast<intptr_t>(vPC) | (static_cast<intptr_t>(inCTIFunction) << 1) | static_cast<intptr_t>(inHostFunction));
        }

        static void sample();

    private:
        class Sample {
        public:
            Sample(volatile intptr_t sample, CodeBlock* volatile codeBlock)
                : m_sample(sample)
                , m_codeBlock(codeBlock)
            {
            }
            
            bool isNull() { return !m_sample; }
            CodeBlock* codeBlock() { return m_codeBlock; }
            Instruction* vPC() { return reinterpret_cast<Instruction*>(m_sample & ~0x3); }
            bool inHostFunction() { return m_sample & 0x1; }
            bool inCTIFunction() { return m_sample & 0x2; }

        private:
            intptr_t m_sample;
            CodeBlock* m_codeBlock;
        };

        void doRun();
        static SamplingTool* s_samplingTool;
        
        Interpreter* m_interpreter;
        
        // State tracked by the main thread, used by the sampling thread.
        CodeBlock* m_codeBlock;
        intptr_t m_sample;

        // Gathered sample data.
        long long m_sampleCount;
        long long m_opcodeSampleCount;
        unsigned m_opcodeSamples[numOpcodeIDs];
        unsigned m_opcodeSamplesInCTIFunctions[numOpcodeIDs];
        
#if ENABLE(CODEBLOCK_SAMPLING)
        Lock m_scriptSampleMapMutex;
        std::unique_ptr<ScriptSampleRecordMap> m_scopeSampleMap;
#endif
    };

} // namespace JSC

#endif // SamplingTool_h
