Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(187)

Side by Side Diff: Source/core/inspector/AsyncCallStackTracker.cpp

Issue 404953003: DevTools: Async call stacks for window.postMessage() (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: rebased Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 54
55 } 55 }
56 56
57 namespace blink { 57 namespace blink {
58 58
59 class AsyncCallStackTracker::ExecutionContextData FINAL : public ContextLifecycl eObserver { 59 class AsyncCallStackTracker::ExecutionContextData FINAL : public ContextLifecycl eObserver {
60 WTF_MAKE_FAST_ALLOCATED; 60 WTF_MAKE_FAST_ALLOCATED;
61 public: 61 public:
62 ExecutionContextData(AsyncCallStackTracker* tracker, ExecutionContext* execu tionContext) 62 ExecutionContextData(AsyncCallStackTracker* tracker, ExecutionContext* execu tionContext)
63 : ContextLifecycleObserver(executionContext) 63 : ContextLifecycleObserver(executionContext)
64 , m_circularSequentialID(0)
64 , m_tracker(tracker) 65 , m_tracker(tracker)
65 { 66 {
66 } 67 }
67 68
68 virtual void contextDestroyed() OVERRIDE 69 virtual void contextDestroyed() OVERRIDE
69 { 70 {
70 ASSERT(executionContext()); 71 ASSERT(executionContext());
71 ExecutionContextData* self = m_tracker->m_executionContextDataMap.take(e xecutionContext()); 72 ExecutionContextData* self = m_tracker->m_executionContextDataMap.take(e xecutionContext());
72 ASSERT(self == this); 73 ASSERT(self == this);
73 ContextLifecycleObserver::contextDestroyed(); 74 ContextLifecycleObserver::contextDestroyed();
74 delete self; 75 delete self;
75 } 76 }
76 77
78 int circularSequentialID()
79 {
80 ++m_circularSequentialID;
81 if (m_circularSequentialID <= 0)
82 m_circularSequentialID = 1;
83 return m_circularSequentialID;
84 }
85
86 private:
87 int m_circularSequentialID;
88
77 public: 89 public:
78 AsyncCallStackTracker* m_tracker; 90 AsyncCallStackTracker* m_tracker;
79 HashSet<int> m_intervalTimerIds; 91 HashSet<int> m_intervalTimerIds;
80 HashMap<int, RefPtr<AsyncCallChain> > m_timerCallChains; 92 HashMap<int, RefPtr<AsyncCallChain> > m_timerCallChains;
81 HashMap<int, RefPtr<AsyncCallChain> > m_animationFrameCallChains; 93 HashMap<int, RefPtr<AsyncCallChain> > m_animationFrameCallChains;
82 HashMap<Event*, RefPtr<AsyncCallChain> > m_eventCallChains; 94 HashMap<Event*, RefPtr<AsyncCallChain> > m_eventCallChains;
83 HashMap<EventTarget*, RefPtr<AsyncCallChain> > m_xhrCallChains; 95 HashMap<EventTarget*, RefPtr<AsyncCallChain> > m_xhrCallChains;
84 HashMap<MutationObserver*, RefPtr<AsyncCallChain> > m_mutationObserverCallCh ains; 96 HashMap<MutationObserver*, RefPtr<AsyncCallChain> > m_mutationObserverCallCh ains;
85 HashMap<ExecutionContextTask*, RefPtr<AsyncCallChain> > m_executionContextTa skCallChains; 97 HashMap<ExecutionContextTask*, RefPtr<AsyncCallChain> > m_executionContextTa skCallChains;
86 HashMap<String, RefPtr<AsyncCallChain> > m_v8AsyncTaskCallChains; 98 HashMap<String, RefPtr<AsyncCallChain> > m_v8AsyncTaskCallChains;
99 HashMap<int, RefPtr<AsyncCallChain> > m_asyncOperationCallChains;
87 }; 100 };
88 101
89 static XMLHttpRequest* toXmlHttpRequest(EventTarget* eventTarget) 102 static XMLHttpRequest* toXmlHttpRequest(EventTarget* eventTarget)
90 { 103 {
91 const AtomicString& interfaceName = eventTarget->interfaceName(); 104 const AtomicString& interfaceName = eventTarget->interfaceName();
92 if (interfaceName == EventTargetNames::XMLHttpRequest) 105 if (interfaceName == EventTargetNames::XMLHttpRequest)
93 return static_cast<XMLHttpRequest*>(eventTarget); 106 return static_cast<XMLHttpRequest*>(eventTarget);
94 if (interfaceName == EventTargetNames::XMLHttpRequestUpload) 107 if (interfaceName == EventTargetNames::XMLHttpRequestUpload)
95 return static_cast<XMLHttpRequestUpload*>(eventTarget)->xmlHttpRequest() ; 108 return static_cast<XMLHttpRequestUpload*>(eventTarget)->xmlHttpRequest() ;
96 return 0; 109 return 0;
97 } 110 }
98 111
99 AsyncCallStackTracker::AsyncCallStack::AsyncCallStack(const String& description, const ScriptValue& callFrames) 112 AsyncCallStackTracker::AsyncCallStack::AsyncCallStack(const String& description, const ScriptValue& callFrames)
100 : m_description(description) 113 : m_description(description)
101 , m_callFrames(callFrames) 114 , m_callFrames(callFrames)
102 { 115 {
103 } 116 }
104 117
105 AsyncCallStackTracker::AsyncCallStack::~AsyncCallStack() 118 AsyncCallStackTracker::AsyncCallStack::~AsyncCallStack()
106 { 119 {
107 } 120 }
108 121
109 AsyncCallStackTracker::AsyncCallStackTracker() 122 AsyncCallStackTracker::AsyncCallStackTracker()
110 : m_maxAsyncCallStackDepth(0) 123 : m_maxAsyncCallStackDepth(0)
124 , m_nestedAsyncCallCount(0)
111 { 125 {
112 } 126 }
113 127
114 void AsyncCallStackTracker::setAsyncCallStackDepth(int depth) 128 void AsyncCallStackTracker::setAsyncCallStackDepth(int depth)
115 { 129 {
116 if (depth <= 0) { 130 if (depth <= 0) {
117 m_maxAsyncCallStackDepth = 0; 131 m_maxAsyncCallStackDepth = 0;
118 clear(); 132 clear();
119 } else { 133 } else {
120 m_maxAsyncCallStackDepth = depth; 134 m_maxAsyncCallStackDepth = depth;
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 void AsyncCallStackTracker::willHandleV8AsyncTask(ExecutionContext* context, con st String& eventName, int id) 365 void AsyncCallStackTracker::willHandleV8AsyncTask(ExecutionContext* context, con st String& eventName, int id)
352 { 366 {
353 ASSERT(context); 367 ASSERT(context);
354 ASSERT(isEnabled()); 368 ASSERT(isEnabled());
355 if (ExecutionContextData* data = m_executionContextDataMap.get(context)) 369 if (ExecutionContextData* data = m_executionContextDataMap.get(context))
356 setCurrentAsyncCallChain(context, data->m_v8AsyncTaskCallChains.take(mak eV8AsyncTaskUniqueId(eventName, id))); 370 setCurrentAsyncCallChain(context, data->m_v8AsyncTaskCallChains.take(mak eV8AsyncTaskUniqueId(eventName, id)));
357 else 371 else
358 setCurrentAsyncCallChain(context, nullptr); 372 setCurrentAsyncCallChain(context, nullptr);
359 } 373 }
360 374
375 int AsyncCallStackTracker::traceAsyncOperationStarting(ExecutionContext* context , const String& operationName, const ScriptValue& callFrames)
376 {
377 ASSERT(context);
378 ASSERT(isEnabled());
379 if (!validateCallFrames(callFrames))
380 return 0;
381 ExecutionContextData* data = createContextDataIfNeeded(context);
382 int id = data->circularSequentialID();
383 while (data->m_asyncOperationCallChains.contains(id))
384 id = data->circularSequentialID();
385 data->m_asyncOperationCallChains.set(id, createAsyncCallChain(operationName, callFrames));
386 return id;
387 }
388
389 void AsyncCallStackTracker::traceAsyncOperationCompleted(ExecutionContext* conte xt, int operationId)
390 {
391 ASSERT(context);
392 ASSERT(isEnabled());
393 if (operationId <= 0)
394 return;
395 if (ExecutionContextData* data = m_executionContextDataMap.get(context))
396 data->m_asyncOperationCallChains.remove(operationId);
397 }
398
399 void AsyncCallStackTracker::traceAsyncCallbackStarting(ExecutionContext* context , int operationId)
400 {
401 ASSERT(context);
402 ASSERT(isEnabled());
403 if (ExecutionContextData* data = m_executionContextDataMap.get(context))
404 setCurrentAsyncCallChain(context, operationId > 0 ? data->m_asyncOperati onCallChains.get(operationId) : nullptr);
405 else
406 setCurrentAsyncCallChain(context, nullptr);
407 }
408
361 void AsyncCallStackTracker::didFireAsyncCall() 409 void AsyncCallStackTracker::didFireAsyncCall()
362 { 410 {
363 clearCurrentAsyncCallChain(); 411 clearCurrentAsyncCallChain();
364 } 412 }
365 413
366 PassRefPtr<AsyncCallStackTracker::AsyncCallChain> AsyncCallStackTracker::createA syncCallChain(const String& description, const ScriptValue& callFrames) 414 PassRefPtr<AsyncCallStackTracker::AsyncCallChain> AsyncCallStackTracker::createA syncCallChain(const String& description, const ScriptValue& callFrames)
367 { 415 {
368 if (callFrames.isEmpty()) { 416 if (callFrames.isEmpty()) {
369 ASSERT(m_currentAsyncCallChain); 417 ASSERT(m_currentAsyncCallChain);
370 return m_currentAsyncCallChain; // Propogate async call stack chain. 418 return m_currentAsyncCallChain; // Propogate async call stack chain.
371 } 419 }
372 RefPtr<AsyncCallChain> chain = adoptRef(m_currentAsyncCallChain ? new AsyncC allStackTracker::AsyncCallChain(*m_currentAsyncCallChain) : new AsyncCallStackTr acker::AsyncCallChain()); 420 RefPtr<AsyncCallChain> chain = adoptRef(m_currentAsyncCallChain ? new AsyncC allStackTracker::AsyncCallChain(*m_currentAsyncCallChain) : new AsyncCallStackTr acker::AsyncCallChain());
373 ensureMaxAsyncCallChainDepth(chain.get(), m_maxAsyncCallStackDepth - 1); 421 ensureMaxAsyncCallChainDepth(chain.get(), m_maxAsyncCallStackDepth - 1);
374 chain->m_callStacks.prepend(adoptRef(new AsyncCallStackTracker::AsyncCallSta ck(description, callFrames))); 422 chain->m_callStacks.prepend(adoptRef(new AsyncCallStackTracker::AsyncCallSta ck(description, callFrames)));
375 return chain.release(); 423 return chain.release();
376 } 424 }
377 425
378 void AsyncCallStackTracker::setCurrentAsyncCallChain(ExecutionContext* context, PassRefPtr<AsyncCallChain> chain) 426 void AsyncCallStackTracker::setCurrentAsyncCallChain(ExecutionContext* context, PassRefPtr<AsyncCallChain> chain)
379 { 427 {
380 if (V8RecursionScope::recursionLevel(toIsolate(context))) { 428 if (chain && !V8RecursionScope::recursionLevel(toIsolate(context))) {
429 // Current AsyncCallChain corresponds to the bottommost JS call frame.
430 m_currentAsyncCallChain = chain;
431 m_nestedAsyncCallCount = 1;
432 } else {
381 if (m_currentAsyncCallChain) 433 if (m_currentAsyncCallChain)
382 ++m_nestedAsyncCallCount; 434 ++m_nestedAsyncCallCount;
383 } else {
384 // Current AsyncCallChain corresponds to the bottommost JS call frame.
385 m_currentAsyncCallChain = chain;
386 m_nestedAsyncCallCount = m_currentAsyncCallChain ? 1 : 0;
387 } 435 }
388 } 436 }
389 437
390 void AsyncCallStackTracker::clearCurrentAsyncCallChain() 438 void AsyncCallStackTracker::clearCurrentAsyncCallChain()
391 { 439 {
392 if (!m_nestedAsyncCallCount) 440 if (!m_nestedAsyncCallCount)
393 return; 441 return;
394 --m_nestedAsyncCallCount; 442 --m_nestedAsyncCallCount;
395 if (!m_nestedAsyncCallCount) 443 if (!m_nestedAsyncCallCount)
396 m_currentAsyncCallChain.clear(); 444 m_currentAsyncCallChain.clear();
(...skipping 24 matching lines...) Expand all
421 { 469 {
422 m_currentAsyncCallChain.clear(); 470 m_currentAsyncCallChain.clear();
423 m_nestedAsyncCallCount = 0; 471 m_nestedAsyncCallCount = 0;
424 ExecutionContextDataMap copy; 472 ExecutionContextDataMap copy;
425 m_executionContextDataMap.swap(copy); 473 m_executionContextDataMap.swap(copy);
426 for (ExecutionContextDataMap::const_iterator it = copy.begin(); it != copy.e nd(); ++it) 474 for (ExecutionContextDataMap::const_iterator it = copy.begin(); it != copy.e nd(); ++it)
427 delete it->value; 475 delete it->value;
428 } 476 }
429 477
430 } // namespace blink 478 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/inspector/AsyncCallStackTracker.h ('k') | Source/core/inspector/CodeGeneratorInstrumentation.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698