summaryrefslogtreecommitdiffstats
path: root/JavaScriptCore/profiler
diff options
context:
space:
mode:
authorShimeng (Simon) Wang <swang@google.com>2010-12-07 17:22:45 -0800
committerShimeng (Simon) Wang <swang@google.com>2010-12-22 14:15:40 -0800
commit4576aa36e9a9671459299c7963ac95aa94beaea9 (patch)
tree3863574e050f168c0126ecb47c83319fab0972d8 /JavaScriptCore/profiler
parent55323ac613cc31553107b68603cb627264d22bb0 (diff)
downloadexternal_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.h2
-rw-r--r--JavaScriptCore/profiler/Profile.cpp2
-rw-r--r--JavaScriptCore/profiler/ProfileGenerator.cpp29
-rw-r--r--JavaScriptCore/profiler/ProfileGenerator.h8
-rw-r--r--JavaScriptCore/profiler/ProfileNode.cpp14
-rw-r--r--JavaScriptCore/profiler/ProfileNode.h17
-rw-r--r--JavaScriptCore/profiler/Profiler.cpp29
-rw-r--r--JavaScriptCore/profiler/Profiler.h10
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; };