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..33625830965dc55e967a39ba4252a5e714a43366 100644 |
| --- a/Source/core/inspector/AsyncCallStackTracker.cpp |
| +++ b/Source/core/inspector/AsyncCallStackTracker.cpp |
| @@ -63,15 +63,20 @@ 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() |
| + void dispose() |
|
aandrey
2014/12/12 10:18:53
turns out, we also need clear(), see comment below
sof
2014/12/12 10:32:47
Done.
|
| { |
| + ASSERT(m_tracker); |
| for (auto it : m_asyncCallChains) { |
| if (AsyncCallStackTracker::Listener* listener = m_tracker->m_listener) |
| listener->didRemoveAsyncCallChain(it.value.get()); |
| @@ -79,6 +84,7 @@ public: |
| break; |
| } |
| m_asyncCallChains.clear(); |
| + m_tracker = nullptr; |
| } |
| void set(typename MapType::KeyPeekInType key, PassRefPtrWillBeRawPtr<AsyncCallChain> chain) |
| @@ -98,6 +104,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 +112,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 +145,7 @@ public: |
| OwnPtrWillBeRawPtr<ExecutionContextData> self = m_tracker->m_executionContextDataMap.take(executionContext()); |
| ASSERT_UNUSED(self, self == this); |
| ContextLifecycleObserver::contextDestroyed(); |
| + dispose(); |
| } |
| int nextAsyncOperationUniqueId() |
| @@ -164,6 +173,18 @@ public: |
| #endif |
| } |
| + void dispose() |
| + { |
| + m_timerCallChains.dispose(); |
| + m_animationFrameCallChains.dispose(); |
| + m_eventCallChains.dispose(); |
| + m_xhrCallChains.dispose(); |
| + m_mutationObserverCallChains.dispose(); |
| + m_executionContextTaskCallChains.dispose(); |
| + m_v8AsyncTaskCallChains.dispose(); |
| + m_asyncOperationCallChains.dispose(); |
| + } |
| + |
| RawPtrWillBeMember<AsyncCallStackTracker> m_tracker; |
| HashSet<int> m_intervalTimerIds; |
| AsyncCallChainMap<int> m_timerCallChains; |
| @@ -434,7 +455,7 @@ void AsyncCallStackTracker::didKillAllExecutionContextTasks(ExecutionContext* co |
| ASSERT(context); |
| ASSERT(isEnabled()); |
| if (ExecutionContextData* data = m_executionContextDataMap.get(context)) |
| - data->m_executionContextTaskCallChains.clear(); |
| + data->m_executionContextTaskCallChains.dispose(); |
|
aandrey
2014/12/12 10:18:53
this should be clear() and leave m_executionContex
sof
2014/12/12 10:26:06
Seems like the null check in clear() wasn't such a
sof
2014/12/12 10:32:47
Done.
|
| } |
| void AsyncCallStackTracker::willPerformExecutionContextTask(ExecutionContext* context, ExecutionContextTask* task) |
| @@ -598,6 +619,8 @@ void AsyncCallStackTracker::clear() |
| { |
| m_currentAsyncCallChain.clear(); |
| m_nestedAsyncCallCount = 0; |
| + for (auto& it : m_executionContextDataMap) |
| + it.value->dispose(); |
| m_executionContextDataMap.clear(); |
| } |