Home | History | Annotate | Download | only in inspector
      1 /*
      2 * Copyright (C) 2012 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 InspectorTimelineAgent_h
     32 #define InspectorTimelineAgent_h
     33 
     34 
     35 #include "InspectorFrontend.h"
     36 #include "bindings/v8/ScriptGCEvent.h"
     37 #include "core/dom/EventContext.h"
     38 #include "core/inspector/InspectorBaseAgent.h"
     39 #include "core/inspector/ScriptGCEventListener.h"
     40 #include "core/platform/JSONValues.h"
     41 #include "core/platform/PlatformInstrumentation.h"
     42 #include "core/platform/graphics/LayoutRect.h"
     43 #include "wtf/PassOwnPtr.h"
     44 #include "wtf/Vector.h"
     45 #include "wtf/WeakPtr.h"
     46 
     47 namespace WebCore {
     48 struct FetchInitiatorInfo;
     49 class DOMWindow;
     50 class Document;
     51 class DocumentLoader;
     52 class Event;
     53 class FloatQuad;
     54 class Frame;
     55 class GraphicsContext;
     56 class InspectorClient;
     57 class InspectorDOMAgent;
     58 class InspectorFrontend;
     59 class InspectorMemoryAgent;
     60 class InspectorPageAgent;
     61 class InstrumentingAgents;
     62 class KURL;
     63 class Node;
     64 class Page;
     65 class RenderObject;
     66 class ResourceError;
     67 class ResourceLoader;
     68 class ResourceRequest;
     69 class ResourceResponse;
     70 class ScriptArguments;
     71 class ScriptCallStack;
     72 class ScriptExecutionContext;
     73 class TimelineTraceEventProcessor;
     74 class WebSocketHandshakeRequest;
     75 class WebSocketHandshakeResponse;
     76 class XMLHttpRequest;
     77 
     78 typedef String ErrorString;
     79 
     80 namespace TimelineRecordType {
     81 extern const char DecodeImage[];
     82 extern const char Rasterize[];
     83 extern const char PaintSetup[];
     84 };
     85 
     86 class TimelineTimeConverter {
     87 public:
     88     TimelineTimeConverter()
     89         : m_timestampsBaseMs(0)
     90         , m_startTimeMs(0)
     91     {
     92     }
     93     double toProtocolTimestamp(double seconds) const  { return seconds * 1000.0 - m_timestampsBaseMs; }
     94     double startTimeMs() const { return m_startTimeMs; }
     95     double timestampsBaseMs() const { return m_timestampsBaseMs; }
     96     void reset();
     97 
     98 private:
     99     double m_timestampsBaseMs;
    100     double m_startTimeMs;
    101 };
    102 
    103 class InspectorTimelineAgent
    104     : public InspectorBaseAgent<InspectorTimelineAgent>,
    105       public ScriptGCEventListener,
    106       public InspectorBackendDispatcher::TimelineCommandHandler,
    107       public PlatformInstrumentationClient {
    108     WTF_MAKE_NONCOPYABLE(InspectorTimelineAgent);
    109 public:
    110     enum InspectorType { PageInspector, WorkerInspector };
    111 
    112     static PassOwnPtr<InspectorTimelineAgent> create(InstrumentingAgents* instrumentingAgents, InspectorPageAgent* pageAgent, InspectorMemoryAgent* memoryAgent, InspectorDOMAgent* domAgent, InspectorCompositeState* state, InspectorType type, InspectorClient* client)
    113     {
    114         return adoptPtr(new InspectorTimelineAgent(instrumentingAgents, pageAgent, memoryAgent, domAgent, state, type, client));
    115     }
    116 
    117     ~InspectorTimelineAgent();
    118 
    119     virtual void setFrontend(InspectorFrontend*);
    120     virtual void clearFrontend();
    121     virtual void restore();
    122 
    123     virtual void start(ErrorString*, const int* maxCallStackDepth, const bool* includeDomCounters, const bool* includeNativeMemoryStatistics);
    124     virtual void stop(ErrorString*);
    125 
    126     void setLayerTreeId(int layerTreeId) { m_layerTreeId = layerTreeId; }
    127     int layerTreeId() const { return m_layerTreeId; }
    128     int id() const { return m_id; }
    129 
    130     void didCommitLoad();
    131 
    132     // Methods called from WebCore.
    133     bool willCallFunction(ScriptExecutionContext* context, const String& scriptName, int scriptLine);
    134     void didCallFunction();
    135 
    136     bool willDispatchEvent(Document* document, const Event& event, DOMWindow* window, Node* node, const EventPath& eventPath);
    137     bool willDispatchEventOnWindow(const Event& event, DOMWindow* window);
    138     void didDispatchEvent();
    139     void didDispatchEventOnWindow();
    140 
    141     void didBeginFrame();
    142     void didCancelFrame();
    143 
    144     void didInvalidateLayout(Frame*);
    145     bool willLayout(Frame*);
    146     void didLayout(RenderObject*);
    147 
    148     void didScheduleStyleRecalculation(Document*);
    149     bool willRecalculateStyle(Document*);
    150     void didRecalculateStyle();
    151     void didRecalculateStyleForElement();
    152 
    153     void willPaint(RenderObject*);
    154     void didPaint(RenderObject*, GraphicsContext*, const LayoutRect&);
    155 
    156     void willScrollLayer(RenderObject*);
    157     void didScrollLayer();
    158 
    159     void willComposite();
    160     void didComposite();
    161 
    162     bool willWriteHTML(Document*, unsigned startLine);
    163     void didWriteHTML(unsigned endLine);
    164 
    165     void didInstallTimer(ScriptExecutionContext* context, int timerId, int timeout, bool singleShot);
    166     void didRemoveTimer(ScriptExecutionContext* context, int timerId);
    167     bool willFireTimer(ScriptExecutionContext* context, int timerId);
    168     void didFireTimer();
    169 
    170     bool willDispatchXHRReadyStateChangeEvent(ScriptExecutionContext* context, XMLHttpRequest* request);
    171     void didDispatchXHRReadyStateChangeEvent();
    172     bool willDispatchXHRLoadEvent(ScriptExecutionContext* context, XMLHttpRequest* request);
    173     void didDispatchXHRLoadEvent();
    174 
    175     bool willEvaluateScript(Frame*, const String&, int);
    176     void didEvaluateScript();
    177 
    178     void consoleTimeStamp(Frame*, PassRefPtr<ScriptArguments>);
    179     void domContentLoadedEventFired(Frame*);
    180     void loadEventFired(Frame*);
    181 
    182     void startConsoleTiming(Frame*, const String&);
    183     void stopConsoleTiming(Frame*, const String&, PassRefPtr<ScriptCallStack>);
    184 
    185     void didScheduleResourceRequest(Document*, const String& url);
    186     void willSendRequest(unsigned long, DocumentLoader*, const ResourceRequest&, const ResourceResponse&, const FetchInitiatorInfo&);
    187     bool willReceiveResourceResponse(Frame*, unsigned long, const ResourceResponse&);
    188     void didReceiveResourceResponse(unsigned long, DocumentLoader*, const ResourceResponse&, ResourceLoader*);
    189     void didFinishLoading(unsigned long, DocumentLoader*, double monotonicFinishTime);
    190     void didFailLoading(unsigned long identifier, DocumentLoader* loader, const ResourceError& error);
    191     bool willReceiveResourceData(Frame*, unsigned long identifier, int length);
    192     void didReceiveResourceData();
    193 
    194     void didRequestAnimationFrame(Document*, int callbackId);
    195     void didCancelAnimationFrame(Document*, int callbackId);
    196     bool willFireAnimationFrame(Document*, int callbackId);
    197     void didFireAnimationFrame();
    198 
    199     void willProcessTask();
    200     void didProcessTask();
    201 
    202     void didCreateWebSocket(Document*, unsigned long identifier, const KURL&, const String& protocol);
    203     void willSendWebSocketHandshakeRequest(Document*, unsigned long identifier, const WebSocketHandshakeRequest&);
    204     void didReceiveWebSocketHandshakeResponse(Document*, unsigned long identifier, const WebSocketHandshakeResponse&);
    205     void didCloseWebSocket(Document*, unsigned long identifier);
    206 
    207     // ScriptGCEventListener methods.
    208     virtual void didGC(double, double, size_t);
    209 
    210     // PlatformInstrumentationClient methods.
    211     virtual void willDecodeImage(const String& imageType) OVERRIDE;
    212     virtual void didDecodeImage() OVERRIDE;
    213     virtual void willResizeImage(bool shouldCache) OVERRIDE;
    214     virtual void didResizeImage() OVERRIDE;
    215 
    216 private:
    217     friend class TimelineRecordStack;
    218     friend class TimelineTraceEventProcessor;
    219 
    220     struct TimelineRecordEntry {
    221         TimelineRecordEntry(PassRefPtr<JSONObject> record, PassRefPtr<JSONObject> data, PassRefPtr<JSONArray> children, const String& type, size_t usedHeapSizeAtStart)
    222             : record(record), data(data), children(children), type(type), usedHeapSizeAtStart(usedHeapSizeAtStart)
    223         {
    224         }
    225         RefPtr<JSONObject> record;
    226         RefPtr<JSONObject> data;
    227         RefPtr<JSONArray> children;
    228         String type;
    229         size_t usedHeapSizeAtStart;
    230     };
    231 
    232     InspectorTimelineAgent(InstrumentingAgents*, InspectorPageAgent*, InspectorMemoryAgent*, InspectorDOMAgent*, InspectorCompositeState*, InspectorType, InspectorClient*);
    233 
    234     void didFinishLoadingResource(unsigned long, bool didFail, double finishTime, Frame*);
    235 
    236     void sendEvent(PassRefPtr<JSONObject>);
    237     void appendRecord(PassRefPtr<JSONObject> data, const String& type, bool captureCallStack, Frame*);
    238     void pushCurrentRecord(PassRefPtr<JSONObject>, const String& type, bool captureCallStack, Frame*, bool hasLowLevelDetails = false);
    239 
    240     void setDOMCounters(TypeBuilder::Timeline::TimelineEvent* record);
    241     void setNativeHeapStatistics(TypeBuilder::Timeline::TimelineEvent* record);
    242     void setFrameIdentifier(JSONObject* record, Frame*);
    243     void pushGCEventRecords();
    244 
    245     void didCompleteCurrentRecord(const String& type);
    246 
    247     void setHeapSizeStatistics(JSONObject* record);
    248     void commitFrameRecord();
    249 
    250     void addRecordToTimeline(PassRefPtr<JSONObject>);
    251     void innerAddRecordToTimeline(PassRefPtr<JSONObject>);
    252     void clearRecordStack();
    253 
    254     void localToPageQuad(const RenderObject& renderer, const LayoutRect&, FloatQuad*);
    255     const TimelineTimeConverter& timeConverter() const { return m_timeConverter; }
    256     long long idForNode(Node*);
    257     void releaseNodeIds();
    258 
    259     double timestamp() const;
    260     Page* page();
    261 
    262     InspectorPageAgent* m_pageAgent;
    263     InspectorMemoryAgent* m_memoryAgent;
    264     InspectorDOMAgent* m_domAgent;
    265     TimelineTimeConverter m_timeConverter;
    266 
    267     InspectorFrontend::Timeline* m_frontend;
    268     double m_timestampOffset;
    269 
    270     Vector<TimelineRecordEntry> m_recordStack;
    271 
    272     int m_id;
    273     struct GCEvent {
    274         GCEvent(double startTime, double endTime, size_t collectedBytes)
    275             : startTime(startTime), endTime(endTime), collectedBytes(collectedBytes)
    276         {
    277         }
    278         double startTime;
    279         double endTime;
    280         size_t collectedBytes;
    281     };
    282     typedef Vector<GCEvent> GCEvents;
    283     GCEvents m_gcEvents;
    284     int m_maxCallStackDepth;
    285     unsigned m_platformInstrumentationClientInstalledAtStackDepth;
    286     RefPtr<JSONObject> m_pendingFrameRecord;
    287     InspectorType m_inspectorType;
    288     InspectorClient* m_client;
    289     WeakPtrFactory<InspectorTimelineAgent> m_weakFactory;
    290     RefPtr<TimelineTraceEventProcessor> m_traceEventProcessor;
    291     unsigned m_styleRecalcElementCounter;
    292     int m_layerTreeId;
    293 };
    294 
    295 } // namespace WebCore
    296 
    297 #endif // !defined(InspectorTimelineAgent_h)
    298