Chromium Code Reviews| 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(); |
| } |