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