/*
 * 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 <wtf/Assertions.h>
#include <wtf/HashMap.h>
#include <wtf/Threading.h>

namespace JSC {

    class ScriptExecutable;

    class SamplingFlags {
        friend class JIT;
    public:
        static void start();
        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;
        };
    
#endif
    private:
        static uint32_t s_flags;
#if ENABLE(SAMPLING_FLAGS)
        static uint64_t s_flagCounts[33];
#endif
    };

    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 WTF::HashMap<ScriptExecutable*, ScriptSampleRecord*> ScriptSampleRecordMap;

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

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

        static void* threadStartFunc(void*);
    };

    class SamplingTool {
    public:
        friend struct CallRecord;
        friend class HostCallRecord;
        
#if ENABLE(OPCODE_SAMPLING)
        class CallRecord {
            WTF_MAKE_NONCOPYABLE(CallRecord);
        public:
            CallRecord(SamplingTool* samplingTool)
                : m_samplingTool(samplingTool)
                , m_savedSample(samplingTool->m_sample)
                , m_savedCodeBlock(samplingTool->m_codeBlock)
            {
            }

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

        private:
            SamplingTool* m_samplingTool;
            intptr_t m_savedSample;
            CodeBlock* m_savedCodeBlock;
        };
        
        class HostCallRecord : public CallRecord {
        public:
            HostCallRecord(SamplingTool* samplingTool)
                : CallRecord(samplingTool)
            {
                samplingTool->m_sample |= 0x1;
            }
        };
#else
        class CallRecord {
            WTF_MAKE_NONCOPYABLE(CallRecord);
        public:
            CallRecord(SamplingTool*)
            {
            }
        };

        class HostCallRecord : public CallRecord {
        public:
            HostCallRecord(SamplingTool* samplingTool)
                : CallRecord(samplingTool)
            {
            }
        };
#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(new ScriptSampleRecordMap())
#endif
        {
            memset(m_opcodeSamples, 0, sizeof(m_opcodeSamples));
            memset(m_opcodeSamplesInCTIFunctions, 0, sizeof(m_opcodeSamplesInCTIFunctions));
        }

        ~SamplingTool()
        {
#if ENABLE(CODEBLOCK_SAMPLING)
            deleteAllValues(*m_scopeSampleMap);
#endif
        }

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

        void notifyOfScope(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
    };

    // AbstractSamplingCounter:
    //
    // Implements a named set of counters, printed on exit if ENABLE(SAMPLING_COUNTERS).
    // See subclasses below, SamplingCounter, GlobalSamplingCounter and DeletableSamplingCounter.
    class AbstractSamplingCounter {
        friend class DeletableSamplingCounter;
    public:
        void count(uint32_t count = 1)
        {
            m_counter += count;
        }

        static void dump();

        int64_t* addressOfCounter() { return &m_counter; }

    protected:
        // Effectively the contructor, however called lazily in the case of GlobalSamplingCounter.
        void init(const char* name)
        {
            m_counter = 0;
            m_name = name;

            // Set m_next to point to the head of the chain, and inform whatever is
            // currently at the head that this node will now hold the pointer to it.
            m_next = s_abstractSamplingCounterChain;
            s_abstractSamplingCounterChain->m_referer = &m_next;
            // Add this node to the head of the list.
            s_abstractSamplingCounterChain = this;
            m_referer = &s_abstractSamplingCounterChain;
        }

        int64_t m_counter;
        const char* m_name;
        AbstractSamplingCounter* m_next;
        // This is a pointer to the pointer to this node in the chain; used to
        // allow fast linked list deletion.
        AbstractSamplingCounter** m_referer;
        // Null object used to detect end of static chain.
        static AbstractSamplingCounter s_abstractSamplingCounterChainEnd;
        static AbstractSamplingCounter* s_abstractSamplingCounterChain;
        static bool s_completed;
    };

#if ENABLE(SAMPLING_COUNTERS)
    // SamplingCounter:
    //
    // This class is suitable and (hopefully!) convenient for cases where a counter is
    // required within the scope of a single function.  It can be instantiated as a
    // static variable since it contains a constructor but not a destructor (static
    // variables in WebKit cannot have destructors).
    //
    // For example:
    //
    // void someFunction()
    // {
    //     static SamplingCounter countMe("This is my counter.  There are many like it, but this one is mine.");
    //     countMe.count();
    //     // ...
    // }
    //
    class SamplingCounter : public AbstractSamplingCounter {
    public:
        SamplingCounter(const char* name) { init(name); }
    };

    // GlobalSamplingCounter:
    //
    // This class is suitable for use where a counter is to be declared globally,
    // since it contains neither a constructor nor destructor.  Instead, ensure
    // that 'name()' is called to provide the counter with a name (and also to
    // allow it to be printed out on exit).
    //
    // GlobalSamplingCounter globalCounter;
    //
    // void firstFunction()
    // {
    //     // Put this within a function that is definitely called!
    //     // (Or alternatively alongside all calls to 'count()').
    //     globalCounter.name("I Name You Destroyer.");
    //     globalCounter.count();
    //     // ...
    // }
    //
    // void secondFunction()
    // {
    //     globalCounter.count();
    //     // ...
    // }
    //
    class GlobalSamplingCounter : public AbstractSamplingCounter {
    public:
        void name(const char* name)
        {
            // Global objects should be mapped in zero filled memory, so this should
            // be a safe (albeit not necessarily threadsafe) check for 'first call'.
            if (!m_next)
                init(name);
        }
    };

    // DeletableSamplingCounter:
    //
    // The above classes (SamplingCounter, GlobalSamplingCounter), are intended for
    // use within a global or static scope, and as such cannot have a destructor.
    // This means there is no convenient way for them to remove themselves from the
    // static list of counters, and should an instance of either class be freed
    // before 'dump()' has walked over the list it will potentially walk over an
    // invalid pointer.
    //
    // This class is intended for use where the counter may possibly be deleted before
    // the program exits.  Should this occur, the counter will print it's value to
    // stderr, and remove itself from the static list.  Example:
    //
    // DeletableSamplingCounter* counter = new DeletableSamplingCounter("The Counter With No Name");
    // counter->count();
    // delete counter;
    //
    class DeletableSamplingCounter : public AbstractSamplingCounter {
    public:
        DeletableSamplingCounter(const char* name) { init(name); }

        ~DeletableSamplingCounter()
        {
            if (!s_completed)
                fprintf(stderr, "DeletableSamplingCounter \"%s\" deleted early (with count %lld)\n", m_name, m_counter);
            // Our m_referer pointer should know where the pointer to this node is,
            // and m_next should know that this node is the previous node in the list.
            ASSERT(*m_referer == this);
            ASSERT(m_next->m_referer == &m_next);
            // Remove this node from the list, and inform m_next that we have done so.
            m_next->m_referer = m_referer;
            *m_referer = m_next;
        }
    };
#endif

} // namespace JSC

#endif // SamplingTool_h
