Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(810)

Unified Diff: Source/core/inspector/AsyncCallStackTracker.cpp

Issue 118293002: DevTools: Support XHR async call stacks in the debugger. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: addressed Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/inspector/AsyncCallStackTracker.h ('k') | Source/core/inspector/InspectorDebuggerAgent.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/inspector/AsyncCallStackTracker.cpp
diff --git a/Source/core/inspector/AsyncCallStackTracker.cpp b/Source/core/inspector/AsyncCallStackTracker.cpp
index 841c94667395ff8770fe72ba997c60f5fc033a48..7d9c579e3a41f1e919aee1a9a1eac10647f542d5 100644
--- a/Source/core/inspector/AsyncCallStackTracker.cpp
+++ b/Source/core/inspector/AsyncCallStackTracker.cpp
@@ -35,8 +35,20 @@
#include "core/dom/ExecutionContext.h"
#include "core/events/EventTarget.h"
#include "core/events/RegisteredEventListener.h"
+#include "core/xml/XMLHttpRequest.h"
+#include "core/xml/XMLHttpRequestUpload.h"
+#include "wtf/text/AtomicStringHash.h"
#include "wtf/text/StringBuilder.h"
+namespace {
+
+static const char setTimeoutName[] = "setTimeout";
+static const char setIntervalName[] = "setInterval";
+static const char requestAnimationFrameName[] = "requestAnimationFrame";
+static const char xhrSendName[] = "XMLHttpRequest.send";
+
+}
+
namespace WebCore {
class AsyncCallStackTracker::ExecutionContextData : public ContextLifecycleObserver {
@@ -111,8 +123,19 @@ public:
HashMap<int, RefPtr<AsyncCallChain> > m_timerCallChains;
HashMap<int, RefPtr<AsyncCallChain> > m_animationFrameCallChains;
HashMap<EventTarget*, EventListenerAsyncCallChainVectorHashMap> m_eventTargetCallChains;
+ HashMap<EventTarget*, RefPtr<AsyncCallChain> > m_xhrCallChains;
};
+static XMLHttpRequest* toXmlHttpRequest(EventTarget* eventTarget)
+{
+ const AtomicString& interfaceName = eventTarget->interfaceName();
+ if (interfaceName == EventTargetNames::XMLHttpRequest)
+ return static_cast<XMLHttpRequest*>(eventTarget);
+ if (interfaceName == EventTargetNames::XMLHttpRequestUpload)
+ return static_cast<XMLHttpRequestUpload*>(eventTarget)->xmlHttpRequest();
+ return 0;
+}
+
AsyncCallStackTracker::AsyncCallStack::AsyncCallStack(const String& description, const ScriptValue& callFrames)
: m_description(description)
, m_callFrames(callFrames)
@@ -147,9 +170,6 @@ const AsyncCallStackTracker::AsyncCallChain* AsyncCallStackTracker::currentAsync
void AsyncCallStackTracker::didInstallTimer(ExecutionContext* context, int timerId, bool singleShot, const ScriptValue& callFrames)
{
- DEFINE_STATIC_LOCAL(String, setTimeoutName, ("setTimeout"));
- DEFINE_STATIC_LOCAL(String, setIntervalName, ("setInterval"));
-
ASSERT(context);
ASSERT(isEnabled());
if (!validateCallFrames(callFrames))
@@ -180,19 +200,18 @@ void AsyncCallStackTracker::willFireTimer(ExecutionContext* context, int timerId
ASSERT(isEnabled());
ASSERT(timerId > 0);
ASSERT(!m_currentAsyncCallChain);
- ExecutionContextData* data = m_executionContextDataMap.get(context);
- if (!data)
- return;
- if (data->m_intervalTimerIds.contains(timerId))
- setCurrentAsyncCallChain(data->m_timerCallChains.get(timerId));
- else
- setCurrentAsyncCallChain(data->m_timerCallChains.take(timerId));
+ if (ExecutionContextData* data = m_executionContextDataMap.get(context)) {
+ if (data->m_intervalTimerIds.contains(timerId))
+ setCurrentAsyncCallChain(data->m_timerCallChains.get(timerId));
+ else
+ setCurrentAsyncCallChain(data->m_timerCallChains.take(timerId));
+ } else {
+ setCurrentAsyncCallChain(0);
+ }
}
void AsyncCallStackTracker::didRequestAnimationFrame(ExecutionContext* context, int callbackId, const ScriptValue& callFrames)
{
- DEFINE_STATIC_LOCAL(String, requestAnimationFrameName, ("requestAnimationFrame"));
-
ASSERT(context);
ASSERT(isEnabled());
if (!validateCallFrames(callFrames))
@@ -220,13 +239,15 @@ void AsyncCallStackTracker::willFireAnimationFrame(ExecutionContext* context, in
ASSERT(!m_currentAsyncCallChain);
if (ExecutionContextData* data = m_executionContextDataMap.get(context))
setCurrentAsyncCallChain(data->m_animationFrameCallChains.take(callbackId));
+ else
+ setCurrentAsyncCallChain(0);
}
void AsyncCallStackTracker::didAddEventListener(EventTarget* eventTarget, const AtomicString& eventType, EventListener* listener, bool useCapture, const ScriptValue& callFrames)
{
ASSERT(eventTarget->executionContext());
ASSERT(isEnabled());
- if (!validateCallFrames(callFrames))
+ if (!validateCallFrames(callFrames) || toXmlHttpRequest(eventTarget))
return;
StringBuilder description;
@@ -266,13 +287,44 @@ void AsyncCallStackTracker::willHandleEvent(EventTarget* eventTarget, const Atom
{
ASSERT(eventTarget->executionContext());
ASSERT(isEnabled());
+ if (XMLHttpRequest* xhr = toXmlHttpRequest(eventTarget)) {
+ willHandleXHREvent(xhr, eventTarget, eventType);
+ return;
+ }
if (ExecutionContextData* data = m_executionContextDataMap.get(eventTarget->executionContext()))
setCurrentAsyncCallChain(data->findEventListenerData(eventTarget, eventType, RegisteredEventListener(listener, useCapture)));
+ else
+ setCurrentAsyncCallChain(0);
+}
+
+void AsyncCallStackTracker::willLoadXHR(XMLHttpRequest* xhr, const ScriptValue& callFrames)
+{
+ ASSERT(xhr->executionContext());
+ ASSERT(isEnabled());
+ if (!validateCallFrames(callFrames))
+ return;
+ ExecutionContextData* data = createContextDataIfNeeded(xhr->executionContext());
+ data->m_xhrCallChains.set(xhr, createAsyncCallChain(xhrSendName, callFrames));
+}
+
+void AsyncCallStackTracker::willHandleXHREvent(XMLHttpRequest* xhr, EventTarget* eventTarget, const AtomicString& eventType)
+{
+ ASSERT(xhr->executionContext());
+ ASSERT(isEnabled());
+ if (ExecutionContextData* data = m_executionContextDataMap.get(xhr->executionContext())) {
+ bool isXHRDownload = (xhr == eventTarget);
+ if (isXHRDownload && eventType == EventTypeNames::loadend)
+ setCurrentAsyncCallChain(data->m_xhrCallChains.take(xhr));
+ else
+ setCurrentAsyncCallChain(data->m_xhrCallChains.get(xhr));
+ } else {
+ setCurrentAsyncCallChain(0);
+ }
}
void AsyncCallStackTracker::didFireAsyncCall()
{
- setCurrentAsyncCallChain(0);
+ clearCurrentAsyncCallChain();
}
PassRefPtr<AsyncCallStackTracker::AsyncCallChain> AsyncCallStackTracker::createAsyncCallChain(const String& description, const ScriptValue& callFrames)
@@ -286,15 +338,22 @@ PassRefPtr<AsyncCallStackTracker::AsyncCallChain> AsyncCallStackTracker::createA
void AsyncCallStackTracker::setCurrentAsyncCallChain(PassRefPtr<AsyncCallChain> chain)
{
if (m_currentAsyncCallChain) {
- m_nestedAsyncCallCount += chain ? 1 : -1;
- if (!m_nestedAsyncCallCount)
- m_currentAsyncCallChain = 0;
+ ++m_nestedAsyncCallCount;
} else if (chain) {
m_currentAsyncCallChain = chain;
m_nestedAsyncCallCount = 1;
}
}
+void AsyncCallStackTracker::clearCurrentAsyncCallChain()
+{
+ if (!m_nestedAsyncCallCount)
+ return;
+ --m_nestedAsyncCallCount;
+ if (!m_nestedAsyncCallCount)
+ m_currentAsyncCallChain.clear();
+}
+
void AsyncCallStackTracker::ensureMaxAsyncCallChainDepth(AsyncCallChain* chain, unsigned maxDepth)
{
while (chain->m_callStacks.size() > maxDepth)
@@ -318,7 +377,7 @@ AsyncCallStackTracker::ExecutionContextData* AsyncCallStackTracker::createContex
void AsyncCallStackTracker::clear()
{
- m_currentAsyncCallChain = 0;
+ m_currentAsyncCallChain.clear();
m_nestedAsyncCallCount = 0;
ExecutionContextDataMap copy;
m_executionContextDataMap.swap(copy);
« no previous file with comments | « Source/core/inspector/AsyncCallStackTracker.h ('k') | Source/core/inspector/InspectorDebuggerAgent.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698