| Index: Source/core/inspector/AsyncCallStackTracker.cpp
|
| diff --git a/Source/core/inspector/AsyncCallStackTracker.cpp b/Source/core/inspector/AsyncCallStackTracker.cpp
|
| index a6b68a5f7a38c8d5dcae9aa7f71ef621f2089255..cb4d83a9eb15b8d10562964f0924ced021fb6f47 100644
|
| --- a/Source/core/inspector/AsyncCallStackTracker.cpp
|
| +++ b/Source/core/inspector/AsyncCallStackTracker.cpp
|
| @@ -40,8 +40,8 @@
|
| #include "core/events/EventTarget.h"
|
| #include "core/xml/XMLHttpRequest.h"
|
| #include "core/xml/XMLHttpRequestUpload.h"
|
| -#include "wtf/text/AtomicStringHash.h"
|
| #include "wtf/text/StringBuilder.h"
|
| +#include "wtf/text/StringHash.h"
|
| #include <v8.h>
|
|
|
| namespace {
|
| @@ -83,6 +83,7 @@ public:
|
| HashMap<EventTarget*, RefPtr<AsyncCallChain> > m_xhrCallChains;
|
| HashMap<MutationObserver*, RefPtr<AsyncCallChain> > m_mutationObserverCallChains;
|
| HashMap<ExecutionContextTask*, RefPtr<AsyncCallChain> > m_executionContextTaskCallChains;
|
| + HashMap<String, RefPtr<AsyncCallChain> > m_v8AsyncTaskCallChains;
|
| };
|
|
|
| static XMLHttpRequest* toXmlHttpRequest(EventTarget* eventTarget)
|
| @@ -326,6 +327,34 @@ void AsyncCallStackTracker::willPerformExecutionContextTask(ExecutionContext* co
|
| setCurrentAsyncCallChain(context, nullptr);
|
| }
|
|
|
| +static String makeV8AsyncTaskUniqueId(const String& eventName, int id)
|
| +{
|
| + StringBuilder builder;
|
| + builder.append(eventName);
|
| + builder.appendNumber(id);
|
| + return builder.toString();
|
| +}
|
| +
|
| +void AsyncCallStackTracker::didEnqueueV8AsyncTask(ExecutionContext* context, const String& eventName, int id, const ScriptValue& callFrames)
|
| +{
|
| + ASSERT(context);
|
| + ASSERT(isEnabled());
|
| + if (!validateCallFrames(callFrames))
|
| + return;
|
| + ExecutionContextData* data = createContextDataIfNeeded(context);
|
| + data->m_v8AsyncTaskCallChains.set(makeV8AsyncTaskUniqueId(eventName, id), createAsyncCallChain(eventName, callFrames));
|
| +}
|
| +
|
| +void AsyncCallStackTracker::willHandleV8AsyncTask(ExecutionContext* context, const String& eventName, int id)
|
| +{
|
| + ASSERT(context);
|
| + ASSERT(isEnabled());
|
| + if (ExecutionContextData* data = m_executionContextDataMap.get(context))
|
| + setCurrentAsyncCallChain(context, data->m_v8AsyncTaskCallChains.take(makeV8AsyncTaskUniqueId(eventName, id)));
|
| + else
|
| + setCurrentAsyncCallChain(context, nullptr);
|
| +}
|
| +
|
| void AsyncCallStackTracker::didFireAsyncCall()
|
| {
|
| clearCurrentAsyncCallChain();
|
| @@ -333,6 +362,10 @@ void AsyncCallStackTracker::didFireAsyncCall()
|
|
|
| PassRefPtr<AsyncCallStackTracker::AsyncCallChain> AsyncCallStackTracker::createAsyncCallChain(const String& description, const ScriptValue& callFrames)
|
| {
|
| + if (callFrames.isEmpty()) {
|
| + ASSERT(m_currentAsyncCallChain);
|
| + return m_currentAsyncCallChain; // Propogate async call stack chain.
|
| + }
|
| RefPtr<AsyncCallChain> chain = adoptRef(m_currentAsyncCallChain ? new AsyncCallStackTracker::AsyncCallChain(*m_currentAsyncCallChain) : new AsyncCallStackTracker::AsyncCallChain());
|
| ensureMaxAsyncCallChainDepth(chain.get(), m_maxAsyncCallStackDepth - 1);
|
| chain->m_callStacks.prepend(adoptRef(new AsyncCallStackTracker::AsyncCallStack(description, callFrames)));
|
| @@ -368,7 +401,7 @@ void AsyncCallStackTracker::ensureMaxAsyncCallChainDepth(AsyncCallChain* chain,
|
|
|
| bool AsyncCallStackTracker::validateCallFrames(const ScriptValue& callFrames)
|
| {
|
| - return !callFrames.isEmpty();
|
| + return !callFrames.isEmpty() || m_currentAsyncCallChain;
|
| }
|
|
|
| AsyncCallStackTracker::ExecutionContextData* AsyncCallStackTracker::createContextDataIfNeeded(ExecutionContext* context)
|
|
|