Index: Source/core/inspector/AsyncCallStackTracker.cpp |
diff --git a/Source/core/inspector/AsyncCallStackTracker.cpp b/Source/core/inspector/AsyncCallStackTracker.cpp |
index cb4d83a9eb15b8d10562964f0924ced021fb6f47..8c8819a05b88cae129d4f5f047848711eee9652c 100644 |
--- a/Source/core/inspector/AsyncCallStackTracker.cpp |
+++ b/Source/core/inspector/AsyncCallStackTracker.cpp |
@@ -40,6 +40,7 @@ |
#include "core/events/EventTarget.h" |
#include "core/xml/XMLHttpRequest.h" |
#include "core/xml/XMLHttpRequestUpload.h" |
+#include "platform/AsyncFileSystemCallbacks.h" |
#include "wtf/text/StringBuilder.h" |
#include "wtf/text/StringHash.h" |
#include <v8.h> |
@@ -51,6 +52,7 @@ static const char setIntervalName[] = "setInterval"; |
static const char requestAnimationFrameName[] = "requestAnimationFrame"; |
static const char xhrSendName[] = "XMLHttpRequest.send"; |
static const char enqueueMutationRecordName[] = "Mutation"; |
+static const char fileSystemName[] = "FileSystem"; |
} |
@@ -83,6 +85,7 @@ public: |
HashMap<EventTarget*, RefPtr<AsyncCallChain> > m_xhrCallChains; |
HashMap<MutationObserver*, RefPtr<AsyncCallChain> > m_mutationObserverCallChains; |
HashMap<ExecutionContextTask*, RefPtr<AsyncCallChain> > m_executionContextTaskCallChains; |
+ HashMap<AsyncFileSystemCallbacks*, RefPtr<AsyncCallChain> > m_fileSystemCallChains; |
HashMap<String, RefPtr<AsyncCallChain> > m_v8AsyncTaskCallChains; |
}; |
@@ -327,6 +330,38 @@ void AsyncCallStackTracker::willPerformExecutionContextTask(ExecutionContext* co |
setCurrentAsyncCallChain(context, nullptr); |
} |
+void AsyncCallStackTracker::didEnqueueAsyncFileSystemCallback(ExecutionContext* context, AsyncFileSystemCallbacks* callback, const ScriptValue& callFrames) |
+{ |
+ ASSERT(context); |
+ ASSERT(isEnabled()); |
+ if (!validateCallFrames(callFrames)) |
+ return; |
+ ExecutionContextData* data = createContextDataIfNeeded(context); |
+ data->m_fileSystemCallChains.set(callback, createAsyncCallChain(fileSystemName, callFrames)); |
+} |
+ |
+void AsyncCallStackTracker::didRemoveAsyncFileSystemCallback(ExecutionContext* context, AsyncFileSystemCallbacks* callback) |
+{ |
+ ASSERT(context); |
+ ASSERT(isEnabled()); |
+ if (ExecutionContextData* data = m_executionContextDataMap.get(context)) |
+ data->m_fileSystemCallChains.remove(callback); |
+} |
+ |
+void AsyncCallStackTracker::willHandleAsyncFileSystemCallback(ExecutionContext* context, AsyncFileSystemCallbacks* callback, bool hasMore) |
+{ |
+ ASSERT(context); |
+ ASSERT(isEnabled()); |
+ if (ExecutionContextData* data = m_executionContextDataMap.get(context)) { |
+ if (hasMore) |
+ setCurrentAsyncCallChain(context, data->m_fileSystemCallChains.get(callback)); |
yurys
2014/07/14 14:55:54
style: consider extracting setCurrentAsyncCallChai
|
+ else |
+ setCurrentAsyncCallChain(context, data->m_fileSystemCallChains.take(callback)); |
+ } else { |
+ setCurrentAsyncCallChain(context, nullptr); |
+ } |
+} |
+ |
static String makeV8AsyncTaskUniqueId(const String& eventName, int id) |
{ |
StringBuilder builder; |
@@ -360,11 +395,28 @@ void AsyncCallStackTracker::didFireAsyncCall() |
clearCurrentAsyncCallChain(); |
} |
+void AsyncCallStackTracker::willRescheduleAsyncCallChain() |
+{ |
+ ASSERT(isEnabled()); |
+ if (!m_rescheduledAsyncCallChain) |
+ m_rescheduleNextAsyncCallChain = true; |
+} |
+ |
+void AsyncCallStackTracker::didRescheduleAsyncCallChain() |
+{ |
+ ASSERT(isEnabled()); |
+ m_rescheduleNextAsyncCallChain = false; |
+ m_rescheduledAsyncCallChain.clear(); |
+} |
+ |
PassRefPtr<AsyncCallStackTracker::AsyncCallChain> AsyncCallStackTracker::createAsyncCallChain(const String& description, const ScriptValue& callFrames) |
{ |
+ // Check if we should propogate the async call stack chain. |
+ if (m_rescheduledAsyncCallChain) |
+ return m_rescheduledAsyncCallChain; |
if (callFrames.isEmpty()) { |
ASSERT(m_currentAsyncCallChain); |
- return m_currentAsyncCallChain; // Propogate async call stack chain. |
+ return m_currentAsyncCallChain; |
} |
RefPtr<AsyncCallChain> chain = adoptRef(m_currentAsyncCallChain ? new AsyncCallStackTracker::AsyncCallChain(*m_currentAsyncCallChain) : new AsyncCallStackTracker::AsyncCallChain()); |
ensureMaxAsyncCallChainDepth(chain.get(), m_maxAsyncCallStackDepth - 1); |
@@ -374,6 +426,10 @@ PassRefPtr<AsyncCallStackTracker::AsyncCallChain> AsyncCallStackTracker::createA |
void AsyncCallStackTracker::setCurrentAsyncCallChain(ExecutionContext* context, PassRefPtr<AsyncCallChain> chain) |
{ |
+ if (m_rescheduleNextAsyncCallChain) { |
+ m_rescheduleNextAsyncCallChain = false; |
+ m_rescheduledAsyncCallChain = chain.get(); |
+ } |
if (V8RecursionScope::recursionLevel(toIsolate(context))) { |
if (m_currentAsyncCallChain) |
++m_nestedAsyncCallCount; |
@@ -401,7 +457,7 @@ void AsyncCallStackTracker::ensureMaxAsyncCallChainDepth(AsyncCallChain* chain, |
bool AsyncCallStackTracker::validateCallFrames(const ScriptValue& callFrames) |
{ |
- return !callFrames.isEmpty() || m_currentAsyncCallChain; |
+ return !callFrames.isEmpty() || m_currentAsyncCallChain || m_rescheduledAsyncCallChain; |
} |
AsyncCallStackTracker::ExecutionContextData* AsyncCallStackTracker::createContextDataIfNeeded(ExecutionContext* context) |
@@ -418,6 +474,8 @@ void AsyncCallStackTracker::clear() |
{ |
m_currentAsyncCallChain.clear(); |
m_nestedAsyncCallCount = 0; |
+ m_rescheduleNextAsyncCallChain = false; |
+ m_rescheduledAsyncCallChain.clear(); |
ExecutionContextDataMap copy; |
m_executionContextDataMap.swap(copy); |
for (ExecutionContextDataMap::const_iterator it = copy.begin(); it != copy.end(); ++it) |