diff options
Diffstat (limited to 'src/3rdparty/javascriptcore/JavaScriptCore/bytecode/SamplingTool.h')
-rw-r--r-- | src/3rdparty/javascriptcore/JavaScriptCore/bytecode/SamplingTool.h | 418 |
1 files changed, 0 insertions, 418 deletions
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/SamplingTool.h b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/SamplingTool.h deleted file mode 100644 index c3e6247..0000000 --- a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/SamplingTool.h +++ /dev/null @@ -1,418 +0,0 @@ -/* - * 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 |