Home | History | Annotate | Download | only in inspector
      1 /*
      2  * Copyright (C) 2013 Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions are
      6  * met:
      7  *
      8  *     * Redistributions of source code must retain the above copyright
      9  * notice, this list of conditions and the following disclaimer.
     10  *     * Redistributions in binary form must reproduce the above
     11  * copyright notice, this list of conditions and the following disclaimer
     12  * in the documentation and/or other materials provided with the
     13  * distribution.
     14  *     * Neither the name of Google Inc. nor the names of its
     15  * contributors may be used to endorse or promote products derived from
     16  * this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 #ifndef AsyncCallStackTracker_h
     32 #define AsyncCallStackTracker_h
     33 
     34 #include "bindings/core/v8/ScriptValue.h"
     35 #include "core/dom/ContextLifecycleObserver.h"
     36 #include "wtf/Deque.h"
     37 #include "wtf/HashMap.h"
     38 #include "wtf/HashSet.h"
     39 #include "wtf/Noncopyable.h"
     40 #include "wtf/PassRefPtr.h"
     41 #include "wtf/RefPtr.h"
     42 
     43 namespace blink {
     44 
     45 class Event;
     46 class EventListener;
     47 class EventTarget;
     48 class ExecutionContext;
     49 class ExecutionContextTask;
     50 class MutationObserver;
     51 class XMLHttpRequest;
     52 
     53 class AsyncCallStackTracker FINAL : public NoBaseWillBeGarbageCollectedFinalized<AsyncCallStackTracker> {
     54     WTF_MAKE_NONCOPYABLE(AsyncCallStackTracker);
     55 public:
     56     class AsyncCallStack FINAL : public RefCountedWillBeGarbageCollectedFinalized<AsyncCallStack> {
     57     public:
     58         AsyncCallStack(const String&, const ScriptValue&);
     59         ~AsyncCallStack();
     60         void trace(Visitor*) { }
     61         String description() const { return m_description; }
     62         ScriptValue callFrames() const { return m_callFrames; }
     63     private:
     64         String m_description;
     65         ScriptValue m_callFrames;
     66     };
     67 
     68     typedef WillBeHeapDeque<RefPtrWillBeMember<AsyncCallStack>, 4> AsyncCallStackVector;
     69 
     70     class AsyncCallChain FINAL : public RefCountedWillBeGarbageCollected<AsyncCallChain> {
     71     public:
     72         AsyncCallChain() { }
     73         AsyncCallChain(const AsyncCallChain& t) : m_callStacks(t.m_callStacks) { }
     74         AsyncCallStackVector callStacks() const { return m_callStacks; }
     75         void trace(Visitor*);
     76     private:
     77         friend class AsyncCallStackTracker;
     78         AsyncCallStackVector m_callStacks;
     79     };
     80 
     81     class ExecutionContextData FINAL : public NoBaseWillBeGarbageCollectedFinalized<ExecutionContextData>, public ContextLifecycleObserver {
     82         WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
     83     public:
     84         ExecutionContextData(AsyncCallStackTracker* tracker, ExecutionContext* executionContext)
     85             : ContextLifecycleObserver(executionContext)
     86             , m_circularSequentialID(0)
     87             , m_tracker(tracker)
     88         {
     89         }
     90 
     91         virtual void contextDestroyed() OVERRIDE;
     92 
     93         int circularSequentialID();
     94 
     95         void trace(Visitor*);
     96 
     97     private:
     98         int m_circularSequentialID;
     99 
    100     public:
    101         RawPtrWillBeMember<AsyncCallStackTracker> m_tracker;
    102         HashSet<int> m_intervalTimerIds;
    103         WillBeHeapHashMap<int, RefPtrWillBeMember<AsyncCallChain> > m_timerCallChains;
    104         WillBeHeapHashMap<int, RefPtrWillBeMember<AsyncCallChain> > m_animationFrameCallChains;
    105         WillBeHeapHashMap<RawPtrWillBeMember<Event>, RefPtrWillBeMember<AsyncCallChain> > m_eventCallChains;
    106         WillBeHeapHashMap<RawPtrWillBeMember<EventTarget>, RefPtrWillBeMember<AsyncCallChain> > m_xhrCallChains;
    107         WillBeHeapHashMap<RawPtrWillBeMember<MutationObserver>, RefPtrWillBeMember<AsyncCallChain> > m_mutationObserverCallChains;
    108         WillBeHeapHashMap<ExecutionContextTask*, RefPtrWillBeMember<AsyncCallChain> > m_executionContextTaskCallChains;
    109         WillBeHeapHashMap<String, RefPtrWillBeMember<AsyncCallChain> > m_v8AsyncTaskCallChains;
    110         WillBeHeapHashMap<int, RefPtrWillBeMember<AsyncCallChain> > m_asyncOperationCallChains;
    111     };
    112 
    113     AsyncCallStackTracker();
    114 
    115     bool isEnabled() const { return m_maxAsyncCallStackDepth; }
    116     void setAsyncCallStackDepth(int);
    117     const AsyncCallChain* currentAsyncCallChain() const;
    118 
    119     void didInstallTimer(ExecutionContext*, int timerId, bool singleShot, const ScriptValue& callFrames);
    120     void didRemoveTimer(ExecutionContext*, int timerId);
    121     void willFireTimer(ExecutionContext*, int timerId);
    122 
    123     void didRequestAnimationFrame(ExecutionContext*, int callbackId, const ScriptValue& callFrames);
    124     void didCancelAnimationFrame(ExecutionContext*, int callbackId);
    125     void willFireAnimationFrame(ExecutionContext*, int callbackId);
    126 
    127     void didEnqueueEvent(EventTarget*, Event*, const ScriptValue& callFrames);
    128     void didRemoveEvent(EventTarget*, Event*);
    129     void willHandleEvent(EventTarget*, Event*, EventListener*, bool useCapture);
    130 
    131     void willLoadXHR(XMLHttpRequest*, const ScriptValue& callFrames);
    132     void didLoadXHR(XMLHttpRequest*);
    133 
    134     void didEnqueueMutationRecord(ExecutionContext*, MutationObserver*, const ScriptValue& callFrames);
    135     bool hasEnqueuedMutationRecord(ExecutionContext*, MutationObserver*);
    136     void didClearAllMutationRecords(ExecutionContext*, MutationObserver*);
    137     void willDeliverMutationRecords(ExecutionContext*, MutationObserver*);
    138 
    139     void didPostExecutionContextTask(ExecutionContext*, ExecutionContextTask*, const ScriptValue& callFrames);
    140     void didKillAllExecutionContextTasks(ExecutionContext*);
    141     void willPerformExecutionContextTask(ExecutionContext*, ExecutionContextTask*);
    142 
    143     void didEnqueueV8AsyncTask(ExecutionContext*, const String& eventName, int id, const ScriptValue& callFrames);
    144     void willHandleV8AsyncTask(ExecutionContext*, const String& eventName, int id);
    145 
    146     int traceAsyncOperationStarting(ExecutionContext*, const String& operationName, const ScriptValue& callFrames);
    147     void traceAsyncOperationCompleted(ExecutionContext*, int operationId);
    148     void traceAsyncCallbackStarting(ExecutionContext*, int operationId);
    149 
    150     void didFireAsyncCall();
    151     void clear();
    152 
    153     void trace(Visitor*);
    154 
    155 private:
    156     void willHandleXHREvent(XMLHttpRequest*, Event*);
    157 
    158     PassRefPtrWillBeRawPtr<AsyncCallChain> createAsyncCallChain(const String& description, const ScriptValue& callFrames);
    159     void setCurrentAsyncCallChain(ExecutionContext*, PassRefPtrWillBeRawPtr<AsyncCallChain>);
    160     void clearCurrentAsyncCallChain();
    161     static void ensureMaxAsyncCallChainDepth(AsyncCallChain*, unsigned);
    162     bool validateCallFrames(const ScriptValue& callFrames);
    163 
    164     ExecutionContextData* createContextDataIfNeeded(ExecutionContext*);
    165 
    166     unsigned m_maxAsyncCallStackDepth;
    167     RefPtrWillBeMember<AsyncCallChain> m_currentAsyncCallChain;
    168     unsigned m_nestedAsyncCallCount;
    169     typedef WillBeHeapHashMap<RawPtrWillBeMember<ExecutionContext>, OwnPtrWillBeMember<ExecutionContextData> > ExecutionContextDataMap;
    170     ExecutionContextDataMap m_executionContextDataMap;
    171 };
    172 
    173 } // namespace blink
    174 
    175 #endif // !defined(AsyncCallStackTracker_h)
    176