diff options
author | Allan Sandfeld Jensen <allan.jensen@digia.com> | 2013-09-13 12:51:20 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-09-19 20:50:05 +0200 |
commit | d441d6f39bb846989d95bcf5caf387b42414718d (patch) | |
tree | e367e64a75991c554930278175d403c072de6bb8 /Source/JavaScriptCore/profiler | |
parent | 0060b2994c07842f4c59de64b5e3e430525c4b90 (diff) | |
download | qtwebkit-d441d6f39bb846989d95bcf5caf387b42414718d.tar.gz |
Import Qt5x2 branch of QtWebkit for Qt 5.2
Importing a new snapshot of webkit.
Change-Id: I2d01ad12cdc8af8cb015387641120a9d7ea5f10c
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@digia.com>
Diffstat (limited to 'Source/JavaScriptCore/profiler')
29 files changed, 1941 insertions, 54 deletions
diff --git a/Source/JavaScriptCore/profiler/Profiler.cpp b/Source/JavaScriptCore/profiler/LegacyProfiler.cpp index 9642a0684..1db2e625e 100644 --- a/Source/JavaScriptCore/profiler/Profiler.cpp +++ b/Source/JavaScriptCore/profiler/LegacyProfiler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All rights reserved. + * Copyright (C) 2008, 2012 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,15 +27,16 @@ */ #include "config.h" -#include "Profiler.h" +#include "LegacyProfiler.h" -#include "CommonIdentifiers.h" #include "CallFrame.h" #include "CodeBlock.h" +#include "CommonIdentifiers.h" #include "InternalFunction.h" #include "JSFunction.h" #include "JSGlobalObject.h" #include "Nodes.h" +#include "Operations.h" #include "Profile.h" #include "ProfileGenerator.h" #include "ProfileNode.h" @@ -49,22 +50,25 @@ static unsigned ProfilesUID = 0; static CallIdentifier createCallIdentifierFromFunctionImp(ExecState*, JSObject*, const String& defaultSourceURL, int defaultLineNumber); -Profiler* Profiler::s_sharedProfiler = 0; +LegacyProfiler* LegacyProfiler::s_sharedLegacyProfiler = 0; -Profiler* Profiler::profiler() +LegacyProfiler* LegacyProfiler::profiler() { - if (!s_sharedProfiler) - s_sharedProfiler = new Profiler(); - return s_sharedProfiler; + if (!s_sharedLegacyProfiler) + s_sharedLegacyProfiler = new LegacyProfiler(); + return s_sharedLegacyProfiler; } -void Profiler::startProfiling(ExecState* exec, const String& title) +void LegacyProfiler::startProfiling(ExecState* exec, const String& title) { ASSERT_ARG(title, !title.isNull()); + if (!exec) + return; + // Check if we currently have a Profile for this global ExecState and title. // If so return early and don't create a new Profile. - JSGlobalObject* origin = exec ? exec->lexicalGlobalObject() : 0; + JSGlobalObject* origin = exec->lexicalGlobalObject(); for (size_t i = 0; i < m_currentProfiles.size(); ++i) { ProfileGenerator* profileGenerator = m_currentProfiles[i].get(); @@ -72,14 +76,17 @@ void Profiler::startProfiling(ExecState* exec, const String& title) return; } - exec->globalData().m_enabledProfiler = this; + exec->vm().m_enabledProfiler = this; RefPtr<ProfileGenerator> profileGenerator = ProfileGenerator::create(exec, title, ++ProfilesUID); m_currentProfiles.append(profileGenerator); } -PassRefPtr<Profile> Profiler::stopProfiling(ExecState* exec, const String& title) +PassRefPtr<Profile> LegacyProfiler::stopProfiling(ExecState* exec, const String& title) { - JSGlobalObject* origin = exec ? exec->lexicalGlobalObject() : 0; + if (!exec) + return 0; + + JSGlobalObject* origin = exec->lexicalGlobalObject(); for (ptrdiff_t i = m_currentProfiles.size() - 1; i >= 0; --i) { ProfileGenerator* profileGenerator = m_currentProfiles[i].get(); if (profileGenerator->origin() == origin && (title.isNull() || profileGenerator->title() == title)) { @@ -88,7 +95,7 @@ PassRefPtr<Profile> Profiler::stopProfiling(ExecState* exec, const String& title m_currentProfiles.remove(i); if (!m_currentProfiles.size()) - exec->globalData().m_enabledProfiler = 0; + exec->vm().m_enabledProfiler = 0; return returnProfile; } @@ -97,7 +104,7 @@ PassRefPtr<Profile> Profiler::stopProfiling(ExecState* exec, const String& title return 0; } -void Profiler::stopProfiling(JSGlobalObject* origin) +void LegacyProfiler::stopProfiling(JSGlobalObject* origin) { for (ptrdiff_t i = m_currentProfiles.size() - 1; i >= 0; --i) { ProfileGenerator* profileGenerator = m_currentProfiles[i].get(); @@ -105,7 +112,7 @@ void Profiler::stopProfiling(JSGlobalObject* origin) profileGenerator->stopProfiling(); m_currentProfiles.remove(i); if (!m_currentProfiles.size()) - origin->globalData().m_enabledProfiler = 0; + origin->vm().m_enabledProfiler = 0; } } } @@ -118,14 +125,14 @@ static inline void dispatchFunctionToProfiles(ExecState* callerOrHandlerCallFram } } -void Profiler::willExecute(ExecState* callerCallFrame, JSValue function) +void LegacyProfiler::willExecute(ExecState* callerCallFrame, JSValue function) { ASSERT(!m_currentProfiles.isEmpty()); dispatchFunctionToProfiles(callerCallFrame, m_currentProfiles, &ProfileGenerator::willExecute, createCallIdentifier(callerCallFrame, function, "", 0), callerCallFrame->lexicalGlobalObject()->profileGroup()); } -void Profiler::willExecute(ExecState* callerCallFrame, const String& sourceURL, int startingLineNumber) +void LegacyProfiler::willExecute(ExecState* callerCallFrame, const String& sourceURL, int startingLineNumber) { ASSERT(!m_currentProfiles.isEmpty()); @@ -134,28 +141,28 @@ void Profiler::willExecute(ExecState* callerCallFrame, const String& sourceURL, dispatchFunctionToProfiles(callerCallFrame, m_currentProfiles, &ProfileGenerator::willExecute, callIdentifier, callerCallFrame->lexicalGlobalObject()->profileGroup()); } -void Profiler::didExecute(ExecState* callerCallFrame, JSValue function) +void LegacyProfiler::didExecute(ExecState* callerCallFrame, JSValue function) { ASSERT(!m_currentProfiles.isEmpty()); dispatchFunctionToProfiles(callerCallFrame, m_currentProfiles, &ProfileGenerator::didExecute, createCallIdentifier(callerCallFrame, function, "", 0), callerCallFrame->lexicalGlobalObject()->profileGroup()); } -void Profiler::didExecute(ExecState* callerCallFrame, const String& sourceURL, int startingLineNumber) +void LegacyProfiler::didExecute(ExecState* callerCallFrame, const String& sourceURL, int startingLineNumber) { ASSERT(!m_currentProfiles.isEmpty()); dispatchFunctionToProfiles(callerCallFrame, m_currentProfiles, &ProfileGenerator::didExecute, createCallIdentifier(callerCallFrame, JSValue(), sourceURL, startingLineNumber), callerCallFrame->lexicalGlobalObject()->profileGroup()); } -void Profiler::exceptionUnwind(ExecState* handlerCallFrame) +void LegacyProfiler::exceptionUnwind(ExecState* handlerCallFrame) { ASSERT(!m_currentProfiles.isEmpty()); dispatchFunctionToProfiles(handlerCallFrame, m_currentProfiles, &ProfileGenerator::exceptionUnwind, createCallIdentifier(handlerCallFrame, JSValue(), "", 0), handlerCallFrame->lexicalGlobalObject()->profileGroup()); } -CallIdentifier Profiler::createCallIdentifier(ExecState* exec, JSValue functionValue, const String& defaultSourceURL, int defaultLineNumber) +CallIdentifier LegacyProfiler::createCallIdentifier(ExecState* exec, JSValue functionValue, const String& defaultSourceURL, int defaultLineNumber) { if (!functionValue) return CallIdentifier(GlobalCodeExecution, defaultSourceURL, defaultLineNumber); diff --git a/Source/JavaScriptCore/profiler/Profiler.h b/Source/JavaScriptCore/profiler/LegacyProfiler.h index 6852457c7..6db57cbf2 100644 --- a/Source/JavaScriptCore/profiler/Profiler.h +++ b/Source/JavaScriptCore/profiler/LegacyProfiler.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All rights reserved. + * Copyright (C) 2008, 2012 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,8 +26,8 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef Profiler_h -#define Profiler_h +#ifndef LegacyProfiler_h +#define LegacyProfiler_h #include "Profile.h" #include <wtf/PassRefPtr.h> @@ -36,38 +36,38 @@ namespace JSC { - class ExecState; - class JSGlobalData; - class JSGlobalObject; - class JSObject; - class JSValue; - class ProfileGenerator; - struct CallIdentifier; +class ExecState; +class VM; +class JSGlobalObject; +class JSObject; +class JSValue; +class ProfileGenerator; +struct CallIdentifier; - class Profiler { - WTF_MAKE_FAST_ALLOCATED; - public: - JS_EXPORT_PRIVATE static Profiler* profiler(); - static CallIdentifier createCallIdentifier(ExecState*, JSValue, const WTF::String& sourceURL, int lineNumber); +class LegacyProfiler { + WTF_MAKE_FAST_ALLOCATED; +public: + JS_EXPORT_PRIVATE static LegacyProfiler* profiler(); + static CallIdentifier createCallIdentifier(ExecState*, JSValue, const WTF::String& sourceURL, int lineNumber); - JS_EXPORT_PRIVATE void startProfiling(ExecState*, const WTF::String& title); - JS_EXPORT_PRIVATE PassRefPtr<Profile> stopProfiling(ExecState*, const WTF::String& title); - void stopProfiling(JSGlobalObject*); + JS_EXPORT_PRIVATE void startProfiling(ExecState*, const WTF::String& title); + JS_EXPORT_PRIVATE PassRefPtr<Profile> stopProfiling(ExecState*, const WTF::String& title); + void stopProfiling(JSGlobalObject*); - void willExecute(ExecState* callerCallFrame, JSValue function); - void willExecute(ExecState* callerCallFrame, const WTF::String& sourceURL, int startingLineNumber); - void didExecute(ExecState* callerCallFrame, JSValue function); - void didExecute(ExecState* callerCallFrame, const WTF::String& sourceURL, int startingLineNumber); + void willExecute(ExecState* callerCallFrame, JSValue function); + void willExecute(ExecState* callerCallFrame, const WTF::String& sourceURL, int startingLineNumber); + void didExecute(ExecState* callerCallFrame, JSValue function); + void didExecute(ExecState* callerCallFrame, const WTF::String& sourceURL, int startingLineNumber); - void exceptionUnwind(ExecState* handlerCallFrame); + void exceptionUnwind(ExecState* handlerCallFrame); - const Vector<RefPtr<ProfileGenerator> >& currentProfiles() { return m_currentProfiles; }; + const Vector<RefPtr<ProfileGenerator> >& currentProfiles() { return m_currentProfiles; }; - private: - Vector<RefPtr<ProfileGenerator> > m_currentProfiles; - static Profiler* s_sharedProfiler; - }; +private: + Vector<RefPtr<ProfileGenerator> > m_currentProfiles; + static LegacyProfiler* s_sharedLegacyProfiler; +}; } // namespace JSC -#endif // Profiler_h +#endif // LegacyProfiler_h diff --git a/Source/JavaScriptCore/profiler/ProfileGenerator.cpp b/Source/JavaScriptCore/profiler/ProfileGenerator.cpp index 09877d3c8..d240aff34 100644 --- a/Source/JavaScriptCore/profiler/ProfileGenerator.cpp +++ b/Source/JavaScriptCore/profiler/ProfileGenerator.cpp @@ -32,8 +32,9 @@ #include "JSStringRef.h" #include "JSFunction.h" #include "Interpreter.h" +#include "LegacyProfiler.h" +#include "Operations.h" #include "Profile.h" -#include "Profiler.h" #include "Tracing.h" namespace JSC { @@ -63,7 +64,7 @@ void ProfileGenerator::addParentForConsoleStart(ExecState* exec) JSValue function; exec->interpreter()->retrieveLastCaller(exec, lineNumber, sourceID, sourceURL, function); - m_currentNode = ProfileNode::create(exec, Profiler::createCallIdentifier(exec, function ? function.toThisObject(exec) : 0, sourceURL, lineNumber), m_head.get(), m_head.get()); + m_currentNode = ProfileNode::create(exec, LegacyProfiler::createCallIdentifier(exec, function ? function.toThisObject(exec) : 0, sourceURL, lineNumber), m_head.get(), m_head.get()); m_head->insertNode(m_currentNode.get()); } diff --git a/Source/JavaScriptCore/profiler/ProfileNode.cpp b/Source/JavaScriptCore/profiler/ProfileNode.cpp index 6c36e47d0..5b6a25411 100644 --- a/Source/JavaScriptCore/profiler/ProfileNode.cpp +++ b/Source/JavaScriptCore/profiler/ProfileNode.cpp @@ -29,7 +29,7 @@ #include "config.h" #include "ProfileNode.h" -#include "Profiler.h" +#include "LegacyProfiler.h" #include <stdio.h> #include <wtf/DateMath.h> #include <wtf/DataLog.h> diff --git a/Source/JavaScriptCore/profiler/ProfilerBytecode.cpp b/Source/JavaScriptCore/profiler/ProfilerBytecode.cpp new file mode 100644 index 000000000..ca602e42f --- /dev/null +++ b/Source/JavaScriptCore/profiler/ProfilerBytecode.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2012 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. + */ + +#include "config.h" +#include "ProfilerBytecode.h" + +#include "JSGlobalObject.h" +#include "ObjectConstructor.h" +#include "Operations.h" + +namespace JSC { namespace Profiler { + +JSValue Bytecode::toJS(ExecState* exec) const +{ + JSObject* result = constructEmptyObject(exec); + result->putDirect(exec->vm(), exec->propertyNames().bytecodeIndex, jsNumber(m_bytecodeIndex)); + result->putDirect(exec->vm(), exec->propertyNames().opcode, jsString(exec, String::fromUTF8(opcodeNames[m_opcodeID]))); + result->putDirect(exec->vm(), exec->propertyNames().description, jsString(exec, String::fromUTF8(m_description))); + return result; +} + +} } // namespace JSC::Profiler + diff --git a/Source/JavaScriptCore/profiler/ProfilerBytecode.h b/Source/JavaScriptCore/profiler/ProfilerBytecode.h new file mode 100644 index 000000000..8e99c9a09 --- /dev/null +++ b/Source/JavaScriptCore/profiler/ProfilerBytecode.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2012 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 ProfilerBytecode_h +#define ProfilerBytecode_h + +#include "JSCJSValue.h" +#include "Opcode.h" +#include <wtf/text/CString.h> + +namespace JSC { namespace Profiler { + +class Bytecode { +public: + Bytecode() + : m_bytecodeIndex(std::numeric_limits<unsigned>::max()) + { + } + + Bytecode(unsigned bytecodeIndex, OpcodeID opcodeID, const CString& description) + : m_bytecodeIndex(bytecodeIndex) + , m_opcodeID(opcodeID) + , m_description(description) + { + } + + unsigned bytecodeIndex() const { return m_bytecodeIndex; } + OpcodeID opcodeID() const { return m_opcodeID; } + const CString& description() const { return m_description; } + + JSValue toJS(ExecState*) const; +private: + unsigned m_bytecodeIndex; + OpcodeID m_opcodeID; + CString m_description; +}; + +inline unsigned getBytecodeIndexForBytecode(Bytecode* bytecode) { return bytecode->bytecodeIndex(); } + +} } // namespace JSC::Profiler + +#endif // ProfilerBytecode_h + diff --git a/Source/JavaScriptCore/profiler/ProfilerBytecodeSequence.cpp b/Source/JavaScriptCore/profiler/ProfilerBytecodeSequence.cpp new file mode 100644 index 000000000..a98b8bace --- /dev/null +++ b/Source/JavaScriptCore/profiler/ProfilerBytecodeSequence.cpp @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2012 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. + */ + +#include "config.h" +#include "ProfilerBytecodeSequence.h" + +#include "CodeBlock.h" +#include "JSGlobalObject.h" +#include "Operands.h" +#include "Operations.h" +#include <wtf/StringPrintStream.h> + +namespace JSC { namespace Profiler { + +BytecodeSequence::BytecodeSequence(CodeBlock* codeBlock) +{ + StringPrintStream out; + +#if ENABLE(VALUE_PROFILER) + for (unsigned i = 0; i < codeBlock->numberOfArgumentValueProfiles(); ++i) { + CString description = codeBlock->valueProfileForArgument(i)->briefDescription(); + if (!description.length()) + continue; + out.reset(); + out.print("arg", i, " (r", argumentToOperand(i), "): ", description); + m_header.append(out.toCString()); + } +#endif // ENABLE(VALUE_PROFILER) + + for (unsigned bytecodeIndex = 0; bytecodeIndex < codeBlock->instructions().size();) { + out.reset(); + codeBlock->dumpBytecode(out, bytecodeIndex); + m_sequence.append(Bytecode(bytecodeIndex, codeBlock->vm()->interpreter->getOpcodeID(codeBlock->instructions()[bytecodeIndex].u.opcode), out.toCString())); + bytecodeIndex += opcodeLength( + codeBlock->vm()->interpreter->getOpcodeID( + codeBlock->instructions()[bytecodeIndex].u.opcode)); + } +} + +BytecodeSequence::~BytecodeSequence() +{ +} + +unsigned BytecodeSequence::indexForBytecodeIndex(unsigned bytecodeIndex) const +{ + return binarySearch<Bytecode, unsigned>(m_sequence, m_sequence.size(), bytecodeIndex, getBytecodeIndexForBytecode) - m_sequence.begin(); +} + +const Bytecode& BytecodeSequence::forBytecodeIndex(unsigned bytecodeIndex) const +{ + return at(indexForBytecodeIndex(bytecodeIndex)); +} + +void BytecodeSequence::addSequenceProperties(ExecState* exec, JSObject* result) const +{ + JSArray* header = constructEmptyArray(exec, 0); + for (unsigned i = 0; i < m_header.size(); ++i) + header->putDirectIndex(exec, i, jsString(exec, String::fromUTF8(m_header[i]))); + result->putDirect(exec->vm(), exec->propertyNames().header, header); + + JSArray* sequence = constructEmptyArray(exec, 0); + for (unsigned i = 0; i < m_sequence.size(); ++i) + sequence->putDirectIndex(exec, i, m_sequence[i].toJS(exec)); + result->putDirect(exec->vm(), exec->propertyNames().bytecode, sequence); +} + +} } // namespace JSC::Profiler + diff --git a/Source/JavaScriptCore/profiler/ProfilerBytecodeSequence.h b/Source/JavaScriptCore/profiler/ProfilerBytecodeSequence.h new file mode 100644 index 000000000..1d5c82a18 --- /dev/null +++ b/Source/JavaScriptCore/profiler/ProfilerBytecodeSequence.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2012 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 ProfilerBytecodeSequence_h +#define ProfilerBytecodeSequence_h + +#include "JSCJSValue.h" +#include "ProfilerBytecode.h" +#include <wtf/PrintStream.h> +#include <wtf/Vector.h> +#include <wtf/text/CString.h> +#include <wtf/text/WTFString.h> + +namespace JSC { + +class CodeBlock; + +namespace Profiler { + +class BytecodeSequence { +public: + BytecodeSequence(CodeBlock*); + ~BytecodeSequence(); + + // Note that this data structure is not indexed by bytecode index. + unsigned size() const { return m_sequence.size(); } + const Bytecode& at(unsigned i) const { return m_sequence[i]; } + + unsigned indexForBytecodeIndex(unsigned bytecodeIndex) const; + const Bytecode& forBytecodeIndex(unsigned bytecodeIndex) const; + +protected: + void addSequenceProperties(ExecState*, JSObject*) const; + +private: + Vector<CString> m_header; + Vector<Bytecode> m_sequence; +}; + +} } // namespace JSC::Profiler + +#endif // ProfilerBytecodeSequence_h + diff --git a/Source/JavaScriptCore/profiler/ProfilerBytecodes.cpp b/Source/JavaScriptCore/profiler/ProfilerBytecodes.cpp new file mode 100644 index 000000000..3ae35dcc0 --- /dev/null +++ b/Source/JavaScriptCore/profiler/ProfilerBytecodes.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2012 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. + */ + +#include "config.h" +#include "ProfilerBytecodes.h" + +#include "CodeBlock.h" +#include "JSGlobalObject.h" +#include "ObjectConstructor.h" +#include "Operations.h" +#include <wtf/StringPrintStream.h> + +namespace JSC { namespace Profiler { + +Bytecodes::Bytecodes(size_t id, CodeBlock* codeBlock) + : BytecodeSequence(codeBlock) + , m_id(id) + , m_inferredName(codeBlock->inferredName()) + , m_sourceCode(codeBlock->sourceCodeForTools()) + , m_hash(codeBlock->hash()) + , m_instructionCount(codeBlock->instructionCount()) +{ +} + +Bytecodes::~Bytecodes() { } + +void Bytecodes::dump(PrintStream& out) const +{ + out.print("#", m_hash, "(", m_id, ")"); +} + +JSValue Bytecodes::toJS(ExecState* exec) const +{ + JSObject* result = constructEmptyObject(exec); + + result->putDirect(exec->vm(), exec->propertyNames().bytecodesID, jsNumber(m_id)); + result->putDirect(exec->vm(), exec->propertyNames().inferredName, jsString(exec, m_inferredName)); + result->putDirect(exec->vm(), exec->propertyNames().sourceCode, jsString(exec, m_sourceCode)); + result->putDirect(exec->vm(), exec->propertyNames().hash, jsString(exec, String::fromUTF8(toCString(m_hash)))); + result->putDirect(exec->vm(), exec->propertyNames().instructionCount, jsNumber(m_instructionCount)); + addSequenceProperties(exec, result); + + return result; +} + +} } // namespace JSC::Profiler + diff --git a/Source/JavaScriptCore/profiler/ProfilerBytecodes.h b/Source/JavaScriptCore/profiler/ProfilerBytecodes.h new file mode 100644 index 000000000..47d856cb4 --- /dev/null +++ b/Source/JavaScriptCore/profiler/ProfilerBytecodes.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2012 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 ProfilerBytecodes_h +#define ProfilerBytecodes_h + +#include "CodeBlockHash.h" +#include "JSCJSValue.h" +#include "ProfilerBytecodeSequence.h" +#include <wtf/PrintStream.h> +#include <wtf/text/WTFString.h> + +namespace JSC { namespace Profiler { + +class Bytecodes : public BytecodeSequence { +public: + Bytecodes(size_t id, CodeBlock*); + ~Bytecodes(); + + size_t id() const { return m_id; } + const String& inferredName() const { return m_inferredName; } + const String& sourceCode() const { return m_sourceCode; } + unsigned instructionCount() const { return m_instructionCount; } + CodeBlockHash hash() const { return m_hash; } + + void dump(PrintStream&) const; + + JSValue toJS(ExecState*) const; + +private: + size_t m_id; + String m_inferredName; + String m_sourceCode; + CodeBlockHash m_hash; + unsigned m_instructionCount; +}; + +} } // namespace JSC::Profiler + +#endif // ProfilerBytecodes_h + diff --git a/Source/JavaScriptCore/profiler/ProfilerCompilation.cpp b/Source/JavaScriptCore/profiler/ProfilerCompilation.cpp new file mode 100644 index 000000000..f82414ffa --- /dev/null +++ b/Source/JavaScriptCore/profiler/ProfilerCompilation.cpp @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2012, 2013 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. + */ + +#include "config.h" +#include "ProfilerCompilation.h" + +#include "JSGlobalObject.h" +#include "ObjectConstructor.h" +#include "Operations.h" +#include "ProfilerDatabase.h" +#include <wtf/StringPrintStream.h> + +namespace JSC { namespace Profiler { + +Compilation::Compilation(Bytecodes* bytecodes, CompilationKind kind) + : m_bytecodes(bytecodes) + , m_kind(kind) + , m_numInlinedGetByIds(0) + , m_numInlinedPutByIds(0) + , m_numInlinedCalls(0) +{ +} + +Compilation::~Compilation() { } + +void Compilation::addProfiledBytecodes(Database& database, CodeBlock* profiledBlock) +{ + Bytecodes* bytecodes = database.ensureBytecodesFor(profiledBlock); + + // First make sure that we haven't already added profiled bytecodes for this code + // block. We do this using an O(N) search because I suspect that this list will + // tend to be fairly small, and the additional space costs of having a HashMap/Set + // would be greater than the time cost of occasionally doing this search. + + for (unsigned i = m_profiledBytecodes.size(); i--;) { + if (m_profiledBytecodes[i].bytecodes() == bytecodes) + return; + } + + m_profiledBytecodes.append(ProfiledBytecodes(bytecodes, profiledBlock)); +} + +void Compilation::addDescription(const CompiledBytecode& compiledBytecode) +{ + m_descriptions.append(compiledBytecode); +} + +ExecutionCounter* Compilation::executionCounterFor(const OriginStack& origin) +{ + HashMap<OriginStack, OwnPtr<ExecutionCounter> >::iterator iter = m_counters.find(origin); + if (iter != m_counters.end()) + return iter->value.get(); + + OwnPtr<ExecutionCounter> counter = adoptPtr(new ExecutionCounter()); + ExecutionCounter* result = counter.get(); + m_counters.add(origin, counter.release()); + return result; +} + +void Compilation::addOSRExitSite(const Vector<const void*>& codeAddresses) +{ + m_osrExitSites.append(OSRExitSite(codeAddresses)); +} + +OSRExit* Compilation::addOSRExit(unsigned id, const OriginStack& originStack, ExitKind exitKind, bool isWatchpoint) +{ + m_osrExits.append(OSRExit(id, originStack, exitKind, isWatchpoint)); + return &m_osrExits.last(); +} + +JSValue Compilation::toJS(ExecState* exec) const +{ + JSObject* result = constructEmptyObject(exec); + + result->putDirect(exec->vm(), exec->propertyNames().bytecodesID, jsNumber(m_bytecodes->id())); + result->putDirect(exec->vm(), exec->propertyNames().compilationKind, jsString(exec, String::fromUTF8(toCString(m_kind)))); + + JSArray* profiledBytecodes = constructEmptyArray(exec, 0); + for (unsigned i = 0; i < m_profiledBytecodes.size(); ++i) + profiledBytecodes->putDirectIndex(exec, i, m_profiledBytecodes[i].toJS(exec)); + result->putDirect(exec->vm(), exec->propertyNames().profiledBytecodes, profiledBytecodes); + + JSArray* descriptions = constructEmptyArray(exec, 0); + for (unsigned i = 0; i < m_descriptions.size(); ++i) + descriptions->putDirectIndex(exec, i, m_descriptions[i].toJS(exec)); + result->putDirect(exec->vm(), exec->propertyNames().descriptions, descriptions); + + JSArray* counters = constructEmptyArray(exec, 0); + HashMap<OriginStack, OwnPtr<ExecutionCounter> >::const_iterator end = m_counters.end(); + for (HashMap<OriginStack, OwnPtr<ExecutionCounter> >::const_iterator iter = m_counters.begin(); iter != end; ++iter) { + JSObject* counterEntry = constructEmptyObject(exec); + counterEntry->putDirect(exec->vm(), exec->propertyNames().origin, iter->key.toJS(exec)); + counterEntry->putDirect(exec->vm(), exec->propertyNames().executionCount, jsNumber(iter->value->count())); + counters->push(exec, counterEntry); + } + result->putDirect(exec->vm(), exec->propertyNames().counters, counters); + + JSArray* exitSites = constructEmptyArray(exec, 0); + for (unsigned i = 0; i < m_osrExitSites.size(); ++i) + exitSites->putDirectIndex(exec, i, m_osrExitSites[i].toJS(exec)); + result->putDirect(exec->vm(), exec->propertyNames().osrExitSites, exitSites); + + JSArray* exits = constructEmptyArray(exec, 0); + for (unsigned i = 0; i < m_osrExits.size(); ++i) + exits->putDirectIndex(exec, i, m_osrExits[i].toJS(exec)); + result->putDirect(exec->vm(), exec->propertyNames().osrExits, exits); + + result->putDirect(exec->vm(), exec->propertyNames().numInlinedGetByIds, jsNumber(m_numInlinedGetByIds)); + result->putDirect(exec->vm(), exec->propertyNames().numInlinedPutByIds, jsNumber(m_numInlinedPutByIds)); + result->putDirect(exec->vm(), exec->propertyNames().numInlinedCalls, jsNumber(m_numInlinedCalls)); + + return result; +} + +} } // namespace JSC::Profiler + diff --git a/Source/JavaScriptCore/profiler/ProfilerCompilation.h b/Source/JavaScriptCore/profiler/ProfilerCompilation.h new file mode 100644 index 000000000..b3183fa02 --- /dev/null +++ b/Source/JavaScriptCore/profiler/ProfilerCompilation.h @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2012, 2013 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 ProfilerCompilation_h +#define ProfilerCompilation_h + +#include "ExitKind.h" +#include "JSCJSValue.h" +#include "ProfilerCompilationKind.h" +#include "ProfilerCompiledBytecode.h" +#include "ProfilerExecutionCounter.h" +#include "ProfilerOSRExit.h" +#include "ProfilerOSRExitSite.h" +#include "ProfilerOriginStack.h" +#include "ProfilerProfiledBytecodes.h" +#include <wtf/RefCounted.h> +#include <wtf/SegmentedVector.h> + +namespace JSC { namespace Profiler { + +class Bytecodes; +class Database; + +// Represents the act of executing some bytecodes in some engine, and does +// all of the counting for those executions. + +class Compilation : public RefCounted<Compilation> { +public: + Compilation(Bytecodes*, CompilationKind); + ~Compilation(); + + void addProfiledBytecodes(Database&, CodeBlock*); + unsigned profiledBytecodesSize() const { return m_profiledBytecodes.size(); } + const ProfiledBytecodes& profiledBytecodesAt(unsigned i) const { return m_profiledBytecodes[i]; } + + void noticeInlinedGetById() { m_numInlinedGetByIds++; } + void noticeInlinedPutById() { m_numInlinedPutByIds++; } + void noticeInlinedCall() { m_numInlinedCalls++; } + + Bytecodes* bytecodes() const { return m_bytecodes; } + CompilationKind kind() const { return m_kind; } + + void addDescription(const CompiledBytecode&); + ExecutionCounter* executionCounterFor(const OriginStack&); + void addOSRExitSite(const Vector<const void*>& codeAddresses); + OSRExit* addOSRExit(unsigned id, const OriginStack&, ExitKind, bool isWatchpoint); + + JSValue toJS(ExecState*) const; + +private: + Bytecodes* m_bytecodes; + CompilationKind m_kind; + Vector<ProfiledBytecodes> m_profiledBytecodes; + Vector<CompiledBytecode> m_descriptions; + HashMap<OriginStack, OwnPtr<ExecutionCounter> > m_counters; + Vector<OSRExitSite> m_osrExitSites; + SegmentedVector<OSRExit> m_osrExits; + unsigned m_numInlinedGetByIds; + unsigned m_numInlinedPutByIds; + unsigned m_numInlinedCalls; +}; + +} } // namespace JSC::Profiler + +#endif // ProfilerCompilation_h + diff --git a/Source/JavaScriptCore/profiler/ProfilerCompilationKind.cpp b/Source/JavaScriptCore/profiler/ProfilerCompilationKind.cpp new file mode 100644 index 000000000..78ce70586 --- /dev/null +++ b/Source/JavaScriptCore/profiler/ProfilerCompilationKind.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2012 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. + */ + +#include "config.h" +#include "ProfilerCompilationKind.h" + +#include <wtf/PrintStream.h> + +namespace WTF { + +void printInternal(PrintStream& out, JSC::Profiler::CompilationKind kind) +{ + switch (kind) { + case JSC::Profiler::LLInt: + out.print("LLInt"); + return; + case JSC::Profiler::Baseline: + out.print("Baseline"); + return; + case JSC::Profiler::DFG: + out.print("DFG"); + return; + default: + CRASH(); + return; + } +} + +} // namespace WTF + diff --git a/Source/JavaScriptCore/profiler/ProfilerCompilationKind.h b/Source/JavaScriptCore/profiler/ProfilerCompilationKind.h new file mode 100644 index 000000000..4806d39b9 --- /dev/null +++ b/Source/JavaScriptCore/profiler/ProfilerCompilationKind.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2012 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 ProfilerCompilationKind_h +#define ProfilerCompilationKind_h + +namespace JSC { namespace Profiler { + +enum CompilationKind { + LLInt, + Baseline, + DFG +}; + +} } // namespace JSC::Profiler + +namespace WTF { + +class PrintStream; +void printInternal(PrintStream&, JSC::Profiler::CompilationKind); + +} // namespace WTF + +#endif // ProfilerCompilationKind_h + diff --git a/Source/JavaScriptCore/profiler/ProfilerCompiledBytecode.cpp b/Source/JavaScriptCore/profiler/ProfilerCompiledBytecode.cpp new file mode 100644 index 000000000..455a48ed9 --- /dev/null +++ b/Source/JavaScriptCore/profiler/ProfilerCompiledBytecode.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2012 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. + */ + +#include "config.h" +#include "ProfilerCompiledBytecode.h" + +#include "JSGlobalObject.h" +#include "ObjectConstructor.h" +#include "Operations.h" + +namespace JSC { namespace Profiler { + +CompiledBytecode::CompiledBytecode(const OriginStack& origin, const CString& description) + : m_origin(origin) + , m_description(description) +{ +} + +CompiledBytecode::~CompiledBytecode() +{ +} + +JSValue CompiledBytecode::toJS(ExecState* exec) const +{ + JSObject* result = constructEmptyObject(exec); + + result->putDirect(exec->vm(), exec->propertyNames().origin, m_origin.toJS(exec)); + result->putDirect(exec->vm(), exec->propertyNames().description, jsString(exec, String::fromUTF8(m_description))); + + return result; +} + +} } // namespace JSC::Profiler + diff --git a/Source/JavaScriptCore/profiler/ProfilerCompiledBytecode.h b/Source/JavaScriptCore/profiler/ProfilerCompiledBytecode.h new file mode 100644 index 000000000..84044445a --- /dev/null +++ b/Source/JavaScriptCore/profiler/ProfilerCompiledBytecode.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2012 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 ProfilerCompiledBytecode_h +#define ProfilerCompiledBytecode_h + +#include "JSCJSValue.h" +#include "ProfilerOriginStack.h" +#include <wtf/text/CString.h> + +namespace JSC { namespace Profiler { + +class CompiledBytecode { +public: + // It's valid to have an empty OriginStack, which indicates that this is some + // sort of non-bytecode-related machine code. + CompiledBytecode(const OriginStack&, const CString& description); + ~CompiledBytecode(); + + const OriginStack& originStack() const { return m_origin; } + const CString& description() const { return m_description; } + + JSValue toJS(ExecState*) const; + +private: + OriginStack m_origin; + CString m_description; +}; + +} } // namespace JSC::Profiler + +#endif // ProfilerCompiledBytecode_h + diff --git a/Source/JavaScriptCore/profiler/ProfilerDatabase.cpp b/Source/JavaScriptCore/profiler/ProfilerDatabase.cpp new file mode 100644 index 000000000..a2fffd955 --- /dev/null +++ b/Source/JavaScriptCore/profiler/ProfilerDatabase.cpp @@ -0,0 +1,187 @@ +/* + * Copyright (C) 2012, 2013 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. + */ + +#include "config.h" +#include "ProfilerDatabase.h" + +#include "CodeBlock.h" +#include "JSONObject.h" +#include "ObjectConstructor.h" +#include "Operations.h" + +namespace JSC { namespace Profiler { + +#if COMPILER(MINGW) || COMPILER(MSVC7_OR_LOWER) || OS(WINCE) +static int databaseCounter; +#else +static volatile int databaseCounter; +#endif +static SpinLock registrationLock = SPINLOCK_INITIALIZER; +static int didRegisterAtExit; +static Database* firstDatabase; + +Database::Database(VM& vm) + : m_databaseID(atomicIncrement(&databaseCounter)) + , m_vm(vm) + , m_shouldSaveAtExit(false) + , m_nextRegisteredDatabase(0) +{ +} + +Database::~Database() +{ + if (m_shouldSaveAtExit) { + removeDatabaseFromAtExit(); + performAtExitSave(); + } +} + +Bytecodes* Database::ensureBytecodesFor(CodeBlock* codeBlock) +{ + codeBlock = codeBlock->baselineVersion(); + + HashMap<CodeBlock*, Bytecodes*>::iterator iter = m_bytecodesMap.find(codeBlock); + if (iter != m_bytecodesMap.end()) + return iter->value; + + m_bytecodes.append(Bytecodes(m_bytecodes.size(), codeBlock)); + Bytecodes* result = &m_bytecodes.last(); + + m_bytecodesMap.add(codeBlock, result); + + return result; +} + +void Database::notifyDestruction(CodeBlock* codeBlock) +{ + m_bytecodesMap.remove(codeBlock); +} + +PassRefPtr<Compilation> Database::newCompilation(Bytecodes* bytecodes, CompilationKind kind) +{ + RefPtr<Compilation> compilation = adoptRef(new Compilation(bytecodes, kind)); + m_compilations.append(compilation); + return compilation.release(); +} + +PassRefPtr<Compilation> Database::newCompilation(CodeBlock* codeBlock, CompilationKind kind) +{ + return newCompilation(ensureBytecodesFor(codeBlock), kind); +} + +JSValue Database::toJS(ExecState* exec) const +{ + JSObject* result = constructEmptyObject(exec); + + JSArray* bytecodes = constructEmptyArray(exec, 0); + for (unsigned i = 0; i < m_bytecodes.size(); ++i) + bytecodes->putDirectIndex(exec, i, m_bytecodes[i].toJS(exec)); + result->putDirect(exec->vm(), exec->propertyNames().bytecodes, bytecodes); + + JSArray* compilations = constructEmptyArray(exec, 0); + for (unsigned i = 0; i < m_compilations.size(); ++i) + compilations->putDirectIndex(exec, i, m_compilations[i]->toJS(exec)); + result->putDirect(exec->vm(), exec->propertyNames().compilations, compilations); + + return result; +} + +String Database::toJSON() const +{ + JSGlobalObject* globalObject = JSGlobalObject::create( + m_vm, JSGlobalObject::createStructure(m_vm, jsNull())); + + return JSONStringify(globalObject->globalExec(), toJS(globalObject->globalExec()), 0); +} + +bool Database::save(const char* filename) const +{ + OwnPtr<FilePrintStream> out = FilePrintStream::open(filename, "w"); + if (!out) + return false; + + out->print(toJSON()); + return true; +} + +void Database::registerToSaveAtExit(const char* filename) +{ + m_atExitSaveFilename = filename; + + if (m_shouldSaveAtExit) + return; + + addDatabaseToAtExit(); + m_shouldSaveAtExit = true; +} + +void Database::addDatabaseToAtExit() +{ + if (atomicIncrement(&didRegisterAtExit) == 1) + atexit(atExitCallback); + + TCMalloc_SpinLockHolder holder(®istrationLock); + m_nextRegisteredDatabase = firstDatabase; + firstDatabase = this; +} + +void Database::removeDatabaseFromAtExit() +{ + TCMalloc_SpinLockHolder holder(®istrationLock); + for (Database** current = &firstDatabase; *current; current = &(*current)->m_nextRegisteredDatabase) { + if (*current != this) + continue; + *current = m_nextRegisteredDatabase; + m_nextRegisteredDatabase = 0; + m_shouldSaveAtExit = false; + break; + } +} + +void Database::performAtExitSave() const +{ + save(m_atExitSaveFilename.data()); +} + +Database* Database::removeFirstAtExitDatabase() +{ + TCMalloc_SpinLockHolder holder(®istrationLock); + Database* result = firstDatabase; + if (result) { + firstDatabase = result->m_nextRegisteredDatabase; + result->m_nextRegisteredDatabase = 0; + result->m_shouldSaveAtExit = false; + } + return result; +} + +void Database::atExitCallback() +{ + while (Database* database = removeFirstAtExitDatabase()) + database->performAtExitSave(); +} + +} } // namespace JSC::Profiler + diff --git a/Source/JavaScriptCore/profiler/ProfilerDatabase.h b/Source/JavaScriptCore/profiler/ProfilerDatabase.h new file mode 100644 index 000000000..172c8eeac --- /dev/null +++ b/Source/JavaScriptCore/profiler/ProfilerDatabase.h @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2012, 2013 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 ProfilerDatabase_h +#define ProfilerDatabase_h + +#include "JSCJSValue.h" +#include "ProfilerBytecodes.h" +#include "ProfilerCompilation.h" +#include "ProfilerCompilationKind.h" +#include <wtf/FastAllocBase.h> +#include <wtf/HashMap.h> +#include <wtf/Noncopyable.h> +#include <wtf/PassRefPtr.h> +#include <wtf/SegmentedVector.h> +#include <wtf/text/WTFString.h> + +namespace JSC { namespace Profiler { + +class Database { + WTF_MAKE_FAST_ALLOCATED; WTF_MAKE_NONCOPYABLE(Database); +public: + JS_EXPORT_PRIVATE Database(VM&); + JS_EXPORT_PRIVATE ~Database(); + + int databaseID() const { return m_databaseID; } + + Bytecodes* ensureBytecodesFor(CodeBlock*); + void notifyDestruction(CodeBlock*); + + PassRefPtr<Compilation> newCompilation(CodeBlock*, CompilationKind); + PassRefPtr<Compilation> newCompilation(Bytecodes*, CompilationKind); + + // Converts the database to a JavaScript object that is suitable for JSON stringification. + // Note that it's probably a good idea to use an ExecState* associated with a global + // object that is "clean" - i.e. array and object prototypes haven't had strange things + // done to them. And yes, it should be appropriate to just use a globalExec here. + JS_EXPORT_PRIVATE JSValue toJS(ExecState*) const; + + // Converts the database to a JavaScript object using a private temporary global object, + // and then returns the JSON representation of that object. + JS_EXPORT_PRIVATE String toJSON() const; + + // Saves the JSON representation (from toJSON()) to the given file. Returns false if the + // save failed. + JS_EXPORT_PRIVATE bool save(const char* filename) const; + + void registerToSaveAtExit(const char* filename); + +private: + + void addDatabaseToAtExit(); + void removeDatabaseFromAtExit(); + void performAtExitSave() const; + static Database* removeFirstAtExitDatabase(); + static void atExitCallback(); + + int m_databaseID; + VM& m_vm; + SegmentedVector<Bytecodes> m_bytecodes; + HashMap<CodeBlock*, Bytecodes*> m_bytecodesMap; + Vector<RefPtr<Compilation> > m_compilations; + bool m_shouldSaveAtExit; + CString m_atExitSaveFilename; + Database* m_nextRegisteredDatabase; +}; + +} } // namespace JSC::Profiler + +#endif // ProfilerDatabase_h + diff --git a/Source/JavaScriptCore/profiler/ProfilerExecutionCounter.h b/Source/JavaScriptCore/profiler/ProfilerExecutionCounter.h new file mode 100644 index 000000000..2884bc5dc --- /dev/null +++ b/Source/JavaScriptCore/profiler/ProfilerExecutionCounter.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2012 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 ProfilerExecutionCounter_h +#define ProfilerExecutionCounter_h + +#include <wtf/FastAllocBase.h> +#include <wtf/Noncopyable.h> + +namespace JSC { namespace Profiler { + +class ExecutionCounter { + WTF_MAKE_FAST_ALLOCATED; WTF_MAKE_NONCOPYABLE(ExecutionCounter); +public: + ExecutionCounter() : m_counter(0) { } + + uint64_t* address() { return &m_counter; } + + uint64_t count() const { return m_counter; } + +private: + uint64_t m_counter; +}; + +} } // namespace JSC::Profiler + +#endif // ProfilerExecutionCounter_h + diff --git a/Source/JavaScriptCore/profiler/ProfilerOSRExit.cpp b/Source/JavaScriptCore/profiler/ProfilerOSRExit.cpp new file mode 100644 index 000000000..0024791b4 --- /dev/null +++ b/Source/JavaScriptCore/profiler/ProfilerOSRExit.cpp @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2012 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. + */ + +#include "config.h" +#include "ProfilerOSRExit.h" + +#include "JSGlobalObject.h" +#include "ObjectConstructor.h" +#include "Operations.h" + +namespace JSC { namespace Profiler { + +OSRExit::OSRExit(unsigned id, const OriginStack& origin, ExitKind kind, bool isWatchpoint) + : m_id(id) + , m_origin(origin) + , m_exitKind(kind) + , m_isWatchpoint(isWatchpoint) + , m_counter(0) +{ +} + +OSRExit::~OSRExit() +{ +} + +JSValue OSRExit::toJS(ExecState* exec) const +{ + JSObject* result = constructEmptyObject(exec); + result->putDirect(exec->vm(), exec->propertyNames().id, jsNumber(m_id)); + result->putDirect(exec->vm(), exec->propertyNames().origin, m_origin.toJS(exec)); + result->putDirect(exec->vm(), exec->propertyNames().exitKind, jsString(exec, exitKindToString(m_exitKind))); + result->putDirect(exec->vm(), exec->propertyNames().isWatchpoint, jsBoolean(m_isWatchpoint)); + result->putDirect(exec->vm(), exec->propertyNames().count, jsNumber(m_counter)); + return result; +} + +} } // namespace JSC::Profiler + diff --git a/Source/JavaScriptCore/profiler/ProfilerOSRExit.h b/Source/JavaScriptCore/profiler/ProfilerOSRExit.h new file mode 100644 index 000000000..2a23d0b2c --- /dev/null +++ b/Source/JavaScriptCore/profiler/ProfilerOSRExit.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2012 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 ProfilerOSRExit_h +#define ProfilerOSRExit_h + +#include "ExitKind.h" +#include "JSCJSValue.h" +#include "ProfilerOriginStack.h" + +namespace JSC { namespace Profiler { + +class OSRExit { +public: + OSRExit(unsigned id, const OriginStack&, ExitKind, bool isWatchpoint); + ~OSRExit(); + + unsigned id() const { return m_id; } + const OriginStack& origin() const { return m_origin; } + ExitKind exitKind() const { return m_exitKind; } + bool isWatchpoint() const { return m_isWatchpoint; } + + uint64_t* counterAddress() { return &m_counter; } + uint64_t count() const { return m_counter; } + + JSValue toJS(ExecState*) const; + +private: + unsigned m_id; + OriginStack m_origin; + ExitKind m_exitKind; + bool m_isWatchpoint; + uint64_t m_counter; +}; + +} } // namespace JSC::Profiler + +#endif // ProfilerOSRExit_h + diff --git a/Source/JavaScriptCore/profiler/ProfilerOSRExitSite.cpp b/Source/JavaScriptCore/profiler/ProfilerOSRExitSite.cpp new file mode 100644 index 000000000..d54f7a275 --- /dev/null +++ b/Source/JavaScriptCore/profiler/ProfilerOSRExitSite.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2012 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. + */ + +#include "config.h" +#include "ProfilerOSRExitSite.h" + +#include "JSGlobalObject.h" +#include "JSScope.h" +#include "JSString.h" +#include "Operations.h" +#include <wtf/StringPrintStream.h> + +namespace JSC { namespace Profiler { + +JSValue OSRExitSite::toJS(ExecState* exec) const +{ + JSArray* result = constructEmptyArray(exec, 0); + for (unsigned i = 0; i < m_codeAddresses.size(); ++i) + result->putDirectIndex(exec, i, jsString(exec, toString(RawPointer(m_codeAddresses[i])))); + return result; +} + +} } // namespace JSC::Profiler + diff --git a/Source/JavaScriptCore/profiler/ProfilerOSRExitSite.h b/Source/JavaScriptCore/profiler/ProfilerOSRExitSite.h new file mode 100644 index 000000000..fa418e9b8 --- /dev/null +++ b/Source/JavaScriptCore/profiler/ProfilerOSRExitSite.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2012 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 ProfilerOSRExitSite_h +#define ProfilerOSRExitSite_h + +#include "JSCJSValue.h" +#include <wtf/Vector.h> + +namespace JSC { namespace Profiler { + +class OSRExitSite { +public: + explicit OSRExitSite(const Vector<const void*>& codeAddresses) + : m_codeAddresses(codeAddresses) + { + } + + const Vector<const void*>& codeAddress() const { return m_codeAddresses; } + + JSValue toJS(ExecState*) const; + +private: + Vector<const void*> m_codeAddresses; +}; + +} } // namespace JSC::Profiler + +#endif // ProfilerOSRExitSite_h + diff --git a/Source/JavaScriptCore/profiler/ProfilerOrigin.cpp b/Source/JavaScriptCore/profiler/ProfilerOrigin.cpp new file mode 100644 index 000000000..1ac29d1cc --- /dev/null +++ b/Source/JavaScriptCore/profiler/ProfilerOrigin.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2012 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. + */ + +#include "config.h" +#include "ProfilerOrigin.h" + +#include "JSGlobalObject.h" +#include "ObjectConstructor.h" +#include "Operations.h" +#include "ProfilerBytecodes.h" +#include "ProfilerDatabase.h" + +namespace JSC { namespace Profiler { + +Origin::Origin(Database& database, CodeBlock* codeBlock, unsigned bytecodeIndex) + : m_bytecodes(database.ensureBytecodesFor(codeBlock)) + , m_bytecodeIndex(bytecodeIndex) +{ +} + +void Origin::dump(PrintStream& out) const +{ + out.print(*m_bytecodes, ":bc#", m_bytecodeIndex); +} + +JSValue Origin::toJS(ExecState* exec) const +{ + JSObject* result = constructEmptyObject(exec); + result->putDirect(exec->vm(), exec->propertyNames().bytecodesID, jsNumber(m_bytecodes->id())); + result->putDirect(exec->vm(), exec->propertyNames().bytecodeIndex, jsNumber(m_bytecodeIndex)); + return result; +} + +} } // namespace JSC::Profiler + diff --git a/Source/JavaScriptCore/profiler/ProfilerOrigin.h b/Source/JavaScriptCore/profiler/ProfilerOrigin.h new file mode 100644 index 000000000..09b388451 --- /dev/null +++ b/Source/JavaScriptCore/profiler/ProfilerOrigin.h @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2012 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 ProfilerOrigin_h +#define ProfilerOrigin_h + +#include "CodeBlockHash.h" +#include "JSCJSValue.h" +#include <wtf/HashMap.h> +#include <wtf/PrintStream.h> + +namespace JSC { + +class CodeBlock; + +namespace Profiler { + +class Bytecodes; +class Database; + +class Origin { +public: + Origin() + : m_bytecodeIndex(std::numeric_limits<unsigned>::max()) + { + } + + Origin(WTF::HashTableDeletedValueType) + : m_bytecodeIndex(std::numeric_limits<unsigned>::max() - 1) + { + } + + Origin(Bytecodes* bytecodes, unsigned bytecodeIndex) + : m_bytecodes(bytecodes) + , m_bytecodeIndex(bytecodeIndex) + { + ASSERT(m_bytecodeIndex < std::numeric_limits<unsigned>::max() - 1); + } + + Origin(Database&, CodeBlock*, unsigned bytecodeIndex); + + bool operator!() const { return m_bytecodeIndex == std::numeric_limits<unsigned>::max(); } + + Bytecodes* bytecodes() const { return m_bytecodes; } + unsigned bytecodeIndex() const { return m_bytecodeIndex; } + + bool operator==(const Origin&) const; + bool operator!=(const Origin& other) const { return !(*this == other); } + unsigned hash() const; + + bool isHashTableDeletedValue() const; + + void dump(PrintStream&) const; + JSValue toJS(ExecState*) const; + +private: + Bytecodes* m_bytecodes; + unsigned m_bytecodeIndex; +}; + +inline bool Origin::operator==(const Origin& other) const +{ + return m_bytecodes == other.m_bytecodes + && m_bytecodeIndex == other.m_bytecodeIndex; +} + +inline unsigned Origin::hash() const +{ + return WTF::PtrHash<Bytecodes*>::hash(m_bytecodes) + m_bytecodeIndex; +} + +inline bool Origin::isHashTableDeletedValue() const +{ + return m_bytecodeIndex == std::numeric_limits<unsigned>::max(); +} + +struct OriginHash { + static unsigned hash(const Origin& key) { return key.hash(); } + static bool equal(const Origin& a, const Origin& b) { return a == b; } + static const bool safeToCompareToEmptyOrDeleted = true; +}; + +} } // namespace JSC::Profiler + +namespace WTF { + +template<typename T> struct DefaultHash; +template<> struct DefaultHash<JSC::Profiler::Origin> { + typedef JSC::Profiler::OriginHash Hash; +}; + +template<typename T> struct HashTraits; +template<> struct HashTraits<JSC::Profiler::Origin> : SimpleClassHashTraits<JSC::Profiler::Origin> { }; + +} // namespace WTF + +#endif // ProfilerOrigin_h + diff --git a/Source/JavaScriptCore/profiler/ProfilerOriginStack.cpp b/Source/JavaScriptCore/profiler/ProfilerOriginStack.cpp new file mode 100644 index 000000000..018ceeb8c --- /dev/null +++ b/Source/JavaScriptCore/profiler/ProfilerOriginStack.cpp @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2012 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. + */ + +#include "config.h" +#include "ProfilerOriginStack.h" + +#include "CodeOrigin.h" +#include "JSGlobalObject.h" +#include "Operations.h" +#include "ProfilerDatabase.h" + +namespace JSC { namespace Profiler { + +OriginStack::OriginStack(WTF::HashTableDeletedValueType) +{ + m_stack.append(Origin(WTF::HashTableDeletedValue)); +} + +OriginStack::OriginStack(const Origin& origin) +{ + m_stack.append(origin); +} + +OriginStack::OriginStack(Database& database, CodeBlock* codeBlock, const CodeOrigin& codeOrigin) +{ + Vector<CodeOrigin> stack = codeOrigin.inlineStack(); + + append(Origin(database, codeBlock, stack[0].bytecodeIndex)); + + for (unsigned i = 1; i < stack.size(); ++i) { + append(Origin( + database.ensureBytecodesFor(stack[i].inlineCallFrame->baselineCodeBlock()), + stack[i].bytecodeIndex)); + } +} + +OriginStack::~OriginStack() { } + +void OriginStack::append(const Origin& origin) +{ + m_stack.append(origin); +} + +bool OriginStack::operator==(const OriginStack& other) const +{ + if (m_stack.size() != other.m_stack.size()) + return false; + + for (unsigned i = m_stack.size(); i--;) { + if (m_stack[i] != other.m_stack[i]) + return false; + } + + return true; +} + +unsigned OriginStack::hash() const +{ + unsigned result = m_stack.size(); + + for (unsigned i = m_stack.size(); i--;) { + result *= 3; + result += m_stack[i].hash(); + } + + return result; +} + +void OriginStack::dump(PrintStream& out) const +{ + for (unsigned i = 0; i < m_stack.size(); ++i) { + if (i) + out.print(" --> "); + out.print(m_stack[i]); + } +} + +JSValue OriginStack::toJS(ExecState* exec) const +{ + JSArray* result = constructEmptyArray(exec, 0); + + for (unsigned i = 0; i < m_stack.size(); ++i) + result->putDirectIndex(exec, i, m_stack[i].toJS(exec)); + + return result; +} + +} } // namespace JSC::Profiler + diff --git a/Source/JavaScriptCore/profiler/ProfilerOriginStack.h b/Source/JavaScriptCore/profiler/ProfilerOriginStack.h new file mode 100644 index 000000000..415e8d9b0 --- /dev/null +++ b/Source/JavaScriptCore/profiler/ProfilerOriginStack.h @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2012 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 ProfilerOriginStack_h +#define ProfilerOriginStack_h + +#include "JSCJSValue.h" +#include "ProfilerOrigin.h" +#include <wtf/HashMap.h> +#include <wtf/PrintStream.h> +#include <wtf/Vector.h> + +namespace JSC { + +class CodeBlock; +struct CodeOrigin; + +namespace Profiler { + +class Database; + +class OriginStack { +public: + OriginStack() { } + + OriginStack(WTF::HashTableDeletedValueType); + + explicit OriginStack(const Origin&); + + explicit OriginStack(Database&, CodeBlock*, const CodeOrigin&); + + ~OriginStack(); + + void append(const Origin&); + + bool operator!() const { return m_stack.isEmpty(); } + + unsigned size() const { return m_stack.size(); } + const Origin& fromBottom(unsigned i) const { return m_stack[i]; } + const Origin& fromTop(unsigned i) const { return m_stack[m_stack.size() - i - 1]; } + + bool operator==(const OriginStack&) const; + unsigned hash() const; + + bool isHashTableDeletedValue() const; + + void dump(PrintStream&) const; + JSValue toJS(ExecState*) const; + +private: + Vector<Origin, 1> m_stack; +}; + +inline bool OriginStack::isHashTableDeletedValue() const +{ + return m_stack.size() == 1 && m_stack[0].isHashTableDeletedValue(); +} + +struct OriginStackHash { + static unsigned hash(const OriginStack& key) { return key.hash(); } + static bool equal(const OriginStack& a, const OriginStack& b) { return a == b; } + static const bool safeToCompareToEmptyOrDeleted = true; +}; + +} } // namespace JSC::Profiler + +namespace WTF { + +template<typename T> struct DefaultHash; +template<> struct DefaultHash<JSC::Profiler::OriginStack> { + typedef JSC::Profiler::OriginStackHash Hash; +}; + +template<typename T> struct HashTraits; +template<> struct HashTraits<JSC::Profiler::OriginStack> : SimpleClassHashTraits<JSC::Profiler::OriginStack> { }; + +} // namespace WTF + +#endif // ProfilerOriginStack_h + diff --git a/Source/JavaScriptCore/profiler/ProfilerProfiledBytecodes.cpp b/Source/JavaScriptCore/profiler/ProfilerProfiledBytecodes.cpp new file mode 100644 index 000000000..6ca6c9f15 --- /dev/null +++ b/Source/JavaScriptCore/profiler/ProfilerProfiledBytecodes.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2012 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. + */ + +#include "config.h" +#include "ProfilerProfiledBytecodes.h" + +#include "JSGlobalObject.h" +#include "ObjectConstructor.h" +#include "Operations.h" + +namespace JSC { namespace Profiler { + +ProfiledBytecodes::ProfiledBytecodes(Bytecodes* bytecodes, CodeBlock* profiledBlock) + : BytecodeSequence(profiledBlock) + , m_bytecodes(bytecodes) +{ +} + +ProfiledBytecodes::~ProfiledBytecodes() +{ +} + +JSValue ProfiledBytecodes::toJS(ExecState* exec) const +{ + JSObject* result = constructEmptyObject(exec); + + result->putDirect(exec->vm(), exec->propertyNames().bytecodesID, jsNumber(m_bytecodes->id())); + addSequenceProperties(exec, result); + + return result; +} + +} } // namespace JSC::Profiler + diff --git a/Source/JavaScriptCore/profiler/ProfilerProfiledBytecodes.h b/Source/JavaScriptCore/profiler/ProfilerProfiledBytecodes.h new file mode 100644 index 000000000..d7cb6ffa8 --- /dev/null +++ b/Source/JavaScriptCore/profiler/ProfilerProfiledBytecodes.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2012 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 ProfilerProfiledBytecodes_h +#define ProfilerProfiledBytecodes_h + +#include "ProfilerBytecodeSequence.h" +#include "ProfilerBytecodes.h" +#include "ProfilerOriginStack.h" + +namespace JSC { namespace Profiler { + +class ProfiledBytecodes : public BytecodeSequence { +public: + ProfiledBytecodes(Bytecodes*, CodeBlock*); + ~ProfiledBytecodes(); + + const Bytecodes* bytecodes() const { return m_bytecodes; } + + JSValue toJS(ExecState*) const; + +private: + Bytecodes* m_bytecodes; +}; + +} } // namespace JSC::Profiler + +#endif // ProfilerProfiledBytecodes_h + |