/*
 * 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 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 ScopeSampleRecord {
        ScopeSampleRecord(ScopeNode* scope)
            : m_scope(scope)
            , m_codeBlock(0)
            , m_sampleCount(0)
            , m_opcodeSampleCount(0)
            , m_samples(0)
            , m_size(0)
        {
        }
        
        ~ScopeSampleRecord()
        {
            if (m_samples)
                free(m_samples);
        }
        
        void sample(CodeBlock*, Instruction*);

        RefPtr<ScopeNode> m_scope;
        CodeBlock* m_codeBlock;
        int m_sampleCount;
        int m_opcodeSampleCount;
        int* m_samples;
        unsigned m_size;
    };

    typedef WTF::HashMap<ScopeNode*, ScopeSampleRecord*> ScopeSampleRecordMap;

    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 class CallRecord;
        friend class HostCallRecord;
        
#if ENABLE(OPCODE_SAMPLING)
        class CallRecord : 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 : 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 ScopeSampleRecordMap())
#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(ScopeNode* 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_scopeSampleMapMutex;
        OwnPtr<ScopeSampleRecordMap> 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
