diff options
author | Konstantin Tokarev <annulen@yandex.ru> | 2016-08-25 19:20:41 +0300 |
---|---|---|
committer | Konstantin Tokarev <annulen@yandex.ru> | 2017-02-02 12:30:55 +0000 |
commit | 6882a04fb36642862b11efe514251d32070c3d65 (patch) | |
tree | b7959826000b061fd5ccc7512035c7478742f7b0 /Source/JavaScriptCore/runtime/SamplingProfiler.h | |
parent | ab6df191029eeeb0b0f16f127d553265659f739e (diff) | |
download | qtwebkit-6882a04fb36642862b11efe514251d32070c3d65.tar.gz |
Imported QtWebKit TP3 (git b57bc6801f1876c3220d5a4bfea33d620d477443)
Change-Id: I3b1d8a2808782c9f34d50240000e20cb38d3680f
Reviewed-by: Konstantin Tokarev <annulen@yandex.ru>
Diffstat (limited to 'Source/JavaScriptCore/runtime/SamplingProfiler.h')
-rw-r--r-- | Source/JavaScriptCore/runtime/SamplingProfiler.h | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/Source/JavaScriptCore/runtime/SamplingProfiler.h b/Source/JavaScriptCore/runtime/SamplingProfiler.h new file mode 100644 index 000000000..bd9d9425c --- /dev/null +++ b/Source/JavaScriptCore/runtime/SamplingProfiler.h @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2016 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. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 INC. OR + * 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 SamplingProfiler_h +#define SamplingProfiler_h + +#if ENABLE(SAMPLING_PROFILER) + +#include "CallFrame.h" +#include "MachineStackMarker.h" +#include <wtf/HashSet.h> +#include <wtf/Lock.h> +#include <wtf/Stopwatch.h> +#include <wtf/Vector.h> +#include <wtf/WorkQueue.h> + +namespace JSC { + +class VM; +class ExecutableBase; + +class SamplingProfiler : public ThreadSafeRefCounted<SamplingProfiler> { + WTF_MAKE_FAST_ALLOCATED; +public: + + struct UnprocessedStackFrame { + UnprocessedStackFrame(CodeBlock* codeBlock, EncodedJSValue callee, CallSiteIndex callSiteIndex) + : unverifiedCallee(callee) + , verifiedCodeBlock(codeBlock) + , callSiteIndex(callSiteIndex) + { } + UnprocessedStackFrame() + { + unverifiedCallee = JSValue::encode(JSValue()); + verifiedCodeBlock = nullptr; + } + + EncodedJSValue unverifiedCallee; + CodeBlock* verifiedCodeBlock; + CallSiteIndex callSiteIndex; + }; + + enum class FrameType { + Executable, + Host, + Unknown + }; + + struct StackFrame { + StackFrame(ExecutableBase* executable) + : frameType(FrameType::Executable) + , executable(executable) + { } + + StackFrame() + { } + + FrameType frameType { FrameType::Unknown }; + ExecutableBase* executable { nullptr }; + JSObject* callee { nullptr }; + // These attempt to be expression-level line and column number. + unsigned lineNumber { std::numeric_limits<unsigned>::max() }; + unsigned columnNumber { std::numeric_limits<unsigned>::max() }; + + bool hasExpressionInfo() const + { + return lineNumber != std::numeric_limits<unsigned>::max() + && columnNumber != std::numeric_limits<unsigned>::max(); + } + + // These are function-level data. + String nameFromCallee(VM&); + String displayName(VM&); + String displayNameForJSONTests(VM&); // Used for JSC stress tests because they want the "(anonymous function)" string for anonymous functions and they want "(eval)" for eval'd code. + int functionStartLine(); + unsigned functionStartColumn(); + intptr_t sourceID(); + String url(); + }; + + struct UnprocessedStackTrace { + double timestamp; + void* topPC; + bool topFrameIsLLInt; + void* llintPC; + Vector<UnprocessedStackFrame> frames; + }; + + struct StackTrace { + double timestamp; + Vector<StackFrame> frames; + StackTrace() + { } + StackTrace(StackTrace&& other) + : timestamp(other.timestamp) + , frames(WTFMove(other.frames)) + { } + }; + + SamplingProfiler(VM&, RefPtr<Stopwatch>&&); + ~SamplingProfiler(); + void noticeJSLockAcquisition(); + void noticeVMEntry(); + void shutdown(); + void visit(SlotVisitor&); + Lock& getLock() { return m_lock; } + void setTimingInterval(std::chrono::microseconds interval) { m_timingInterval = interval; } + JS_EXPORT_PRIVATE void start(); + void start(const LockHolder&); + void stop(); + void stop(const LockHolder&); + Vector<StackTrace> releaseStackTraces(const LockHolder&); + JS_EXPORT_PRIVATE String stackTracesAsJSON(); + JS_EXPORT_PRIVATE void noticeCurrentThreadAsJSCExecutionThread(); + void noticeCurrentThreadAsJSCExecutionThread(const LockHolder&); + void processUnverifiedStackTraces(); // You should call this only after acquiring the lock. + double totalTime(const LockHolder&) { return m_totalTime; } + void setStopWatch(const LockHolder&, Ref<Stopwatch>&& stopwatch) { m_stopwatch = WTFMove(stopwatch); } + +private: + void dispatchIfNecessary(const LockHolder&); + void dispatchFunction(const LockHolder&); + void pause(); + void clearData(const LockHolder&); + + VM& m_vm; + RefPtr<Stopwatch> m_stopwatch; + Vector<StackTrace> m_stackTraces; + Vector<UnprocessedStackTrace> m_unprocessedStackTraces; + std::chrono::microseconds m_timingInterval; + double m_lastTime; + double m_totalTime; + Ref<WorkQueue> m_timerQueue; + std::function<void ()> m_handler; + Lock m_lock; + MachineThreads::Thread* m_jscExecutionThread; + bool m_isActive; + bool m_isPaused; + bool m_hasDispatchedFunction; + HashSet<JSCell*> m_liveCellPointers; + Vector<UnprocessedStackFrame> m_currentFrames; +}; + +} // namespace JSC + +namespace WTF { + +void printInternal(PrintStream&, JSC::SamplingProfiler::FrameType); + +} // namespace WTF + +#endif // ENABLE(SAMPLING_PROFILER) + +#endif // SamplingProfiler_h |