/*
 * Copyright (C) 2008 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 Computer, 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 "Nodes.h"
#include "Opcode.h"
#include "SamplingCounter.h"
#include <wtf/Assertions.h>
#include <wtf/Atomics.h>
#include <wtf/HashMap.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(JSGlobalData& globalData, ScriptExecutable* executable)
            : m_executable(globalData, 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*, OwnPtr<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 {
    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(adoptPtr(new 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(JSGlobalData&, 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)
        Mutex m_scriptSampleMapMutex;
        OwnPtr<ScriptSampleRecordMap> m_scopeSampleMap;
#endif
    };

} // namespace JSC

#endif // SamplingTool_h
