Index: Source/core/inspector/AsyncCallStackTracker.cpp |
diff --git a/Source/core/inspector/AsyncCallStackTracker.cpp b/Source/core/inspector/AsyncCallStackTracker.cpp |
index f899e041ec14d62c1432c7bfbab0c78c3a105b8c..34c9129487a2c2b94ad2970528aeb2bf2369295d 100644 |
--- a/Source/core/inspector/AsyncCallStackTracker.cpp |
+++ b/Source/core/inspector/AsyncCallStackTracker.cpp |
@@ -63,22 +63,29 @@ class AsyncCallStackTracker::AsyncCallChainMap final { |
ALLOW_ONLY_INLINE_ALLOCATION(); |
public: |
using MapType = WillBeHeapHashMap<K, RefPtrWillBeMember<AsyncCallStackTracker::AsyncCallChain>>; |
- explicit AsyncCallChainMap(AsyncCallStackTracker* tracker) : m_tracker(tracker) { } |
+ explicit AsyncCallChainMap(AsyncCallStackTracker* tracker) |
+ : m_tracker(tracker) |
+ { |
+ } |
~AsyncCallChainMap() |
{ |
- clear(); |
+ // Verify that this object has been explicitly cleared already. |
+ ASSERT(!m_tracker); |
} |
void clear() |
aandrey
2014/12/12 08:40:52
nit: clear -> dispose
sof
2014/12/12 09:16:33
done.
|
{ |
- for (auto it : m_asyncCallChains) { |
- if (AsyncCallStackTracker::Listener* listener = m_tracker->m_listener) |
+ if (!m_tracker) |
aandrey
2014/12/12 08:40:52
once a clear() is called, the object is unusable.
sof
2014/12/12 09:16:33
Done.
|
+ return; |
+ |
+ if (AsyncCallStackTracker::Listener* listener = m_tracker->m_listener) { |
+ for (auto it : m_asyncCallChains) { |
listener->didRemoveAsyncCallChain(it.value.get()); |
aandrey
2014/12/12 08:40:52
please revert, as a didRemoveAsyncCallChain() may
sof
2014/12/12 09:16:33
Done.
|
- else |
- break; |
+ } |
} |
m_asyncCallChains.clear(); |
+ m_tracker = nullptr; |
} |
void set(typename MapType::KeyPeekInType key, PassRefPtrWillBeRawPtr<AsyncCallChain> chain) |
@@ -98,6 +105,7 @@ public: |
void remove(typename MapType::KeyPeekInType key) |
{ |
+ ASSERT(m_tracker); |
RefPtrWillBeRawPtr<AsyncCallStackTracker::AsyncCallChain> chain = m_asyncCallChains.take(key); |
if (chain && m_tracker->m_listener) |
m_tracker->m_listener->didRemoveAsyncCallChain(chain.get()); |
@@ -105,11 +113,12 @@ public: |
void trace(Visitor* visitor) |
{ |
+ visitor->trace(m_tracker); |
visitor->trace(m_asyncCallChains); |
} |
private: |
- AsyncCallStackTracker* m_tracker; |
+ RawPtrWillBeMember<AsyncCallStackTracker> m_tracker; |
MapType m_asyncCallChains; |
}; |
@@ -137,6 +146,7 @@ public: |
OwnPtrWillBeRawPtr<ExecutionContextData> self = m_tracker->m_executionContextDataMap.take(executionContext()); |
ASSERT_UNUSED(self, self == this); |
ContextLifecycleObserver::contextDestroyed(); |
+ dispose(); |
} |
int nextAsyncOperationUniqueId() |
@@ -164,6 +174,18 @@ public: |
#endif |
} |
+ void dispose() |
+ { |
+ m_timerCallChains.clear(); |
+ m_animationFrameCallChains.clear(); |
+ m_eventCallChains.clear(); |
+ m_xhrCallChains.clear(); |
+ m_mutationObserverCallChains.clear(); |
+ m_executionContextTaskCallChains.clear(); |
+ m_v8AsyncTaskCallChains.clear(); |
+ m_asyncOperationCallChains.clear(); |
+ } |
+ |
RawPtrWillBeMember<AsyncCallStackTracker> m_tracker; |
HashSet<int> m_intervalTimerIds; |
AsyncCallChainMap<int> m_timerCallChains; |
@@ -598,6 +620,9 @@ void AsyncCallStackTracker::clear() |
{ |
m_currentAsyncCallChain.clear(); |
m_nestedAsyncCallCount = 0; |
+ for (auto& it : m_executionContextDataMap) { |
aandrey
2014/12/12 08:40:52
nit: no need for { }
sof
2014/12/12 09:16:33
done.
|
+ it.value->dispose(); |
+ } |
m_executionContextDataMap.clear(); |
} |