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

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

Issue 397843009: Revert of DevTools: Support async call stacks for FileSystem API (part 1). (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 22 matching lines...) Expand all
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/dom/ExecutionContextTask.h" 38 #include "core/dom/ExecutionContextTask.h"
39 #include "core/events/Event.h" 39 #include "core/events/Event.h"
40 #include "core/events/EventTarget.h" 40 #include "core/events/EventTarget.h"
41 #include "core/xml/XMLHttpRequest.h" 41 #include "core/xml/XMLHttpRequest.h"
42 #include "core/xml/XMLHttpRequestUpload.h" 42 #include "core/xml/XMLHttpRequestUpload.h"
43 #include "platform/AsyncFileSystemCallbacks.h"
44 #include "wtf/text/StringBuilder.h" 43 #include "wtf/text/StringBuilder.h"
45 #include "wtf/text/StringHash.h" 44 #include "wtf/text/StringHash.h"
46 #include <v8.h> 45 #include <v8.h>
47 46
48 namespace { 47 namespace {
49 48
50 static const char setTimeoutName[] = "setTimeout"; 49 static const char setTimeoutName[] = "setTimeout";
51 static const char setIntervalName[] = "setInterval"; 50 static const char setIntervalName[] = "setInterval";
52 static const char requestAnimationFrameName[] = "requestAnimationFrame"; 51 static const char requestAnimationFrameName[] = "requestAnimationFrame";
53 static const char xhrSendName[] = "XMLHttpRequest.send"; 52 static const char xhrSendName[] = "XMLHttpRequest.send";
54 static const char enqueueMutationRecordName[] = "Mutation"; 53 static const char enqueueMutationRecordName[] = "Mutation";
55 static const char fileSystemName[] = "FileSystem";
56 54
57 } 55 }
58 56
59 namespace WebCore { 57 namespace WebCore {
60 58
61 class AsyncCallStackTracker::ExecutionContextData FINAL : public ContextLifecycl eObserver { 59 class AsyncCallStackTracker::ExecutionContextData FINAL : public ContextLifecycl eObserver {
62 WTF_MAKE_FAST_ALLOCATED; 60 WTF_MAKE_FAST_ALLOCATED;
63 public: 61 public:
64 ExecutionContextData(AsyncCallStackTracker* tracker, ExecutionContext* execu tionContext) 62 ExecutionContextData(AsyncCallStackTracker* tracker, ExecutionContext* execu tionContext)
65 : ContextLifecycleObserver(executionContext) 63 : ContextLifecycleObserver(executionContext)
(...skipping 12 matching lines...) Expand all
78 76
79 public: 77 public:
80 AsyncCallStackTracker* m_tracker; 78 AsyncCallStackTracker* m_tracker;
81 HashSet<int> m_intervalTimerIds; 79 HashSet<int> m_intervalTimerIds;
82 HashMap<int, RefPtr<AsyncCallChain> > m_timerCallChains; 80 HashMap<int, RefPtr<AsyncCallChain> > m_timerCallChains;
83 HashMap<int, RefPtr<AsyncCallChain> > m_animationFrameCallChains; 81 HashMap<int, RefPtr<AsyncCallChain> > m_animationFrameCallChains;
84 HashMap<Event*, RefPtr<AsyncCallChain> > m_eventCallChains; 82 HashMap<Event*, RefPtr<AsyncCallChain> > m_eventCallChains;
85 HashMap<EventTarget*, RefPtr<AsyncCallChain> > m_xhrCallChains; 83 HashMap<EventTarget*, RefPtr<AsyncCallChain> > m_xhrCallChains;
86 HashMap<MutationObserver*, RefPtr<AsyncCallChain> > m_mutationObserverCallCh ains; 84 HashMap<MutationObserver*, RefPtr<AsyncCallChain> > m_mutationObserverCallCh ains;
87 HashMap<ExecutionContextTask*, RefPtr<AsyncCallChain> > m_executionContextTa skCallChains; 85 HashMap<ExecutionContextTask*, RefPtr<AsyncCallChain> > m_executionContextTa skCallChains;
88 HashMap<AsyncFileSystemCallbacks*, RefPtr<AsyncCallChain> > m_fileSystemCall Chains;
89 HashMap<String, RefPtr<AsyncCallChain> > m_v8AsyncTaskCallChains; 86 HashMap<String, RefPtr<AsyncCallChain> > m_v8AsyncTaskCallChains;
90 }; 87 };
91 88
92 static XMLHttpRequest* toXmlHttpRequest(EventTarget* eventTarget) 89 static XMLHttpRequest* toXmlHttpRequest(EventTarget* eventTarget)
93 { 90 {
94 const AtomicString& interfaceName = eventTarget->interfaceName(); 91 const AtomicString& interfaceName = eventTarget->interfaceName();
95 if (interfaceName == EventTargetNames::XMLHttpRequest) 92 if (interfaceName == EventTargetNames::XMLHttpRequest)
96 return static_cast<XMLHttpRequest*>(eventTarget); 93 return static_cast<XMLHttpRequest*>(eventTarget);
97 if (interfaceName == EventTargetNames::XMLHttpRequestUpload) 94 if (interfaceName == EventTargetNames::XMLHttpRequestUpload)
98 return static_cast<XMLHttpRequestUpload*>(eventTarget)->xmlHttpRequest() ; 95 return static_cast<XMLHttpRequestUpload*>(eventTarget)->xmlHttpRequest() ;
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 void AsyncCallStackTracker::willPerformExecutionContextTask(ExecutionContext* co ntext, ExecutionContextTask* task) 320 void AsyncCallStackTracker::willPerformExecutionContextTask(ExecutionContext* co ntext, ExecutionContextTask* task)
324 { 321 {
325 ASSERT(context); 322 ASSERT(context);
326 ASSERT(isEnabled()); 323 ASSERT(isEnabled());
327 if (ExecutionContextData* data = m_executionContextDataMap.get(context)) 324 if (ExecutionContextData* data = m_executionContextDataMap.get(context))
328 setCurrentAsyncCallChain(context, data->m_executionContextTaskCallChains .take(task)); 325 setCurrentAsyncCallChain(context, data->m_executionContextTaskCallChains .take(task));
329 else 326 else
330 setCurrentAsyncCallChain(context, nullptr); 327 setCurrentAsyncCallChain(context, nullptr);
331 } 328 }
332 329
333 void AsyncCallStackTracker::didEnqueueAsyncFileSystemCallback(ExecutionContext* context, AsyncFileSystemCallbacks* callback, const ScriptValue& callFrames)
334 {
335 ASSERT(context);
336 ASSERT(isEnabled());
337 if (!validateCallFrames(callFrames))
338 return;
339 ExecutionContextData* data = createContextDataIfNeeded(context);
340 data->m_fileSystemCallChains.set(callback, createAsyncCallChain(fileSystemNa me, callFrames));
341 }
342
343 void AsyncCallStackTracker::didRemoveAsyncFileSystemCallback(ExecutionContext* c ontext, AsyncFileSystemCallbacks* callback)
344 {
345 ASSERT(context);
346 ASSERT(isEnabled());
347 if (ExecutionContextData* data = m_executionContextDataMap.get(context))
348 data->m_fileSystemCallChains.remove(callback);
349 }
350
351 void AsyncCallStackTracker::willHandleAsyncFileSystemCallback(ExecutionContext* context, AsyncFileSystemCallbacks* callback, bool hasMore)
352 {
353 ASSERT(context);
354 ASSERT(isEnabled());
355 if (ExecutionContextData* data = m_executionContextDataMap.get(context)) {
356 if (hasMore)
357 setCurrentAsyncCallChain(context, data->m_fileSystemCallChains.get(c allback));
358 else
359 setCurrentAsyncCallChain(context, data->m_fileSystemCallChains.take( callback));
360 } else {
361 setCurrentAsyncCallChain(context, nullptr);
362 }
363 }
364
365 static String makeV8AsyncTaskUniqueId(const String& eventName, int id) 330 static String makeV8AsyncTaskUniqueId(const String& eventName, int id)
366 { 331 {
367 StringBuilder builder; 332 StringBuilder builder;
368 builder.append(eventName); 333 builder.append(eventName);
369 builder.appendNumber(id); 334 builder.appendNumber(id);
370 return builder.toString(); 335 return builder.toString();
371 } 336 }
372 337
373 void AsyncCallStackTracker::didEnqueueV8AsyncTask(ExecutionContext* context, con st String& eventName, int id, const ScriptValue& callFrames) 338 void AsyncCallStackTracker::didEnqueueV8AsyncTask(ExecutionContext* context, con st String& eventName, int id, const ScriptValue& callFrames)
374 { 339 {
(...skipping 13 matching lines...) Expand all
388 setCurrentAsyncCallChain(context, data->m_v8AsyncTaskCallChains.take(mak eV8AsyncTaskUniqueId(eventName, id))); 353 setCurrentAsyncCallChain(context, data->m_v8AsyncTaskCallChains.take(mak eV8AsyncTaskUniqueId(eventName, id)));
389 else 354 else
390 setCurrentAsyncCallChain(context, nullptr); 355 setCurrentAsyncCallChain(context, nullptr);
391 } 356 }
392 357
393 void AsyncCallStackTracker::didFireAsyncCall() 358 void AsyncCallStackTracker::didFireAsyncCall()
394 { 359 {
395 clearCurrentAsyncCallChain(); 360 clearCurrentAsyncCallChain();
396 } 361 }
397 362
398 void AsyncCallStackTracker::willRescheduleAsyncCallChain()
399 {
400 ASSERT(isEnabled());
401 if (!m_rescheduledAsyncCallChain)
402 m_rescheduleNextAsyncCallChain = true;
403 }
404
405 void AsyncCallStackTracker::didRescheduleAsyncCallChain()
406 {
407 ASSERT(isEnabled());
408 m_rescheduleNextAsyncCallChain = false;
409 m_rescheduledAsyncCallChain.clear();
410 }
411
412 PassRefPtr<AsyncCallStackTracker::AsyncCallChain> AsyncCallStackTracker::createA syncCallChain(const String& description, const ScriptValue& callFrames) 363 PassRefPtr<AsyncCallStackTracker::AsyncCallChain> AsyncCallStackTracker::createA syncCallChain(const String& description, const ScriptValue& callFrames)
413 { 364 {
414 // Check if we should propogate the async call stack chain.
415 if (m_rescheduledAsyncCallChain)
416 return m_rescheduledAsyncCallChain;
417 if (callFrames.isEmpty()) { 365 if (callFrames.isEmpty()) {
418 ASSERT(m_currentAsyncCallChain); 366 ASSERT(m_currentAsyncCallChain);
419 return m_currentAsyncCallChain; 367 return m_currentAsyncCallChain; // Propogate async call stack chain.
420 } 368 }
421 RefPtr<AsyncCallChain> chain = adoptRef(m_currentAsyncCallChain ? new AsyncC allStackTracker::AsyncCallChain(*m_currentAsyncCallChain) : new AsyncCallStackTr acker::AsyncCallChain()); 369 RefPtr<AsyncCallChain> chain = adoptRef(m_currentAsyncCallChain ? new AsyncC allStackTracker::AsyncCallChain(*m_currentAsyncCallChain) : new AsyncCallStackTr acker::AsyncCallChain());
422 ensureMaxAsyncCallChainDepth(chain.get(), m_maxAsyncCallStackDepth - 1); 370 ensureMaxAsyncCallChainDepth(chain.get(), m_maxAsyncCallStackDepth - 1);
423 chain->m_callStacks.prepend(adoptRef(new AsyncCallStackTracker::AsyncCallSta ck(description, callFrames))); 371 chain->m_callStacks.prepend(adoptRef(new AsyncCallStackTracker::AsyncCallSta ck(description, callFrames)));
424 return chain.release(); 372 return chain.release();
425 } 373 }
426 374
427 void AsyncCallStackTracker::setCurrentAsyncCallChain(ExecutionContext* context, PassRefPtr<AsyncCallChain> chain) 375 void AsyncCallStackTracker::setCurrentAsyncCallChain(ExecutionContext* context, PassRefPtr<AsyncCallChain> chain)
428 { 376 {
429 if (m_rescheduleNextAsyncCallChain) {
430 m_rescheduleNextAsyncCallChain = false;
431 m_rescheduledAsyncCallChain = chain.get();
432 }
433 if (V8RecursionScope::recursionLevel(toIsolate(context))) { 377 if (V8RecursionScope::recursionLevel(toIsolate(context))) {
434 if (m_currentAsyncCallChain) 378 if (m_currentAsyncCallChain)
435 ++m_nestedAsyncCallCount; 379 ++m_nestedAsyncCallCount;
436 } else { 380 } else {
437 // Current AsyncCallChain corresponds to the bottommost JS call frame. 381 // Current AsyncCallChain corresponds to the bottommost JS call frame.
438 m_currentAsyncCallChain = chain; 382 m_currentAsyncCallChain = chain;
439 m_nestedAsyncCallCount = m_currentAsyncCallChain ? 1 : 0; 383 m_nestedAsyncCallCount = m_currentAsyncCallChain ? 1 : 0;
440 } 384 }
441 } 385 }
442 386
443 void AsyncCallStackTracker::clearCurrentAsyncCallChain() 387 void AsyncCallStackTracker::clearCurrentAsyncCallChain()
444 { 388 {
445 if (!m_nestedAsyncCallCount) 389 if (!m_nestedAsyncCallCount)
446 return; 390 return;
447 --m_nestedAsyncCallCount; 391 --m_nestedAsyncCallCount;
448 if (!m_nestedAsyncCallCount) 392 if (!m_nestedAsyncCallCount)
449 m_currentAsyncCallChain.clear(); 393 m_currentAsyncCallChain.clear();
450 } 394 }
451 395
452 void AsyncCallStackTracker::ensureMaxAsyncCallChainDepth(AsyncCallChain* chain, unsigned maxDepth) 396 void AsyncCallStackTracker::ensureMaxAsyncCallChainDepth(AsyncCallChain* chain, unsigned maxDepth)
453 { 397 {
454 while (chain->m_callStacks.size() > maxDepth) 398 while (chain->m_callStacks.size() > maxDepth)
455 chain->m_callStacks.removeLast(); 399 chain->m_callStacks.removeLast();
456 } 400 }
457 401
458 bool AsyncCallStackTracker::validateCallFrames(const ScriptValue& callFrames) 402 bool AsyncCallStackTracker::validateCallFrames(const ScriptValue& callFrames)
459 { 403 {
460 return !callFrames.isEmpty() || m_currentAsyncCallChain || m_rescheduledAsyn cCallChain; 404 return !callFrames.isEmpty() || m_currentAsyncCallChain;
461 } 405 }
462 406
463 AsyncCallStackTracker::ExecutionContextData* AsyncCallStackTracker::createContex tDataIfNeeded(ExecutionContext* context) 407 AsyncCallStackTracker::ExecutionContextData* AsyncCallStackTracker::createContex tDataIfNeeded(ExecutionContext* context)
464 { 408 {
465 ExecutionContextData* data = m_executionContextDataMap.get(context); 409 ExecutionContextData* data = m_executionContextDataMap.get(context);
466 if (!data) { 410 if (!data) {
467 data = new AsyncCallStackTracker::ExecutionContextData(this, context); 411 data = new AsyncCallStackTracker::ExecutionContextData(this, context);
468 m_executionContextDataMap.set(context, data); 412 m_executionContextDataMap.set(context, data);
469 } 413 }
470 return data; 414 return data;
471 } 415 }
472 416
473 void AsyncCallStackTracker::clear() 417 void AsyncCallStackTracker::clear()
474 { 418 {
475 m_currentAsyncCallChain.clear(); 419 m_currentAsyncCallChain.clear();
476 m_nestedAsyncCallCount = 0; 420 m_nestedAsyncCallCount = 0;
477 m_rescheduleNextAsyncCallChain = false;
478 m_rescheduledAsyncCallChain.clear();
479 ExecutionContextDataMap copy; 421 ExecutionContextDataMap copy;
480 m_executionContextDataMap.swap(copy); 422 m_executionContextDataMap.swap(copy);
481 for (ExecutionContextDataMap::const_iterator it = copy.begin(); it != copy.e nd(); ++it) 423 for (ExecutionContextDataMap::const_iterator it = copy.begin(); it != copy.e nd(); ++it)
482 delete it->value; 424 delete it->value;
483 } 425 }
484 426
485 } // namespace WebCore 427 } // namespace WebCore
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