 Chromium Code Reviews
 Chromium Code Reviews Issue 1198863006:
  First version of PerformanceObserver  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/blink.git@master
    
  
    Issue 1198863006:
  First version of PerformanceObserver  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/blink.git@master| OLD | NEW | 
|---|---|
| 1 /* | 1 /* | 
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 
| 3 * | 3 * | 
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without | 
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are | 
| 6 * met: | 6 * met: | 
| 7 * | 7 * | 
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright | 
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. | 
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above | 
| (...skipping 20 matching lines...) Expand all Loading... | |
| 31 #include "config.h" | 31 #include "config.h" | 
| 32 #include "core/inspector/AsyncCallTracker.h" | 32 #include "core/inspector/AsyncCallTracker.h" | 
| 33 | 33 | 
| 34 #include "core/dom/ContextLifecycleObserver.h" | 34 #include "core/dom/ContextLifecycleObserver.h" | 
| 35 #include "core/dom/ExecutionContext.h" | 35 #include "core/dom/ExecutionContext.h" | 
| 36 #include "core/dom/ExecutionContextTask.h" | 36 #include "core/dom/ExecutionContextTask.h" | 
| 37 #include "core/events/Event.h" | 37 #include "core/events/Event.h" | 
| 38 #include "core/events/EventTarget.h" | 38 #include "core/events/EventTarget.h" | 
| 39 #include "core/inspector/AsyncOperationMap.h" | 39 #include "core/inspector/AsyncOperationMap.h" | 
| 40 #include "core/inspector/InspectorDebuggerAgent.h" | 40 #include "core/inspector/InspectorDebuggerAgent.h" | 
| 41 #include "core/timing/PerformanceObserver.h" | |
| 41 #include "core/xmlhttprequest/XMLHttpRequest.h" | 42 #include "core/xmlhttprequest/XMLHttpRequest.h" | 
| 42 #include "core/xmlhttprequest/XMLHttpRequestUpload.h" | 43 #include "core/xmlhttprequest/XMLHttpRequestUpload.h" | 
| 43 #include "wtf/text/StringBuilder.h" | 44 #include "wtf/text/StringBuilder.h" | 
| 44 #include "wtf/text/StringHash.h" | 45 #include "wtf/text/StringHash.h" | 
| 45 | 46 | 
| 46 namespace { | 47 namespace { | 
| 47 | 48 | 
| 48 static const char setTimeoutName[] = "setTimeout"; | 49 static const char setTimeoutName[] = "setTimeout"; | 
| 49 static const char setIntervalName[] = "setInterval"; | 50 static const char setIntervalName[] = "setInterval"; | 
| 50 static const char requestAnimationFrameName[] = "requestAnimationFrame"; | 51 static const char requestAnimationFrameName[] = "requestAnimationFrame"; | 
| 51 static const char xhrSendName[] = "XMLHttpRequest.send"; | 52 static const char xhrSendName[] = "XMLHttpRequest.send"; | 
| 52 static const char enqueueMutationRecordName[] = "Mutation"; | 53 static const char enqueueMutationRecordName[] = "Mutation"; | 
| 54 static const char enqueuePerformanceObservationsName[] = "PerformanceObservation "; | |
| 53 | 55 | 
| 54 } | 56 } | 
| 55 | 57 | 
| 56 namespace blink { | 58 namespace blink { | 
| 57 | 59 | 
| 58 class AsyncCallTracker::ExecutionContextData final : public NoBaseWillBeGarbageC ollectedFinalized<ExecutionContextData>, public ContextLifecycleObserver { | 60 class AsyncCallTracker::ExecutionContextData final : public NoBaseWillBeGarbageC ollectedFinalized<ExecutionContextData>, public ContextLifecycleObserver { | 
| 59 WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(AsyncCallTracker::ExecutionContextData ); | 61 WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(AsyncCallTracker::ExecutionContextData ); | 
| 60 WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED(AsyncCallTracker::ExecutionContextDa ta); | 62 WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED(AsyncCallTracker::ExecutionContextDa ta); | 
| 61 public: | 63 public: | 
| 62 ExecutionContextData(AsyncCallTracker* tracker, ExecutionContext* executionC ontext) | 64 ExecutionContextData(AsyncCallTracker* tracker, ExecutionContext* executionC ontext) | 
| 63 : ContextLifecycleObserver(executionContext) | 65 : ContextLifecycleObserver(executionContext) | 
| 64 , m_tracker(tracker) | 66 , m_tracker(tracker) | 
| 65 , m_timerCallChains(tracker->m_debuggerAgent) | 67 , m_timerCallChains(tracker->m_debuggerAgent) | 
| 66 , m_animationFrameCallChains(tracker->m_debuggerAgent) | 68 , m_animationFrameCallChains(tracker->m_debuggerAgent) | 
| 67 , m_eventCallChains(tracker->m_debuggerAgent) | 69 , m_eventCallChains(tracker->m_debuggerAgent) | 
| 68 , m_xhrCallChains(tracker->m_debuggerAgent) | 70 , m_xhrCallChains(tracker->m_debuggerAgent) | 
| 69 , m_mutationObserverCallChains(tracker->m_debuggerAgent) | 71 , m_mutationObserverCallChains(tracker->m_debuggerAgent) | 
| 72 , m_performanceObserverCallChains(tracker->m_debuggerAgent) | |
| 70 , m_executionContextTaskCallChains(tracker->m_debuggerAgent) | 73 , m_executionContextTaskCallChains(tracker->m_debuggerAgent) | 
| 71 , m_asyncOperations(tracker->m_debuggerAgent) | 74 , m_asyncOperations(tracker->m_debuggerAgent) | 
| 72 { | 75 { | 
| 73 } | 76 } | 
| 74 | 77 | 
| 75 void contextDestroyed() override | 78 void contextDestroyed() override | 
| 76 { | 79 { | 
| 77 ASSERT(executionContext()); | 80 ASSERT(executionContext()); | 
| 78 OwnPtrWillBeRawPtr<ExecutionContextData> self = m_tracker->m_executionCo ntextDataMap.take(executionContext()); | 81 OwnPtrWillBeRawPtr<ExecutionContextData> self = m_tracker->m_executionCo ntextDataMap.take(executionContext()); | 
| 79 ASSERT_UNUSED(self, self == this); | 82 ASSERT_UNUSED(self, self == this); | 
| (...skipping 12 matching lines...) Expand all Loading... | |
| 92 visitor->trace(m_tracker); | 95 visitor->trace(m_tracker); | 
| 93 #if ENABLE(OILPAN) | 96 #if ENABLE(OILPAN) | 
| 94 visitor->trace(m_timerCallChains); | 97 visitor->trace(m_timerCallChains); | 
| 95 visitor->trace(m_animationFrameCallChains); | 98 visitor->trace(m_animationFrameCallChains); | 
| 96 visitor->trace(m_eventCallChains); | 99 visitor->trace(m_eventCallChains); | 
| 97 visitor->trace(m_xhrCallChains); | 100 visitor->trace(m_xhrCallChains); | 
| 98 visitor->trace(m_mutationObserverCallChains); | 101 visitor->trace(m_mutationObserverCallChains); | 
| 99 visitor->trace(m_executionContextTaskCallChains); | 102 visitor->trace(m_executionContextTaskCallChains); | 
| 100 visitor->trace(m_asyncOperations); | 103 visitor->trace(m_asyncOperations); | 
| 101 #endif | 104 #endif | 
| 105 visitor->trace(m_performanceObserverCallChains); | |
| 102 ContextLifecycleObserver::trace(visitor); | 106 ContextLifecycleObserver::trace(visitor); | 
| 103 } | 107 } | 
| 104 | 108 | 
| 105 RawPtrWillBeMember<AsyncCallTracker> m_tracker; | 109 RawPtrWillBeMember<AsyncCallTracker> m_tracker; | 
| 106 HashSet<int> m_intervalTimerIds; | 110 HashSet<int> m_intervalTimerIds; | 
| 107 AsyncOperationMap<int> m_timerCallChains; | 111 AsyncOperationMap<int> m_timerCallChains; | 
| 108 AsyncOperationMap<int> m_animationFrameCallChains; | 112 AsyncOperationMap<int> m_animationFrameCallChains; | 
| 109 AsyncOperationMap<RawPtrWillBeMember<Event> > m_eventCallChains; | 113 AsyncOperationMap<RawPtrWillBeMember<Event> > m_eventCallChains; | 
| 110 AsyncOperationMap<RawPtrWillBeMember<EventTarget> > m_xhrCallChains; | 114 AsyncOperationMap<RawPtrWillBeMember<EventTarget> > m_xhrCallChains; | 
| 111 AsyncOperationMap<RawPtrWillBeMember<MutationObserver> > m_mutationObserverC allChains; | 115 AsyncOperationMap<RawPtrWillBeMember<MutationObserver> > m_mutationObserverC allChains; | 
| 116 AsyncOperationMap<Member<PerformanceObserver>, HeapHashMap<Member<Performanc eObserver>, int>> m_performanceObserverCallChains; | |
| 112 AsyncOperationMap<ExecutionContextTask*> m_executionContextTaskCallChains; | 117 AsyncOperationMap<ExecutionContextTask*> m_executionContextTaskCallChains; | 
| 113 AsyncOperationMap<int> m_asyncOperations; | 118 AsyncOperationMap<int> m_asyncOperations; | 
| 114 | 119 | 
| 115 private: | 120 private: | 
| 116 void disposeCallChains() | 121 void disposeCallChains() | 
| 117 { | 122 { | 
| 118 m_timerCallChains.dispose(); | 123 m_timerCallChains.dispose(); | 
| 119 m_animationFrameCallChains.dispose(); | 124 m_animationFrameCallChains.dispose(); | 
| 120 m_eventCallChains.dispose(); | 125 m_eventCallChains.dispose(); | 
| 121 m_xhrCallChains.dispose(); | 126 m_xhrCallChains.dispose(); | 
| 122 m_mutationObserverCallChains.dispose(); | 127 m_mutationObserverCallChains.dispose(); | 
| 128 m_performanceObserverCallChains.dispose(); | |
| 123 m_executionContextTaskCallChains.dispose(); | 129 m_executionContextTaskCallChains.dispose(); | 
| 124 m_asyncOperations.dispose(); | 130 m_asyncOperations.dispose(); | 
| 125 } | 131 } | 
| 126 }; | 132 }; | 
| 127 | 133 | 
| 128 static XMLHttpRequest* toXmlHttpRequest(EventTarget* eventTarget) | 134 static XMLHttpRequest* toXmlHttpRequest(EventTarget* eventTarget) | 
| 129 { | 135 { | 
| 130 const AtomicString& interfaceName = eventTarget->interfaceName(); | 136 const AtomicString& interfaceName = eventTarget->interfaceName(); | 
| 131 if (interfaceName == EventTargetNames::XMLHttpRequest) | 137 if (interfaceName == EventTargetNames::XMLHttpRequest) | 
| 132 return static_cast<XMLHttpRequest*>(eventTarget); | 138 return static_cast<XMLHttpRequest*>(eventTarget); | 
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 321 ASSERT(context); | 327 ASSERT(context); | 
| 322 ASSERT(m_debuggerAgent->trackingAsyncCalls()); | 328 ASSERT(m_debuggerAgent->trackingAsyncCalls()); | 
| 323 if (ExecutionContextData* data = m_executionContextDataMap.get(context)) { | 329 if (ExecutionContextData* data = m_executionContextDataMap.get(context)) { | 
| 324 willFireAsyncCall(data->m_mutationObserverCallChains.get(observer)); | 330 willFireAsyncCall(data->m_mutationObserverCallChains.get(observer)); | 
| 325 data->m_mutationObserverCallChains.remove(observer); | 331 data->m_mutationObserverCallChains.remove(observer); | 
| 326 } else { | 332 } else { | 
| 327 willFireAsyncCall(InspectorDebuggerAgent::unknownAsyncOperationId); | 333 willFireAsyncCall(InspectorDebuggerAgent::unknownAsyncOperationId); | 
| 328 } | 334 } | 
| 329 } | 335 } | 
| 330 | 336 | 
| 337 void AsyncCallTracker::didEnqueuePerformanceObserverEntries(ExecutionContext* co ntext, PerformanceObserver* observer) | |
| 
adamk
2015/07/24 21:26:30
Seems sad to have to duplicate all these calls. Wo
 | |
| 338 { | |
| 339 ASSERT(context); | |
| 340 ASSERT(m_debuggerAgent->trackingAsyncCalls()); | |
| 341 ExecutionContextData* data = createContextDataIfNeeded(context); | |
| 342 if (data->m_performanceObserverCallChains.contains(observer)) | |
| 343 return; | |
| 344 int operationId = m_debuggerAgent->traceAsyncOperationStarting(enqueuePerfor manceObservationsName); | |
| 345 data->m_performanceObserverCallChains.set(observer, operationId); | |
| 346 } | |
| 347 | |
| 348 void AsyncCallTracker::didClearAllPerformanceObservations(ExecutionContext* cont ext, PerformanceObserver* observer) | |
| 349 { | |
| 350 ASSERT(context); | |
| 351 ASSERT(m_debuggerAgent->trackingAsyncCalls()); | |
| 352 if (ExecutionContextData* data = m_executionContextDataMap.get(context)) | |
| 353 data->m_performanceObserverCallChains.remove(observer); | |
| 354 } | |
| 355 | |
| 356 void AsyncCallTracker::willDeliverPerformanceObservations(ExecutionContext* cont ext, PerformanceObserver* observer) | |
| 357 { | |
| 358 ASSERT(context); | |
| 359 ASSERT(m_debuggerAgent->trackingAsyncCalls()); | |
| 360 if (ExecutionContextData* data = m_executionContextDataMap.get(context)) { | |
| 361 willFireAsyncCall(data->m_performanceObserverCallChains.get(observer)); | |
| 362 data->m_performanceObserverCallChains.remove(observer); | |
| 363 } else { | |
| 364 willFireAsyncCall(InspectorDebuggerAgent::unknownAsyncOperationId); | |
| 365 } | |
| 366 } | |
| 367 | |
| 331 void AsyncCallTracker::didPostExecutionContextTask(ExecutionContext* context, Ex ecutionContextTask* task) | 368 void AsyncCallTracker::didPostExecutionContextTask(ExecutionContext* context, Ex ecutionContextTask* task) | 
| 332 { | 369 { | 
| 333 ASSERT(context); | 370 ASSERT(context); | 
| 334 ASSERT(m_debuggerAgent->trackingAsyncCalls()); | 371 ASSERT(m_debuggerAgent->trackingAsyncCalls()); | 
| 335 if (task->taskNameForInstrumentation().isEmpty()) | 372 if (task->taskNameForInstrumentation().isEmpty()) | 
| 336 return; | 373 return; | 
| 337 int operationId = m_debuggerAgent->traceAsyncOperationStarting(task->taskNam eForInstrumentation()); | 374 int operationId = m_debuggerAgent->traceAsyncOperationStarting(task->taskNam eForInstrumentation()); | 
| 338 ExecutionContextData* data = createContextDataIfNeeded(context); | 375 ExecutionContextData* data = createContextDataIfNeeded(context); | 
| 339 data->m_executionContextTaskCallChains.set(task, operationId); | 376 data->m_executionContextTaskCallChains.set(task, operationId); | 
| 340 } | 377 } | 
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 428 { | 465 { | 
| 429 #if ENABLE(OILPAN) | 466 #if ENABLE(OILPAN) | 
| 430 visitor->trace(m_executionContextDataMap); | 467 visitor->trace(m_executionContextDataMap); | 
| 431 visitor->trace(m_debuggerAgent); | 468 visitor->trace(m_debuggerAgent); | 
| 432 visitor->trace(m_instrumentingAgents); | 469 visitor->trace(m_instrumentingAgents); | 
| 433 #endif | 470 #endif | 
| 434 InspectorDebuggerAgent::AsyncCallTrackingListener::trace(visitor); | 471 InspectorDebuggerAgent::AsyncCallTrackingListener::trace(visitor); | 
| 435 } | 472 } | 
| 436 | 473 | 
| 437 } // namespace blink | 474 } // namespace blink | 
| OLD | NEW |