summaryrefslogtreecommitdiff
path: root/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/SamplingTool.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/javascriptcore/JavaScriptCore/bytecode/SamplingTool.h')
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/bytecode/SamplingTool.h418
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