diff options
author | Shimeng (Simon) Wang <swang@google.com> | 2010-12-07 17:22:45 -0800 |
---|---|---|
committer | Shimeng (Simon) Wang <swang@google.com> | 2010-12-22 14:15:40 -0800 |
commit | 4576aa36e9a9671459299c7963ac95aa94beaea9 (patch) | |
tree | 3863574e050f168c0126ecb47c83319fab0972d8 /JavaScriptCore/profiler | |
parent | 55323ac613cc31553107b68603cb627264d22bb0 (diff) | |
download | external_webkit-4576aa36e9a9671459299c7963ac95aa94beaea9.zip external_webkit-4576aa36e9a9671459299c7963ac95aa94beaea9.tar.gz external_webkit-4576aa36e9a9671459299c7963ac95aa94beaea9.tar.bz2 |
Merge WebKit at r73109: Initial merge by git.
Change-Id: I61f1a66d9642e3d8405d3ac6ccab2a53421c75d8
Diffstat (limited to 'JavaScriptCore/profiler')
-rw-r--r-- | JavaScriptCore/profiler/CallIdentifier.h | 2 | ||||
-rw-r--r-- | JavaScriptCore/profiler/Profile.cpp | 2 | ||||
-rw-r--r-- | JavaScriptCore/profiler/ProfileGenerator.cpp | 29 | ||||
-rw-r--r-- | JavaScriptCore/profiler/ProfileGenerator.h | 8 | ||||
-rw-r--r-- | JavaScriptCore/profiler/ProfileNode.cpp | 14 | ||||
-rw-r--r-- | JavaScriptCore/profiler/ProfileNode.h | 17 | ||||
-rw-r--r-- | JavaScriptCore/profiler/Profiler.cpp | 29 | ||||
-rw-r--r-- | JavaScriptCore/profiler/Profiler.h | 10 |
8 files changed, 69 insertions, 42 deletions
diff --git a/JavaScriptCore/profiler/CallIdentifier.h b/JavaScriptCore/profiler/CallIdentifier.h index 5487209..76c1470 100644 --- a/JavaScriptCore/profiler/CallIdentifier.h +++ b/JavaScriptCore/profiler/CallIdentifier.h @@ -62,7 +62,7 @@ namespace JSC { key.m_url.impl()->hash(), key.m_lineNumber }; - return StringImpl::computeHash(reinterpret_cast<char*>(hashCodes), sizeof(hashCodes)); + return WTF::StringHasher::createBlobHash<sizeof(hashCodes)>(hashCodes); } static bool equal(const CallIdentifier& a, const CallIdentifier& b) { return a == b; } diff --git a/JavaScriptCore/profiler/Profile.cpp b/JavaScriptCore/profiler/Profile.cpp index bc239b3..1a84518 100644 --- a/JavaScriptCore/profiler/Profile.cpp +++ b/JavaScriptCore/profiler/Profile.cpp @@ -42,7 +42,7 @@ Profile::Profile(const UString& title, unsigned 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(CallIdentifier("Thread_1", UString(), 0), 0, 0); + m_head = ProfileNode::create(0, CallIdentifier("Thread_1", UString(), 0), 0, 0); } Profile::~Profile() diff --git a/JavaScriptCore/profiler/ProfileGenerator.cpp b/JavaScriptCore/profiler/ProfileGenerator.cpp index 1d916ea..68d1733 100644 --- a/JavaScriptCore/profiler/ProfileGenerator.cpp +++ b/JavaScriptCore/profiler/ProfileGenerator.cpp @@ -63,7 +63,7 @@ void ProfileGenerator::addParentForConsoleStart(ExecState* exec) JSValue function; exec->interpreter()->retrieveLastCaller(exec, lineNumber, sourceID, sourceURL, function); - m_currentNode = ProfileNode::create(Profiler::createCallIdentifier(exec, function ? function.toThisObject(exec) : 0, sourceURL, lineNumber), m_head.get(), m_head.get()); + 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()); } @@ -72,7 +72,7 @@ const UString& ProfileGenerator::title() const return m_profile->title(); } -void ProfileGenerator::willExecute(const CallIdentifier& callIdentifier) +void ProfileGenerator::willExecute(ExecState* callerCallFrame, const CallIdentifier& callIdentifier) { if (JAVASCRIPTCORE_PROFILE_WILL_EXECUTE_ENABLED()) { CString name = callIdentifier.m_name.utf8(); @@ -83,11 +83,11 @@ void ProfileGenerator::willExecute(const CallIdentifier& callIdentifier) if (!m_originatingGlobalExec) return; - ASSERT_ARG(m_currentNode, m_currentNode); - m_currentNode = m_currentNode->willExecute(callIdentifier); + ASSERT(m_currentNode); + m_currentNode = m_currentNode->willExecute(callerCallFrame, callIdentifier); } -void ProfileGenerator::didExecute(const CallIdentifier& callIdentifier) +void ProfileGenerator::didExecute(ExecState* callerCallFrame, const CallIdentifier& callIdentifier) { if (JAVASCRIPTCORE_PROFILE_DID_EXECUTE_ENABLED()) { CString name = callIdentifier.m_name.utf8(); @@ -98,9 +98,9 @@ void ProfileGenerator::didExecute(const CallIdentifier& callIdentifier) if (!m_originatingGlobalExec) return; - ASSERT_ARG(m_currentNode, m_currentNode); + ASSERT(m_currentNode); if (m_currentNode->callIdentifier() != callIdentifier) { - RefPtr<ProfileNode> returningNode = ProfileNode::create(callIdentifier, m_head.get(), m_currentNode.get()); + 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()); @@ -110,6 +110,17 @@ void ProfileGenerator::didExecute(const CallIdentifier& callIdentifier) 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); @@ -117,14 +128,14 @@ void ProfileGenerator::stopProfiling() removeProfileStart(); removeProfileEnd(); - ASSERT_ARG(m_currentNode, m_currentNode); + 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(CallIdentifier(NonJSExecution, UString(), 0), m_head.get(), m_head.get()); + RefPtr<ProfileNode> idleNode = ProfileNode::create(0, CallIdentifier(NonJSExecution, UString(), 0), m_head.get(), m_head.get()); idleNode->setTotalTime(headSelfTime); idleNode->setSelfTime(headSelfTime); diff --git a/JavaScriptCore/profiler/ProfileGenerator.h b/JavaScriptCore/profiler/ProfileGenerator.h index 82149b3..cbed73b 100644 --- a/JavaScriptCore/profiler/ProfileGenerator.h +++ b/JavaScriptCore/profiler/ProfileGenerator.h @@ -50,13 +50,15 @@ namespace JSC { unsigned profileGroup() const { return m_profileGroup; } // Collecting - void willExecute(const CallIdentifier&); - void didExecute(const CallIdentifier&); + 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)(const CallIdentifier& callIdentifier); + typedef void (ProfileGenerator::*ProfileFunction)(ExecState* callerOrHandlerCallFrame, const CallIdentifier& callIdentifier); private: ProfileGenerator(const UString& title, ExecState* originatingExec, unsigned uid); diff --git a/JavaScriptCore/profiler/ProfileNode.cpp b/JavaScriptCore/profiler/ProfileNode.cpp index bfcfcbe..8f20bbe 100644 --- a/JavaScriptCore/profiler/ProfileNode.cpp +++ b/JavaScriptCore/profiler/ProfileNode.cpp @@ -56,8 +56,9 @@ static double getCount() #endif } -ProfileNode::ProfileNode(const CallIdentifier& callIdentifier, ProfileNode* headNode, ProfileNode* parentNode) - : m_callIdentifier(callIdentifier) +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) @@ -72,8 +73,9 @@ ProfileNode::ProfileNode(const CallIdentifier& callIdentifier, ProfileNode* head startTimer(); } -ProfileNode::ProfileNode(ProfileNode* headNode, ProfileNode* nodeToCopy) - : m_callIdentifier(nodeToCopy->callIdentifier()) +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) @@ -87,7 +89,7 @@ ProfileNode::ProfileNode(ProfileNode* headNode, ProfileNode* nodeToCopy) { } -ProfileNode* ProfileNode::willExecute(const CallIdentifier& callIdentifier) +ProfileNode* ProfileNode::willExecute(ExecState* callerCallFrame, const CallIdentifier& callIdentifier) { for (StackIterator currentChild = m_children.begin(); currentChild != m_children.end(); ++currentChild) { if ((*currentChild)->callIdentifier() == callIdentifier) { @@ -96,7 +98,7 @@ ProfileNode* ProfileNode::willExecute(const CallIdentifier& callIdentifier) } } - RefPtr<ProfileNode> newChild = ProfileNode::create(callIdentifier, m_head ? m_head : this, this); // If this ProfileNode has no head it is the head. + 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()); diff --git a/JavaScriptCore/profiler/ProfileNode.h b/JavaScriptCore/profiler/ProfileNode.h index eafeea6..ffe7b6f 100644 --- a/JavaScriptCore/profiler/ProfileNode.h +++ b/JavaScriptCore/profiler/ProfileNode.h @@ -37,6 +37,7 @@ namespace JSC { + class ExecState; class ProfileNode; typedef Vector<RefPtr<ProfileNode> >::const_iterator StackIterator; @@ -44,23 +45,24 @@ namespace JSC { class ProfileNode : public RefCounted<ProfileNode> { public: - static PassRefPtr<ProfileNode> create(const CallIdentifier& callIdentifier, ProfileNode* headNode, ProfileNode* parentNode) + static PassRefPtr<ProfileNode> create(ExecState* callerCallFrame, const CallIdentifier& callIdentifier, ProfileNode* headNode, ProfileNode* parentNode) { - return adoptRef(new ProfileNode(callIdentifier, headNode, parentNode)); + return adoptRef(new ProfileNode(callerCallFrame, callIdentifier, headNode, parentNode)); } - static PassRefPtr<ProfileNode> create(ProfileNode* headNode, ProfileNode* node) + static PassRefPtr<ProfileNode> create(ExecState* callerCallFrame, ProfileNode* headNode, ProfileNode* node) { - return adoptRef(new ProfileNode(headNode, node)); + return adoptRef(new ProfileNode(callerCallFrame, headNode, node)); } bool operator==(ProfileNode* node) { return m_callIdentifier == node->callIdentifier(); } - ProfileNode* willExecute(const 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; } @@ -128,8 +130,8 @@ namespace JSC { #endif private: - ProfileNode(const CallIdentifier&, ProfileNode* headNode, ProfileNode* parentNode); - ProfileNode(ProfileNode* headNode, ProfileNode* nodeToCopy); + ProfileNode(ExecState* callerCallFrame, const CallIdentifier&, ProfileNode* headNode, ProfileNode* parentNode); + ProfileNode(ExecState* callerCallFrame, ProfileNode* headNode, ProfileNode* nodeToCopy); void startTimer(); void resetChildrensSiblings(); @@ -147,6 +149,7 @@ namespace JSC { 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; diff --git a/JavaScriptCore/profiler/Profiler.cpp b/JavaScriptCore/profiler/Profiler.cpp index 78fe2f5..9ac73fd 100644 --- a/JavaScriptCore/profiler/Profiler.cpp +++ b/JavaScriptCore/profiler/Profiler.cpp @@ -99,42 +99,49 @@ PassRefPtr<Profile> Profiler::stopProfiling(ExecState* exec, const UString& titl return 0; } -static inline void dispatchFunctionToProfiles(const Vector<RefPtr<ProfileGenerator> >& profiles, ProfileGenerator::ProfileFunction function, const CallIdentifier& callIdentifier, unsigned currentProfileTargetGroup) +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)(callIdentifier); + (profiles[i].get()->*function)(callerOrHandlerCallFrame, callIdentifier); } } -void Profiler::willExecute(ExecState* exec, JSValue function) +void Profiler::willExecute(ExecState* callerCallFrame, JSValue function) { ASSERT(!m_currentProfiles.isEmpty()); - dispatchFunctionToProfiles(m_currentProfiles, &ProfileGenerator::willExecute, createCallIdentifier(exec, function, "", 0), exec->lexicalGlobalObject()->profileGroup()); + dispatchFunctionToProfiles(callerCallFrame, m_currentProfiles, &ProfileGenerator::willExecute, createCallIdentifier(callerCallFrame, function, "", 0), callerCallFrame->lexicalGlobalObject()->profileGroup()); } -void Profiler::willExecute(ExecState* exec, const UString& sourceURL, int startingLineNumber) +void Profiler::willExecute(ExecState* callerCallFrame, const UString& sourceURL, int startingLineNumber) { ASSERT(!m_currentProfiles.isEmpty()); - CallIdentifier callIdentifier = createCallIdentifier(exec, JSValue(), sourceURL, startingLineNumber); + CallIdentifier callIdentifier = createCallIdentifier(callerCallFrame, JSValue(), sourceURL, startingLineNumber); - dispatchFunctionToProfiles(m_currentProfiles, &ProfileGenerator::willExecute, callIdentifier, exec->lexicalGlobalObject()->profileGroup()); + dispatchFunctionToProfiles(callerCallFrame, m_currentProfiles, &ProfileGenerator::willExecute, callIdentifier, callerCallFrame->lexicalGlobalObject()->profileGroup()); } -void Profiler::didExecute(ExecState* exec, JSValue function) +void Profiler::didExecute(ExecState* callerCallFrame, JSValue function) { ASSERT(!m_currentProfiles.isEmpty()); - dispatchFunctionToProfiles(m_currentProfiles, &ProfileGenerator::didExecute, createCallIdentifier(exec, function, "", 0), exec->lexicalGlobalObject()->profileGroup()); + dispatchFunctionToProfiles(callerCallFrame, m_currentProfiles, &ProfileGenerator::didExecute, createCallIdentifier(callerCallFrame, function, "", 0), callerCallFrame->lexicalGlobalObject()->profileGroup()); } -void Profiler::didExecute(ExecState* exec, const UString& sourceURL, int startingLineNumber) +void Profiler::didExecute(ExecState* callerCallFrame, const UString& sourceURL, int startingLineNumber) { ASSERT(!m_currentProfiles.isEmpty()); - dispatchFunctionToProfiles(m_currentProfiles, &ProfileGenerator::didExecute, createCallIdentifier(exec, JSValue(), sourceURL, startingLineNumber), exec->lexicalGlobalObject()->profileGroup()); + 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) diff --git a/JavaScriptCore/profiler/Profiler.h b/JavaScriptCore/profiler/Profiler.h index 4b8b4a0..f9c2ccb 100644 --- a/JavaScriptCore/profiler/Profiler.h +++ b/JavaScriptCore/profiler/Profiler.h @@ -57,10 +57,12 @@ namespace JSC { void startProfiling(ExecState*, const UString& title); PassRefPtr<Profile> stopProfiling(ExecState*, const UString& title); - void willExecute(ExecState*, JSValue function); - void willExecute(ExecState*, const UString& sourceURL, int startingLineNumber); - void didExecute(ExecState*, JSValue function); - void didExecute(ExecState*, const UString& sourceURL, int startingLineNumber); + 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; }; |