diff options
author | Steve Block <steveblock@google.com> | 2011-05-06 11:45:16 +0100 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2011-05-12 13:44:10 +0100 |
commit | cad810f21b803229eb11403f9209855525a25d57 (patch) | |
tree | 29a6fd0279be608e0fe9ffe9841f722f0f4e4269 /JavaScriptCore/profiler | |
parent | 121b0cf4517156d0ac5111caf9830c51b69bae8f (diff) | |
download | external_webkit-cad810f21b803229eb11403f9209855525a25d57.zip external_webkit-cad810f21b803229eb11403f9209855525a25d57.tar.gz external_webkit-cad810f21b803229eb11403f9209855525a25d57.tar.bz2 |
Merge WebKit at r75315: Initial merge by git.
Change-Id: I570314b346ce101c935ed22a626b48c2af266b84
Diffstat (limited to 'JavaScriptCore/profiler')
-rw-r--r-- | JavaScriptCore/profiler/CallIdentifier.h | 100 | ||||
-rw-r--r-- | JavaScriptCore/profiler/Profile.cpp | 136 | ||||
-rw-r--r-- | JavaScriptCore/profiler/Profile.h | 72 | ||||
-rw-r--r-- | JavaScriptCore/profiler/ProfileGenerator.cpp | 181 | ||||
-rw-r--r-- | JavaScriptCore/profiler/ProfileGenerator.h | 79 | ||||
-rw-r--r-- | JavaScriptCore/profiler/ProfileNode.cpp | 351 | ||||
-rw-r--r-- | JavaScriptCore/profiler/ProfileNode.h | 172 | ||||
-rw-r--r-- | JavaScriptCore/profiler/Profiler.cpp | 172 | ||||
-rw-r--r-- | JavaScriptCore/profiler/Profiler.h | 77 | ||||
-rw-r--r-- | JavaScriptCore/profiler/ProfilerServer.h | 35 | ||||
-rw-r--r-- | JavaScriptCore/profiler/ProfilerServer.mm | 115 |
11 files changed, 0 insertions, 1490 deletions
diff --git a/JavaScriptCore/profiler/CallIdentifier.h b/JavaScriptCore/profiler/CallIdentifier.h deleted file mode 100644 index 76c1470..0000000 --- a/JavaScriptCore/profiler/CallIdentifier.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 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 CallIdentifier_h -#define CallIdentifier_h - -#include <runtime/UString.h> -#include "FastAllocBase.h" -#include <wtf/text/CString.h> -#include <wtf/text/StringHash.h> - -namespace JSC { - - struct CallIdentifier : public FastAllocBase { - UString m_name; - UString m_url; - unsigned m_lineNumber; - - CallIdentifier() - : m_lineNumber(0) - { - } - - CallIdentifier(const UString& name, const UString& url, int lineNumber) - : m_name(name) - , m_url(!url.isNull() ? url : "") - , m_lineNumber(lineNumber) - { - } - - inline bool operator==(const CallIdentifier& ci) const { return ci.m_lineNumber == m_lineNumber && ci.m_name == m_name && ci.m_url == m_url; } - inline bool operator!=(const CallIdentifier& ci) const { return !(*this == ci); } - - struct Hash { - static unsigned hash(const CallIdentifier& key) - { - unsigned hashCodes[3] = { - key.m_name.impl()->hash(), - key.m_url.impl()->hash(), - key.m_lineNumber - }; - return WTF::StringHasher::createBlobHash<sizeof(hashCodes)>(hashCodes); - } - - static bool equal(const CallIdentifier& a, const CallIdentifier& b) { return a == b; } - static const bool safeToCompareToEmptyOrDeleted = true; - }; - - unsigned hash() const { return Hash::hash(*this); } - -#ifndef NDEBUG - operator const char*() const { return c_str(); } - const char* c_str() const { return m_name.utf8().data(); } -#endif - }; - -} // namespace JSC - -namespace WTF { - - template<> struct DefaultHash<JSC::CallIdentifier> { typedef JSC::CallIdentifier::Hash Hash; }; - - template<> struct HashTraits<JSC::CallIdentifier> : GenericHashTraits<JSC::CallIdentifier> { - static void constructDeletedValue(JSC::CallIdentifier& slot) - { - new (&slot) JSC::CallIdentifier(JSC::UString(), JSC::UString(), std::numeric_limits<unsigned>::max()); - } - static bool isDeletedValue(const JSC::CallIdentifier& value) - { - return value.m_name.isNull() && value.m_url.isNull() && value.m_lineNumber == std::numeric_limits<unsigned>::max(); - } - }; - -} // namespace WTF - -#endif // CallIdentifier_h - diff --git a/JavaScriptCore/profiler/Profile.cpp b/JavaScriptCore/profiler/Profile.cpp deleted file mode 100644 index 1a84518..0000000 --- a/JavaScriptCore/profiler/Profile.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 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 "Profile.h" - -#include "ProfileNode.h" -#include <stdio.h> - -namespace JSC { - -PassRefPtr<Profile> Profile::create(const UString& title, unsigned uid) -{ - return adoptRef(new Profile(title, uid)); -} - -Profile::Profile(const UString& title, unsigned uid) - : m_title(title) - , m_uid(uid) -{ - // FIXME: When multi-threading is supported this will be a vector and calls - // into the profiler will need to know which thread it is executing on. - m_head = ProfileNode::create(0, CallIdentifier("Thread_1", UString(), 0), 0, 0); -} - -Profile::~Profile() -{ -} - -void Profile::forEach(void (ProfileNode::*function)()) -{ - ProfileNode* currentNode = m_head->firstChild(); - for (ProfileNode* nextNode = currentNode; nextNode; nextNode = nextNode->firstChild()) - currentNode = nextNode; - - if (!currentNode) - currentNode = m_head.get(); - - ProfileNode* endNode = m_head->traverseNextNodePostOrder(); - while (currentNode && currentNode != endNode) { - (currentNode->*function)(); - currentNode = currentNode->traverseNextNodePostOrder(); - } -} - -void Profile::focus(const ProfileNode* profileNode) -{ - if (!profileNode || !m_head) - return; - - bool processChildren; - const CallIdentifier& callIdentifier = profileNode->callIdentifier(); - for (ProfileNode* currentNode = m_head.get(); currentNode; currentNode = currentNode->traverseNextNodePreOrder(processChildren)) - processChildren = currentNode->focus(callIdentifier); - - // Set the visible time of all nodes so that the %s display correctly. - forEach(&ProfileNode::calculateVisibleTotalTime); -} - -void Profile::exclude(const ProfileNode* profileNode) -{ - if (!profileNode || !m_head) - return; - - const CallIdentifier& callIdentifier = profileNode->callIdentifier(); - - for (ProfileNode* currentNode = m_head.get(); currentNode; currentNode = currentNode->traverseNextNodePreOrder()) - currentNode->exclude(callIdentifier); - - // Set the visible time of the head so the %s display correctly. - m_head->setVisibleTotalTime(m_head->totalTime() - m_head->selfTime()); - m_head->setVisibleSelfTime(0.0); -} - -void Profile::restoreAll() -{ - forEach(&ProfileNode::restore); -} - -#ifndef NDEBUG -void Profile::debugPrintData() const -{ - printf("Call graph:\n"); - m_head->debugPrintData(0); -} - -typedef pair<StringImpl*, unsigned> NameCountPair; - -static inline bool functionNameCountPairComparator(const NameCountPair& a, const NameCountPair& b) -{ - return a.second > b.second; -} - -void Profile::debugPrintDataSampleStyle() const -{ - typedef Vector<NameCountPair> NameCountPairVector; - - FunctionCallHashCount countedFunctions; - printf("Call graph:\n"); - m_head->debugPrintDataSampleStyle(0, countedFunctions); - - printf("\nTotal number in stack:\n"); - NameCountPairVector sortedFunctions(countedFunctions.size()); - copyToVector(countedFunctions, sortedFunctions); - - std::sort(sortedFunctions.begin(), sortedFunctions.end(), functionNameCountPairComparator); - for (NameCountPairVector::iterator it = sortedFunctions.begin(); it != sortedFunctions.end(); ++it) - printf(" %-12d%s\n", (*it).second, UString((*it).first).utf8().data()); - - printf("\nSort by top of stack, same collapsed (when >= 5):\n"); -} -#endif - -} // namespace JSC diff --git a/JavaScriptCore/profiler/Profile.h b/JavaScriptCore/profiler/Profile.h deleted file mode 100644 index 6bf29f7..0000000 --- a/JavaScriptCore/profiler/Profile.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 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 Profile_h -#define Profile_h - -#include "ProfileNode.h" -#include <runtime/UString.h> -#include <wtf/RefCounted.h> -#include <wtf/RefPtr.h> - -namespace JSC { - - class Profile : public RefCounted<Profile> { - public: - static PassRefPtr<Profile> create(const UString& title, unsigned uid); - virtual ~Profile(); - - const UString& title() const { return m_title; } - ProfileNode* head() const { return m_head.get(); } - void setHead(PassRefPtr<ProfileNode> head) { m_head = head; } - double totalTime() const { return m_head->totalTime(); } - unsigned int uid() const { return m_uid; } - - void forEach(void (ProfileNode::*)()); - - void focus(const ProfileNode*); - void exclude(const ProfileNode*); - void restoreAll(); - -#ifndef NDEBUG - void debugPrintData() const; - void debugPrintDataSampleStyle() const; -#endif - - protected: - Profile(const UString& title, unsigned uid); - - private: - void removeProfileStart(); - void removeProfileEnd(); - - UString m_title; - RefPtr<ProfileNode> m_head; - unsigned int m_uid; - }; - -} // namespace JSC - -#endif // Profile_h diff --git a/JavaScriptCore/profiler/ProfileGenerator.cpp b/JavaScriptCore/profiler/ProfileGenerator.cpp deleted file mode 100644 index 68d1733..0000000 --- a/JavaScriptCore/profiler/ProfileGenerator.cpp +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 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 "ProfileGenerator.h" - -#include "CallFrame.h" -#include "CodeBlock.h" -#include "JSGlobalObject.h" -#include "JSStringRef.h" -#include "JSFunction.h" -#include "Interpreter.h" -#include "Profile.h" -#include "Profiler.h" -#include "Tracing.h" - -namespace JSC { - -static const char* NonJSExecution = "(idle)"; - -PassRefPtr<ProfileGenerator> ProfileGenerator::create(const UString& title, ExecState* originatingExec, unsigned uid) -{ - return adoptRef(new ProfileGenerator(title, originatingExec, uid)); -} - -ProfileGenerator::ProfileGenerator(const UString& title, ExecState* originatingExec, unsigned uid) - : m_originatingGlobalExec(originatingExec ? originatingExec->lexicalGlobalObject()->globalExec() : 0) - , m_profileGroup(originatingExec ? originatingExec->lexicalGlobalObject()->profileGroup() : 0) -{ - m_profile = Profile::create(title, uid); - m_currentNode = m_head = m_profile->head(); - if (originatingExec) - addParentForConsoleStart(originatingExec); -} - -void ProfileGenerator::addParentForConsoleStart(ExecState* exec) -{ - int lineNumber; - intptr_t sourceID; - UString sourceURL; - 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_head->insertNode(m_currentNode.get()); -} - -const UString& ProfileGenerator::title() const -{ - return m_profile->title(); -} - -void ProfileGenerator::willExecute(ExecState* callerCallFrame, const CallIdentifier& callIdentifier) -{ - if (JAVASCRIPTCORE_PROFILE_WILL_EXECUTE_ENABLED()) { - CString name = callIdentifier.m_name.utf8(); - CString url = callIdentifier.m_url.utf8(); - JAVASCRIPTCORE_PROFILE_WILL_EXECUTE(m_profileGroup, const_cast<char*>(name.data()), const_cast<char*>(url.data()), callIdentifier.m_lineNumber); - } - - if (!m_originatingGlobalExec) - return; - - ASSERT(m_currentNode); - m_currentNode = m_currentNode->willExecute(callerCallFrame, callIdentifier); -} - -void ProfileGenerator::didExecute(ExecState* callerCallFrame, const CallIdentifier& callIdentifier) -{ - if (JAVASCRIPTCORE_PROFILE_DID_EXECUTE_ENABLED()) { - CString name = callIdentifier.m_name.utf8(); - CString url = callIdentifier.m_url.utf8(); - JAVASCRIPTCORE_PROFILE_DID_EXECUTE(m_profileGroup, const_cast<char*>(name.data()), const_cast<char*>(url.data()), callIdentifier.m_lineNumber); - } - - if (!m_originatingGlobalExec) - return; - - ASSERT(m_currentNode); - if (m_currentNode->callIdentifier() != callIdentifier) { - RefPtr<ProfileNode> returningNode = ProfileNode::create(callerCallFrame, callIdentifier, m_head.get(), m_currentNode.get()); - returningNode->setStartTime(m_currentNode->startTime()); - returningNode->didExecute(); - m_currentNode->insertNode(returningNode.release()); - return; - } - - m_currentNode = m_currentNode->didExecute(); -} - -void ProfileGenerator::exceptionUnwind(ExecState* handlerCallFrame, const CallIdentifier&) -{ - // If the current node was called by the handler (==) or any - // more nested function (>) the we have exited early from it. - ASSERT(m_currentNode); - while (m_currentNode->callerCallFrame() >= handlerCallFrame) { - didExecute(m_currentNode->callerCallFrame(), m_currentNode->callIdentifier()); - ASSERT(m_currentNode); - } -} - -void ProfileGenerator::stopProfiling() -{ - m_profile->forEach(&ProfileNode::stopProfiling); - - removeProfileStart(); - removeProfileEnd(); - - ASSERT(m_currentNode); - - // Set the current node to the parent, because we are in a call that - // will not get didExecute call. - m_currentNode = m_currentNode->parent(); - - if (double headSelfTime = m_head->selfTime()) { - RefPtr<ProfileNode> idleNode = ProfileNode::create(0, CallIdentifier(NonJSExecution, UString(), 0), m_head.get(), m_head.get()); - - idleNode->setTotalTime(headSelfTime); - idleNode->setSelfTime(headSelfTime); - idleNode->setVisible(true); - - m_head->setSelfTime(0.0); - m_head->addChild(idleNode.release()); - } -} - -// The console.ProfileGenerator that started this ProfileGenerator will be the first child. -void ProfileGenerator::removeProfileStart() -{ - ProfileNode* currentNode = 0; - for (ProfileNode* next = m_head.get(); next; next = next->firstChild()) - currentNode = next; - - if (currentNode->callIdentifier().m_name != "profile") - return; - - // Attribute the time of the node aobut to be removed to the self time of its parent - currentNode->parent()->setSelfTime(currentNode->parent()->selfTime() + currentNode->totalTime()); - currentNode->parent()->removeChild(currentNode); -} - -// The console.ProfileGeneratorEnd that stopped this ProfileGenerator will be the last child. -void ProfileGenerator::removeProfileEnd() -{ - ProfileNode* currentNode = 0; - for (ProfileNode* next = m_head.get(); next; next = next->lastChild()) - currentNode = next; - - if (currentNode->callIdentifier().m_name != "profileEnd") - return; - - // Attribute the time of the node aobut to be removed to the self time of its parent - currentNode->parent()->setSelfTime(currentNode->parent()->selfTime() + currentNode->totalTime()); - - ASSERT(currentNode->callIdentifier() == (currentNode->parent()->children()[currentNode->parent()->children().size() - 1])->callIdentifier()); - currentNode->parent()->removeChild(currentNode); -} - -} // namespace JSC diff --git a/JavaScriptCore/profiler/ProfileGenerator.h b/JavaScriptCore/profiler/ProfileGenerator.h deleted file mode 100644 index cbed73b..0000000 --- a/JavaScriptCore/profiler/ProfileGenerator.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 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 ProfileGenerator_h -#define ProfileGenerator_h - -#include "Profile.h" -#include <wtf/PassRefPtr.h> -#include <wtf/RefCounted.h> -#include <wtf/RefPtr.h> - -namespace JSC { - - class ExecState; - class Profile; - class ProfileNode; - class UString; - struct CallIdentifier; - - class ProfileGenerator : public RefCounted<ProfileGenerator> { - public: - static PassRefPtr<ProfileGenerator> create(const UString& title, ExecState* originatingExec, unsigned uid); - - // Members - const UString& title() const; - PassRefPtr<Profile> profile() const { return m_profile; } - ExecState* originatingGlobalExec() const { return m_originatingGlobalExec; } - unsigned profileGroup() const { return m_profileGroup; } - - // Collecting - void willExecute(ExecState* callerCallFrame, const CallIdentifier&); - void didExecute(ExecState* callerCallFrame, const CallIdentifier&); - - void exceptionUnwind(ExecState* handlerCallFrame, const CallIdentifier&); - - // Stopping Profiling - void stopProfiling(); - - typedef void (ProfileGenerator::*ProfileFunction)(ExecState* callerOrHandlerCallFrame, const CallIdentifier& callIdentifier); - - private: - ProfileGenerator(const UString& title, ExecState* originatingExec, unsigned uid); - void addParentForConsoleStart(ExecState*); - - void removeProfileStart(); - void removeProfileEnd(); - - RefPtr<Profile> m_profile; - ExecState* m_originatingGlobalExec; - unsigned m_profileGroup; - RefPtr<ProfileNode> m_head; - RefPtr<ProfileNode> m_currentNode; - }; - -} // namespace JSC - -#endif // ProfileGenerator_h diff --git a/JavaScriptCore/profiler/ProfileNode.cpp b/JavaScriptCore/profiler/ProfileNode.cpp deleted file mode 100644 index 8f20bbe..0000000 --- a/JavaScriptCore/profiler/ProfileNode.cpp +++ /dev/null @@ -1,351 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "ProfileNode.h" - -#include "Profiler.h" -#include <stdio.h> -#include <wtf/DateMath.h> -#include <wtf/text/StringHash.h> - -#if OS(WINDOWS) -#include <windows.h> -#endif - -using namespace WTF; - -namespace JSC { - -static double getCount() -{ -#if OS(WINDOWS) - static LARGE_INTEGER frequency; - if (!frequency.QuadPart) - QueryPerformanceFrequency(&frequency); - LARGE_INTEGER counter; - QueryPerformanceCounter(&counter); - return static_cast<double>(counter.QuadPart) / frequency.QuadPart; -#else - return currentTimeMS(); -#endif -} - -ProfileNode::ProfileNode(ExecState* callerCallFrame, const CallIdentifier& callIdentifier, ProfileNode* headNode, ProfileNode* parentNode) - : m_callerCallFrame(callerCallFrame) - , m_callIdentifier(callIdentifier) - , m_head(headNode) - , m_parent(parentNode) - , m_nextSibling(0) - , m_startTime(0.0) - , m_actualTotalTime(0.0) - , m_visibleTotalTime(0.0) - , m_actualSelfTime(0.0) - , m_visibleSelfTime(0.0) - , m_numberOfCalls(0) - , m_visible(true) -{ - startTimer(); -} - -ProfileNode::ProfileNode(ExecState* callerCallFrame, ProfileNode* headNode, ProfileNode* nodeToCopy) - : m_callerCallFrame(callerCallFrame) - , m_callIdentifier(nodeToCopy->callIdentifier()) - , m_head(headNode) - , m_parent(nodeToCopy->parent()) - , m_nextSibling(0) - , m_startTime(0.0) - , m_actualTotalTime(nodeToCopy->actualTotalTime()) - , m_visibleTotalTime(nodeToCopy->totalTime()) - , m_actualSelfTime(nodeToCopy->actualSelfTime()) - , m_visibleSelfTime(nodeToCopy->selfTime()) - , m_numberOfCalls(nodeToCopy->numberOfCalls()) - , m_visible(nodeToCopy->visible()) -{ -} - -ProfileNode* ProfileNode::willExecute(ExecState* callerCallFrame, const CallIdentifier& callIdentifier) -{ - for (StackIterator currentChild = m_children.begin(); currentChild != m_children.end(); ++currentChild) { - if ((*currentChild)->callIdentifier() == callIdentifier) { - (*currentChild)->startTimer(); - return (*currentChild).get(); - } - } - - RefPtr<ProfileNode> newChild = ProfileNode::create(callerCallFrame, callIdentifier, m_head ? m_head : this, this); // If this ProfileNode has no head it is the head. - if (m_children.size()) - m_children.last()->setNextSibling(newChild.get()); - m_children.append(newChild.release()); - return m_children.last().get(); -} - -ProfileNode* ProfileNode::didExecute() -{ - endAndRecordCall(); - return m_parent; -} - -void ProfileNode::addChild(PassRefPtr<ProfileNode> prpChild) -{ - RefPtr<ProfileNode> child = prpChild; - child->setParent(this); - if (m_children.size()) - m_children.last()->setNextSibling(child.get()); - m_children.append(child.release()); -} - -ProfileNode* ProfileNode::findChild(ProfileNode* node) const -{ - if (!node) - return 0; - - for (size_t i = 0; i < m_children.size(); ++i) { - if (*node == m_children[i].get()) - return m_children[i].get(); - } - - return 0; -} - -void ProfileNode::removeChild(ProfileNode* node) -{ - if (!node) - return; - - for (size_t i = 0; i < m_children.size(); ++i) { - if (*node == m_children[i].get()) { - m_children.remove(i); - break; - } - } - - resetChildrensSiblings(); -} - -void ProfileNode::insertNode(PassRefPtr<ProfileNode> prpNode) -{ - RefPtr<ProfileNode> node = prpNode; - - for (unsigned i = 0; i < m_children.size(); ++i) - node->addChild(m_children[i].release()); - - m_children.clear(); - m_children.append(node.release()); -} - -void ProfileNode::stopProfiling() -{ - if (m_startTime) - endAndRecordCall(); - - m_visibleTotalTime = m_actualTotalTime; - - ASSERT(m_actualSelfTime == 0.0 && m_startTime == 0.0); - - // Because we iterate in post order all of our children have been stopped before us. - for (unsigned i = 0; i < m_children.size(); ++i) - m_actualSelfTime += m_children[i]->totalTime(); - - ASSERT(m_actualSelfTime <= m_actualTotalTime); - m_actualSelfTime = m_actualTotalTime - m_actualSelfTime; - m_visibleSelfTime = m_actualSelfTime; -} - -ProfileNode* ProfileNode::traverseNextNodePostOrder() const -{ - ProfileNode* next = m_nextSibling; - if (!next) - return m_parent; - while (ProfileNode* firstChild = next->firstChild()) - next = firstChild; - return next; -} - -ProfileNode* ProfileNode::traverseNextNodePreOrder(bool processChildren) const -{ - if (processChildren && m_children.size()) - return m_children[0].get(); - - if (m_nextSibling) - return m_nextSibling; - - ProfileNode* nextParent = m_parent; - if (!nextParent) - return 0; - - ProfileNode* next; - for (next = m_parent->nextSibling(); !next; next = nextParent->nextSibling()) { - nextParent = nextParent->parent(); - if (!nextParent) - return 0; - } - - return next; -} - -void ProfileNode::setTreeVisible(ProfileNode* node, bool visible) -{ - ProfileNode* nodeParent = node->parent(); - ProfileNode* nodeSibling = node->nextSibling(); - node->setParent(0); - node->setNextSibling(0); - - for (ProfileNode* currentNode = node; currentNode; currentNode = currentNode->traverseNextNodePreOrder()) - currentNode->setVisible(visible); - - node->setParent(nodeParent); - node->setNextSibling(nodeSibling); -} - -void ProfileNode::calculateVisibleTotalTime() -{ - double sumOfVisibleChildrensTime = 0.0; - - for (unsigned i = 0; i < m_children.size(); ++i) { - if (m_children[i]->visible()) - sumOfVisibleChildrensTime += m_children[i]->totalTime(); - } - - m_visibleTotalTime = m_visibleSelfTime + sumOfVisibleChildrensTime; -} - -bool ProfileNode::focus(const CallIdentifier& callIdentifier) -{ - if (!m_visible) - return false; - - if (m_callIdentifier != callIdentifier) { - m_visible = false; - return true; - } - - for (ProfileNode* currentParent = m_parent; currentParent; currentParent = currentParent->parent()) - currentParent->setVisible(true); - - return false; -} - -void ProfileNode::exclude(const CallIdentifier& callIdentifier) -{ - if (m_visible && m_callIdentifier == callIdentifier) { - setTreeVisible(this, false); - - m_parent->setVisibleSelfTime(m_parent->selfTime() + m_visibleTotalTime); - } -} - -void ProfileNode::restore() -{ - m_visibleTotalTime = m_actualTotalTime; - m_visibleSelfTime = m_actualSelfTime; - m_visible = true; -} - -void ProfileNode::endAndRecordCall() -{ - m_actualTotalTime += m_startTime ? getCount() - m_startTime : 0.0; - m_startTime = 0.0; - - ++m_numberOfCalls; -} - -void ProfileNode::startTimer() -{ - if (!m_startTime) - m_startTime = getCount(); -} - -void ProfileNode::resetChildrensSiblings() -{ - unsigned size = m_children.size(); - for (unsigned i = 0; i < size; ++i) - m_children[i]->setNextSibling(i + 1 == size ? 0 : m_children[i + 1].get()); -} - -#ifndef NDEBUG -void ProfileNode::debugPrintData(int indentLevel) const -{ - // Print function names - for (int i = 0; i < indentLevel; ++i) - printf(" "); - - printf("Function Name %s %d SelfTime %.3fms/%.3f%% TotalTime %.3fms/%.3f%% VSelf %.3fms VTotal %.3fms Visible %s Next Sibling %s\n", - functionName().utf8().data(), - m_numberOfCalls, m_actualSelfTime, selfPercent(), m_actualTotalTime, totalPercent(), - m_visibleSelfTime, m_visibleTotalTime, - (m_visible ? "True" : "False"), - m_nextSibling ? m_nextSibling->functionName().utf8().data() : ""); - - ++indentLevel; - - // Print children's names and information - for (StackIterator currentChild = m_children.begin(); currentChild != m_children.end(); ++currentChild) - (*currentChild)->debugPrintData(indentLevel); -} - -// print the profiled data in a format that matches the tool sample's output. -double ProfileNode::debugPrintDataSampleStyle(int indentLevel, FunctionCallHashCount& countedFunctions) const -{ - printf(" "); - - // Print function names - const char* name = functionName().utf8().data(); - double sampleCount = m_actualTotalTime * 1000; - if (indentLevel) { - for (int i = 0; i < indentLevel; ++i) - printf(" "); - - countedFunctions.add(functionName().impl()); - - printf("%.0f %s\n", sampleCount ? sampleCount : 1, name); - } else - printf("%s\n", name); - - ++indentLevel; - - // Print children's names and information - double sumOfChildrensCount = 0.0; - for (StackIterator currentChild = m_children.begin(); currentChild != m_children.end(); ++currentChild) - sumOfChildrensCount += (*currentChild)->debugPrintDataSampleStyle(indentLevel, countedFunctions); - - sumOfChildrensCount *= 1000; // - // Print remainder of samples to match sample's output - if (sumOfChildrensCount < sampleCount) { - printf(" "); - while (indentLevel--) - printf(" "); - - printf("%.0f %s\n", sampleCount - sumOfChildrensCount, functionName().utf8().data()); - } - - return m_actualTotalTime; -} -#endif - -} // namespace JSC diff --git a/JavaScriptCore/profiler/ProfileNode.h b/JavaScriptCore/profiler/ProfileNode.h deleted file mode 100644 index ffe7b6f..0000000 --- a/JavaScriptCore/profiler/ProfileNode.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef ProfileNode_h -#define ProfileNode_h - -#include "CallIdentifier.h" -#include <wtf/HashCountedSet.h> -#include <wtf/RefCounted.h> -#include <wtf/RefPtr.h> -#include <wtf/Vector.h> - -namespace JSC { - - class ExecState; - class ProfileNode; - - typedef Vector<RefPtr<ProfileNode> >::const_iterator StackIterator; - typedef HashCountedSet<StringImpl*> FunctionCallHashCount; - - class ProfileNode : public RefCounted<ProfileNode> { - public: - static PassRefPtr<ProfileNode> create(ExecState* callerCallFrame, const CallIdentifier& callIdentifier, ProfileNode* headNode, ProfileNode* parentNode) - { - return adoptRef(new ProfileNode(callerCallFrame, callIdentifier, headNode, parentNode)); - } - static PassRefPtr<ProfileNode> create(ExecState* callerCallFrame, ProfileNode* headNode, ProfileNode* node) - { - return adoptRef(new ProfileNode(callerCallFrame, headNode, node)); - } - - bool operator==(ProfileNode* node) { return m_callIdentifier == node->callIdentifier(); } - - ProfileNode* willExecute(ExecState* callerCallFrame, const CallIdentifier&); - ProfileNode* didExecute(); - - void stopProfiling(); - - // CallIdentifier members - ExecState* callerCallFrame() const { return m_callerCallFrame; } - const CallIdentifier& callIdentifier() const { return m_callIdentifier; } - const UString& functionName() const { return m_callIdentifier.m_name; } - const UString& url() const { return m_callIdentifier.m_url; } - unsigned lineNumber() const { return m_callIdentifier.m_lineNumber; } - - // Relationships - ProfileNode* head() const { return m_head; } - void setHead(ProfileNode* head) { m_head = head; } - ProfileNode* parent() const { return m_parent; } - void setParent(ProfileNode* parent) { m_parent = parent; } - ProfileNode* nextSibling() const { return m_nextSibling; } - void setNextSibling(ProfileNode* nextSibling) { m_nextSibling = nextSibling; } - - // Time members - double startTime() const { return m_startTime; } - void setStartTime(double startTime) { m_startTime = startTime; } - double totalTime() const { return m_visibleTotalTime; } - double actualTotalTime() const { return m_actualTotalTime; } - void setTotalTime(double time) { m_actualTotalTime = time; m_visibleTotalTime = time; } - void setActualTotalTime(double time) { m_actualTotalTime = time; } - void setVisibleTotalTime(double time) { m_visibleTotalTime = time; } - double selfTime() const { return m_visibleSelfTime; } - double actualSelfTime() const { return m_actualSelfTime; } - void setSelfTime(double time) {m_actualSelfTime = time; m_visibleSelfTime = time; } - void setActualSelfTime(double time) { m_actualSelfTime = time; } - void setVisibleSelfTime(double time) { m_visibleSelfTime = time; } - - double totalPercent() const { return (m_visibleTotalTime / (m_head ? m_head->totalTime() : totalTime())) * 100.0; } - double selfPercent() const { return (m_visibleSelfTime / (m_head ? m_head->totalTime() : totalTime())) * 100.0; } - - unsigned numberOfCalls() const { return m_numberOfCalls; } - void setNumberOfCalls(unsigned number) { m_numberOfCalls = number; } - - // Children members - const Vector<RefPtr<ProfileNode> >& children() const { return m_children; } - ProfileNode* firstChild() const { return m_children.size() ? m_children.first().get() : 0; } - ProfileNode* lastChild() const { return m_children.size() ? m_children.last().get() : 0; } - ProfileNode* findChild(ProfileNode*) const; - void removeChild(ProfileNode*); - void addChild(PassRefPtr<ProfileNode> prpChild); - void insertNode(PassRefPtr<ProfileNode> prpNode); - - // Visiblity - bool visible() const { return m_visible; } - void setVisible(bool visible) { m_visible = visible; } - - static void setTreeVisible(ProfileNode*, bool visible); - - // Sorting - ProfileNode* traverseNextNodePostOrder() const; - ProfileNode* traverseNextNodePreOrder(bool processChildren = true) const; - - // Views - void calculateVisibleTotalTime(); - bool focus(const CallIdentifier&); - void exclude(const CallIdentifier&); - void restore(); - - void endAndRecordCall(); - -#ifndef NDEBUG - const char* c_str() const { return m_callIdentifier; } - void debugPrintData(int indentLevel) const; - double debugPrintDataSampleStyle(int indentLevel, FunctionCallHashCount&) const; -#endif - - private: - ProfileNode(ExecState* callerCallFrame, const CallIdentifier&, ProfileNode* headNode, ProfileNode* parentNode); - ProfileNode(ExecState* callerCallFrame, ProfileNode* headNode, ProfileNode* nodeToCopy); - - void startTimer(); - void resetChildrensSiblings(); - - RefPtr<ProfileNode>* childrenBegin() { return m_children.begin(); } - RefPtr<ProfileNode>* childrenEnd() { return m_children.end(); } - - // Sorting comparators - static inline bool totalTimeDescendingComparator(const RefPtr<ProfileNode>& a, const RefPtr<ProfileNode>& b) { return a->totalTime() > b->totalTime(); } - static inline bool totalTimeAscendingComparator(const RefPtr<ProfileNode>& a, const RefPtr<ProfileNode>& b) { return a->totalTime() < b->totalTime(); } - static inline bool selfTimeDescendingComparator(const RefPtr<ProfileNode>& a, const RefPtr<ProfileNode>& b) { return a->selfTime() > b->selfTime(); } - static inline bool selfTimeAscendingComparator(const RefPtr<ProfileNode>& a, const RefPtr<ProfileNode>& b) { return a->selfTime() < b->selfTime(); } - static inline bool callsDescendingComparator(const RefPtr<ProfileNode>& a, const RefPtr<ProfileNode>& b) { return a->numberOfCalls() > b->numberOfCalls(); } - static inline bool callsAscendingComparator(const RefPtr<ProfileNode>& a, const RefPtr<ProfileNode>& b) { return a->numberOfCalls() < b->numberOfCalls(); } - static inline bool functionNameDescendingComparator(const RefPtr<ProfileNode>& a, const RefPtr<ProfileNode>& b) { return a->functionName() > b->functionName(); } - static inline bool functionNameAscendingComparator(const RefPtr<ProfileNode>& a, const RefPtr<ProfileNode>& b) { return a->functionName() < b->functionName(); } - - ExecState* m_callerCallFrame; - CallIdentifier m_callIdentifier; - ProfileNode* m_head; - ProfileNode* m_parent; - ProfileNode* m_nextSibling; - - double m_startTime; - double m_actualTotalTime; - double m_visibleTotalTime; - double m_actualSelfTime; - double m_visibleSelfTime; - unsigned m_numberOfCalls; - - bool m_visible; - - Vector<RefPtr<ProfileNode> > m_children; - }; - -} // namespace JSC - -#endif // ProfileNode_h diff --git a/JavaScriptCore/profiler/Profiler.cpp b/JavaScriptCore/profiler/Profiler.cpp deleted file mode 100644 index 9ac73fd..0000000 --- a/JavaScriptCore/profiler/Profiler.cpp +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "Profiler.h" - -#include "CommonIdentifiers.h" -#include "CallFrame.h" -#include "CodeBlock.h" -#include "InternalFunction.h" -#include "JSFunction.h" -#include "JSGlobalObject.h" -#include "Nodes.h" -#include "Profile.h" -#include "ProfileGenerator.h" -#include "ProfileNode.h" -#include "UStringConcatenate.h" -#include <stdio.h> - -namespace JSC { - -static const char* GlobalCodeExecution = "(program)"; -static const char* AnonymousFunction = "(anonymous function)"; -static unsigned ProfilesUID = 0; - -static CallIdentifier createCallIdentifierFromFunctionImp(ExecState*, JSFunction*); - -Profiler* Profiler::s_sharedProfiler = 0; -Profiler* Profiler::s_sharedEnabledProfilerReference = 0; - -Profiler* Profiler::profiler() -{ - if (!s_sharedProfiler) - s_sharedProfiler = new Profiler(); - return s_sharedProfiler; -} - -void Profiler::startProfiling(ExecState* exec, const UString& title) -{ - ASSERT_ARG(title, !title.isNull()); - - // Check if we currently have a Profile for this global ExecState and title. - // If so return early and don't create a new Profile. - ExecState* globalExec = exec ? exec->lexicalGlobalObject()->globalExec() : 0; - - for (size_t i = 0; i < m_currentProfiles.size(); ++i) { - ProfileGenerator* profileGenerator = m_currentProfiles[i].get(); - if (profileGenerator->originatingGlobalExec() == globalExec && profileGenerator->title() == title) - return; - } - - s_sharedEnabledProfilerReference = this; - RefPtr<ProfileGenerator> profileGenerator = ProfileGenerator::create(title, exec, ++ProfilesUID); - m_currentProfiles.append(profileGenerator); -} - -PassRefPtr<Profile> Profiler::stopProfiling(ExecState* exec, const UString& title) -{ - ExecState* globalExec = exec ? exec->lexicalGlobalObject()->globalExec() : 0; - for (ptrdiff_t i = m_currentProfiles.size() - 1; i >= 0; --i) { - ProfileGenerator* profileGenerator = m_currentProfiles[i].get(); - if (profileGenerator->originatingGlobalExec() == globalExec && (title.isNull() || profileGenerator->title() == title)) { - profileGenerator->stopProfiling(); - RefPtr<Profile> returnProfile = profileGenerator->profile(); - - m_currentProfiles.remove(i); - if (!m_currentProfiles.size()) - s_sharedEnabledProfilerReference = 0; - - return returnProfile; - } - } - - return 0; -} - -static inline void dispatchFunctionToProfiles(ExecState* callerOrHandlerCallFrame, const Vector<RefPtr<ProfileGenerator> >& profiles, ProfileGenerator::ProfileFunction function, const CallIdentifier& callIdentifier, unsigned currentProfileTargetGroup) -{ - for (size_t i = 0; i < profiles.size(); ++i) { - if (profiles[i]->profileGroup() == currentProfileTargetGroup || !profiles[i]->originatingGlobalExec()) - (profiles[i].get()->*function)(callerOrHandlerCallFrame, callIdentifier); - } -} - -void Profiler::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 UString& sourceURL, int startingLineNumber) -{ - ASSERT(!m_currentProfiles.isEmpty()); - - CallIdentifier callIdentifier = createCallIdentifier(callerCallFrame, JSValue(), sourceURL, startingLineNumber); - - dispatchFunctionToProfiles(callerCallFrame, m_currentProfiles, &ProfileGenerator::willExecute, callIdentifier, callerCallFrame->lexicalGlobalObject()->profileGroup()); -} - -void Profiler::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 UString& 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) -{ - 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 UString& defaultSourceURL, int defaultLineNumber) -{ - if (!functionValue) - return CallIdentifier(GlobalCodeExecution, defaultSourceURL, defaultLineNumber); - if (!functionValue.isObject()) - return CallIdentifier("(unknown)", defaultSourceURL, defaultLineNumber); - if (asObject(functionValue)->inherits(&JSFunction::info)) { - JSFunction* function = asFunction(functionValue); - if (!function->executable()->isHostFunction()) - return createCallIdentifierFromFunctionImp(exec, function); - } - if (asObject(functionValue)->inherits(&JSFunction::info)) - return CallIdentifier(static_cast<JSFunction*>(asObject(functionValue))->name(exec), defaultSourceURL, defaultLineNumber); - if (asObject(functionValue)->inherits(&InternalFunction::info)) - return CallIdentifier(static_cast<InternalFunction*>(asObject(functionValue))->name(exec), defaultSourceURL, defaultLineNumber); - return CallIdentifier(makeUString("(", asObject(functionValue)->className(), " object)"), defaultSourceURL, defaultLineNumber); -} - -CallIdentifier createCallIdentifierFromFunctionImp(ExecState* exec, JSFunction* function) -{ - ASSERT(!function->isHostFunction()); - const UString& name = function->calculatedDisplayName(exec); - return CallIdentifier(name.isEmpty() ? AnonymousFunction : name, function->jsExecutable()->sourceURL(), function->jsExecutable()->lineNo()); -} - -} // namespace JSC diff --git a/JavaScriptCore/profiler/Profiler.h b/JavaScriptCore/profiler/Profiler.h deleted file mode 100644 index f9c2ccb..0000000 --- a/JavaScriptCore/profiler/Profiler.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef Profiler_h -#define Profiler_h - -#include "Profile.h" -#include <wtf/PassRefPtr.h> -#include <wtf/RefPtr.h> -#include <wtf/Vector.h> - -namespace JSC { - - class ExecState; - class JSGlobalData; - class JSObject; - class JSValue; - class ProfileGenerator; - class UString; - struct CallIdentifier; - - class Profiler : public FastAllocBase { - public: - static Profiler** enabledProfilerReference() - { - return &s_sharedEnabledProfilerReference; - } - - static Profiler* profiler(); - static CallIdentifier createCallIdentifier(ExecState* exec, JSValue, const UString& sourceURL, int lineNumber); - - void startProfiling(ExecState*, const UString& title); - PassRefPtr<Profile> stopProfiling(ExecState*, const UString& title); - - void willExecute(ExecState* callerCallFrame, JSValue function); - void willExecute(ExecState* callerCallFrame, const UString& sourceURL, int startingLineNumber); - void didExecute(ExecState* callerCallFrame, JSValue function); - void didExecute(ExecState* callerCallFrame, const UString& sourceURL, int startingLineNumber); - - void exceptionUnwind(ExecState* handlerCallFrame); - - const Vector<RefPtr<ProfileGenerator> >& currentProfiles() { return m_currentProfiles; }; - - private: - Vector<RefPtr<ProfileGenerator> > m_currentProfiles; - static Profiler* s_sharedProfiler; - static Profiler* s_sharedEnabledProfilerReference; - }; - -} // namespace JSC - -#endif // Profiler_h diff --git a/JavaScriptCore/profiler/ProfilerServer.h b/JavaScriptCore/profiler/ProfilerServer.h deleted file mode 100644 index 5b7cc46..0000000 --- a/JavaScriptCore/profiler/ProfilerServer.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 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 ProfileServer_h -#define ProfileServer_h - -namespace JSC { - -void startProfilerServerIfNeeded(); - -} // namespace JSC - -#endif // ProfileServer_h diff --git a/JavaScriptCore/profiler/ProfilerServer.mm b/JavaScriptCore/profiler/ProfilerServer.mm deleted file mode 100644 index 7d87f96..0000000 --- a/JavaScriptCore/profiler/ProfilerServer.mm +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 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. - */ - -#import "config.h" -#import "ProfilerServer.h" - -#import "JSProfilerPrivate.h" -#import "JSRetainPtr.h" -#import <Foundation/Foundation.h> - -#if PLATFORM(IOS_SIMULATOR) -#import <Foundation/NSDistributedNotificationCenter.h> -#endif - -@interface ProfilerServer : NSObject { -@private - NSString *_serverName; - unsigned _listenerCount; -} -+ (ProfilerServer *)sharedProfileServer; -- (void)startProfiling; -- (void)stopProfiling; -@end - -@implementation ProfilerServer - -+ (ProfilerServer *)sharedProfileServer -{ - static ProfilerServer *sharedServer; - if (!sharedServer) - sharedServer = [[ProfilerServer alloc] init]; - return sharedServer; -} - -- (id)init -{ - if (!(self = [super init])) - return nil; - - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - - NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; - if ([defaults boolForKey:@"EnableJSProfiling"]) - [self startProfiling]; - -#if !PLATFORM(IOS) || PLATFORM(IOS_SIMULATOR) - // FIXME: <rdar://problem/6546135> - // The catch-all notifications - [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(startProfiling) name:@"ProfilerServerStartNotification" object:nil]; - [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(stopProfiling) name:@"ProfilerServerStopNotification" object:nil]; -#endif - - // The specific notifications - NSProcessInfo *processInfo = [NSProcessInfo processInfo]; - _serverName = [[NSString alloc] initWithFormat:@"ProfilerServer-%d", [processInfo processIdentifier]]; - -#if !PLATFORM(IOS) || PLATFORM(IOS_SIMULATOR) - // FIXME: <rdar://problem/6546135> - [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(startProfiling) name:[_serverName stringByAppendingString:@"-Start"] object:nil]; - [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(stopProfiling) name:[_serverName stringByAppendingString:@"-Stop"] object:nil]; -#endif - - [pool drain]; - - return self; -} - -- (void)startProfiling -{ - if (++_listenerCount > 1) - return; - JSRetainPtr<JSStringRef> profileName(Adopt, JSStringCreateWithUTF8CString([_serverName UTF8String])); - JSStartProfiling(0, profileName.get()); -} - -- (void)stopProfiling -{ - if (!_listenerCount || --_listenerCount > 0) - return; - JSRetainPtr<JSStringRef> profileName(Adopt, JSStringCreateWithUTF8CString([_serverName UTF8String])); - JSEndProfiling(0, profileName.get()); -} - -@end - -namespace JSC { - -void startProfilerServerIfNeeded() -{ - [ProfilerServer sharedProfileServer]; -} - -} // namespace JSC |