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

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

Issue 374903002: DevTools: Async call stacks for Promises and Object.observe. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: 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 21 matching lines...) Expand all
32 #include "core/inspector/AsyncCallStackTracker.h" 32 #include "core/inspector/AsyncCallStackTracker.h"
33 33
34 #include "bindings/core/v8/V8Binding.h" 34 #include "bindings/core/v8/V8Binding.h"
35 #include "bindings/core/v8/V8RecursionScope.h" 35 #include "bindings/core/v8/V8RecursionScope.h"
36 #include "core/dom/ContextLifecycleObserver.h" 36 #include "core/dom/ContextLifecycleObserver.h"
37 #include "core/dom/ExecutionContext.h" 37 #include "core/dom/ExecutionContext.h"
38 #include "core/events/Event.h" 38 #include "core/events/Event.h"
39 #include "core/events/EventTarget.h" 39 #include "core/events/EventTarget.h"
40 #include "core/xml/XMLHttpRequest.h" 40 #include "core/xml/XMLHttpRequest.h"
41 #include "core/xml/XMLHttpRequestUpload.h" 41 #include "core/xml/XMLHttpRequestUpload.h"
42 #include "wtf/text/AtomicStringHash.h"
43 #include "wtf/text/StringBuilder.h" 42 #include "wtf/text/StringBuilder.h"
43 #include "wtf/text/StringHash.h"
44 #include <v8.h> 44 #include <v8.h>
45 45
46 namespace { 46 namespace {
47 47
48 static const char setTimeoutName[] = "setTimeout"; 48 static const char setTimeoutName[] = "setTimeout";
49 static const char setIntervalName[] = "setInterval"; 49 static const char setIntervalName[] = "setInterval";
50 static const char requestAnimationFrameName[] = "requestAnimationFrame"; 50 static const char requestAnimationFrameName[] = "requestAnimationFrame";
51 static const char xhrSendName[] = "XMLHttpRequest.send"; 51 static const char xhrSendName[] = "XMLHttpRequest.send";
52 static const char enqueueMutationRecordName[] = "Mutation"; 52 static const char enqueueMutationRecordName[] = "Mutation";
53 53
(...skipping 20 matching lines...) Expand all
74 } 74 }
75 75
76 public: 76 public:
77 AsyncCallStackTracker* m_tracker; 77 AsyncCallStackTracker* m_tracker;
78 HashSet<int> m_intervalTimerIds; 78 HashSet<int> m_intervalTimerIds;
79 HashMap<int, RefPtr<AsyncCallChain> > m_timerCallChains; 79 HashMap<int, RefPtr<AsyncCallChain> > m_timerCallChains;
80 HashMap<int, RefPtr<AsyncCallChain> > m_animationFrameCallChains; 80 HashMap<int, RefPtr<AsyncCallChain> > m_animationFrameCallChains;
81 HashMap<Event*, RefPtr<AsyncCallChain> > m_eventCallChains; 81 HashMap<Event*, RefPtr<AsyncCallChain> > m_eventCallChains;
82 HashMap<EventTarget*, RefPtr<AsyncCallChain> > m_xhrCallChains; 82 HashMap<EventTarget*, RefPtr<AsyncCallChain> > m_xhrCallChains;
83 HashMap<MutationObserver*, RefPtr<AsyncCallChain> > m_mutationObserverCallCh ains; 83 HashMap<MutationObserver*, RefPtr<AsyncCallChain> > m_mutationObserverCallCh ains;
84 HashMap<String, RefPtr<AsyncCallChain> > m_v8AsyncTaskCallChains;
84 }; 85 };
85 86
86 static XMLHttpRequest* toXmlHttpRequest(EventTarget* eventTarget) 87 static XMLHttpRequest* toXmlHttpRequest(EventTarget* eventTarget)
87 { 88 {
88 const AtomicString& interfaceName = eventTarget->interfaceName(); 89 const AtomicString& interfaceName = eventTarget->interfaceName();
89 if (interfaceName == EventTargetNames::XMLHttpRequest) 90 if (interfaceName == EventTargetNames::XMLHttpRequest)
90 return static_cast<XMLHttpRequest*>(eventTarget); 91 return static_cast<XMLHttpRequest*>(eventTarget);
91 if (interfaceName == EventTargetNames::XMLHttpRequestUpload) 92 if (interfaceName == EventTargetNames::XMLHttpRequestUpload)
92 return static_cast<XMLHttpRequestUpload*>(eventTarget)->xmlHttpRequest() ; 93 return static_cast<XMLHttpRequestUpload*>(eventTarget)->xmlHttpRequest() ;
93 return 0; 94 return 0;
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 void AsyncCallStackTracker::willDeliverMutationRecords(ExecutionContext* context , MutationObserver* observer) 290 void AsyncCallStackTracker::willDeliverMutationRecords(ExecutionContext* context , MutationObserver* observer)
290 { 291 {
291 ASSERT(context); 292 ASSERT(context);
292 ASSERT(isEnabled()); 293 ASSERT(isEnabled());
293 if (ExecutionContextData* data = m_executionContextDataMap.get(context)) 294 if (ExecutionContextData* data = m_executionContextDataMap.get(context))
294 setCurrentAsyncCallChain(context, data->m_mutationObserverCallChains.tak e(observer)); 295 setCurrentAsyncCallChain(context, data->m_mutationObserverCallChains.tak e(observer));
295 else 296 else
296 setCurrentAsyncCallChain(context, nullptr); 297 setCurrentAsyncCallChain(context, nullptr);
297 } 298 }
298 299
300 static String makeV8AsyncTaskUniqueId(const String& eventName, int id)
301 {
302 StringBuilder builder;
303 builder.append(eventName);
304 builder.appendNumber(id);
305 return builder.toString();
306 }
307
308 void AsyncCallStackTracker::didEnqueueV8AsyncTask(ExecutionContext* context, con st String& eventName, int id, const ScriptValue& callFrames)
309 {
310 ASSERT(context);
311 ASSERT(isEnabled());
312 if (!validateCallFrames(callFrames))
313 return;
314 ExecutionContextData* data = createContextDataIfNeeded(context);
315 data->m_v8AsyncTaskCallChains.set(makeV8AsyncTaskUniqueId(eventName, id), cr eateAsyncCallChain(eventName, callFrames));
316 }
317
318 void AsyncCallStackTracker::willHandleV8AsyncTask(ExecutionContext* context, con st String& eventName, int id)
319 {
320 ASSERT(context);
321 ASSERT(isEnabled());
322 if (ExecutionContextData* data = m_executionContextDataMap.get(context))
323 setCurrentAsyncCallChain(context, data->m_v8AsyncTaskCallChains.take(mak eV8AsyncTaskUniqueId(eventName, id)));
324 else
325 setCurrentAsyncCallChain(context, nullptr);
326 }
327
299 void AsyncCallStackTracker::didFireAsyncCall() 328 void AsyncCallStackTracker::didFireAsyncCall()
300 { 329 {
301 clearCurrentAsyncCallChain(); 330 clearCurrentAsyncCallChain();
302 } 331 }
303 332
304 PassRefPtr<AsyncCallStackTracker::AsyncCallChain> AsyncCallStackTracker::createA syncCallChain(const String& description, const ScriptValue& callFrames) 333 PassRefPtr<AsyncCallStackTracker::AsyncCallChain> AsyncCallStackTracker::createA syncCallChain(const String& description, const ScriptValue& callFrames)
305 { 334 {
335 if (callFrames.isEmpty()) {
336 ASSERT(m_currentAsyncCallChain);
337 return m_currentAsyncCallChain; // Propogate async call stack chain.
338 }
306 RefPtr<AsyncCallChain> chain = adoptRef(m_currentAsyncCallChain ? new AsyncC allStackTracker::AsyncCallChain(*m_currentAsyncCallChain) : new AsyncCallStackTr acker::AsyncCallChain()); 339 RefPtr<AsyncCallChain> chain = adoptRef(m_currentAsyncCallChain ? new AsyncC allStackTracker::AsyncCallChain(*m_currentAsyncCallChain) : new AsyncCallStackTr acker::AsyncCallChain());
307 ensureMaxAsyncCallChainDepth(chain.get(), m_maxAsyncCallStackDepth - 1); 340 ensureMaxAsyncCallChainDepth(chain.get(), m_maxAsyncCallStackDepth - 1);
308 chain->m_callStacks.prepend(adoptRef(new AsyncCallStackTracker::AsyncCallSta ck(description, callFrames))); 341 chain->m_callStacks.prepend(adoptRef(new AsyncCallStackTracker::AsyncCallSta ck(description, callFrames)));
309 return chain.release(); 342 return chain.release();
310 } 343 }
311 344
312 void AsyncCallStackTracker::setCurrentAsyncCallChain(ExecutionContext* context, PassRefPtr<AsyncCallChain> chain) 345 void AsyncCallStackTracker::setCurrentAsyncCallChain(ExecutionContext* context, PassRefPtr<AsyncCallChain> chain)
313 { 346 {
314 if (V8RecursionScope::recursionLevel(toIsolate(context))) { 347 if (V8RecursionScope::recursionLevel(toIsolate(context))) {
315 if (m_currentAsyncCallChain) 348 if (m_currentAsyncCallChain)
(...skipping 15 matching lines...) Expand all
331 } 364 }
332 365
333 void AsyncCallStackTracker::ensureMaxAsyncCallChainDepth(AsyncCallChain* chain, unsigned maxDepth) 366 void AsyncCallStackTracker::ensureMaxAsyncCallChainDepth(AsyncCallChain* chain, unsigned maxDepth)
334 { 367 {
335 while (chain->m_callStacks.size() > maxDepth) 368 while (chain->m_callStacks.size() > maxDepth)
336 chain->m_callStacks.removeLast(); 369 chain->m_callStacks.removeLast();
337 } 370 }
338 371
339 bool AsyncCallStackTracker::validateCallFrames(const ScriptValue& callFrames) 372 bool AsyncCallStackTracker::validateCallFrames(const ScriptValue& callFrames)
340 { 373 {
341 return !callFrames.isEmpty(); 374 return !callFrames.isEmpty() || m_currentAsyncCallChain;
342 } 375 }
343 376
344 AsyncCallStackTracker::ExecutionContextData* AsyncCallStackTracker::createContex tDataIfNeeded(ExecutionContext* context) 377 AsyncCallStackTracker::ExecutionContextData* AsyncCallStackTracker::createContex tDataIfNeeded(ExecutionContext* context)
345 { 378 {
346 ExecutionContextData* data = m_executionContextDataMap.get(context); 379 ExecutionContextData* data = m_executionContextDataMap.get(context);
347 if (!data) { 380 if (!data) {
348 data = new AsyncCallStackTracker::ExecutionContextData(this, context); 381 data = new AsyncCallStackTracker::ExecutionContextData(this, context);
349 m_executionContextDataMap.set(context, data); 382 m_executionContextDataMap.set(context, data);
350 } 383 }
351 return data; 384 return data;
352 } 385 }
353 386
354 void AsyncCallStackTracker::clear() 387 void AsyncCallStackTracker::clear()
355 { 388 {
356 m_currentAsyncCallChain.clear(); 389 m_currentAsyncCallChain.clear();
357 m_nestedAsyncCallCount = 0; 390 m_nestedAsyncCallCount = 0;
358 ExecutionContextDataMap copy; 391 ExecutionContextDataMap copy;
359 m_executionContextDataMap.swap(copy); 392 m_executionContextDataMap.swap(copy);
360 for (ExecutionContextDataMap::const_iterator it = copy.begin(); it != copy.e nd(); ++it) 393 for (ExecutionContextDataMap::const_iterator it = copy.begin(); it != copy.e nd(); ++it)
361 delete it->value; 394 delete it->value;
362 } 395 }
363 396
364 } // namespace WebCore 397 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698