/*
 * 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 <wtf/Assertions.h>
#include <wtf/HashMap.h>
#include <wtf/Threading.h>

#include "Nodes.h"
#include "Opcode.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(ScriptExecutable* executable)
            : m_executable(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*);

#if COMPILER(WINSCW) || COMPILER(ACC)
        ScriptExecutable* m_executable;
#else
        RefPtr<ScriptExecutable> m_executable;
#endif
        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 : public Noncopyable {
        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 : public Noncopyable {
        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 JIT;
        friend class DeletableSamplingCounter;
    public:
        void count(uint32_t count = 1)
        {
            m_counter += count;
        }

        static void dump();

    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
