1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
6 #include "core/inspector/InspectorTraceEvents.h"
8 #include "bindings/v8/ScriptCallStackFactory.h"
9 #include "bindings/v8/ScriptGCEvent.h"
10 #include "bindings/v8/ScriptSourceCode.h"
11 #include "core/frame/FrameView.h"
12 #include "core/frame/LocalFrame.h"
13 #include "core/inspector/IdentifiersFactory.h"
14 #include "core/inspector/InspectorNodeIds.h"
15 #include "core/inspector/ScriptCallStack.h"
16 #include "core/page/Page.h"
17 #include "core/rendering/RenderObject.h"
18 #include "core/xml/XMLHttpRequest.h"
19 #include "platform/JSONValues.h"
20 #include "platform/TracedValue.h"
21 #include "platform/graphics/GraphicsLayer.h"
22 #include "platform/network/ResourceRequest.h"
23 #include "platform/network/ResourceResponse.h"
24 #include "platform/weborigin/KURL.h"
25 #include "wtf/Vector.h"
32 class JSCallStack : public TraceEvent::ConvertableToTraceFormat {
34 explicit JSCallStack(PassRefPtr<ScriptCallStack> callstack) : m_callstack(callstack) { }
35 virtual String asTraceFormat() const
39 return m_callstack->buildInspectorArray()->toJSONString();
43 RefPtr<ScriptCallStack> m_callstack;
46 String toHexString(void* p)
48 return String::format("0x%" PRIx64, static_cast<uint64>(reinterpret_cast<intptr_t>(p)));
53 PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorLayoutEvent::beginData(FrameView* frameView)
56 unsigned needsLayoutObjects;
57 unsigned totalObjects;
58 LocalFrame& frame = frameView->frame();
59 frame.countObjectsNeedingLayout(needsLayoutObjects, totalObjects, isPartial);
61 RefPtr<JSONObject> data = JSONObject::create();
62 data->setNumber("dirtyObjects", needsLayoutObjects);
63 data->setNumber("totalObjects", totalObjects);
64 data->setBoolean("partialLayout", isPartial);
65 data->setString("frame", toHexString(&frame));
66 return TracedValue::fromJSONValue(data);
69 static PassRefPtr<JSONArray> createQuad(const FloatQuad& quad)
71 RefPtr<JSONArray> array = JSONArray::create();
72 array->pushNumber(quad.p1().x());
73 array->pushNumber(quad.p1().y());
74 array->pushNumber(quad.p2().x());
75 array->pushNumber(quad.p2().y());
76 array->pushNumber(quad.p3().x());
77 array->pushNumber(quad.p3().y());
78 array->pushNumber(quad.p4().x());
79 array->pushNumber(quad.p4().y());
80 return array.release();
83 PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorLayoutEvent::endData(RenderObject* rootForThisLayout)
85 Vector<FloatQuad> quads;
86 rootForThisLayout->absoluteQuads(quads);
88 RefPtr<JSONObject> data = JSONObject::create();
89 if (quads.size() >= 1) {
90 data->setArray("root", createQuad(quads[0]));
91 int rootNodeId = InspectorNodeIds::idForNode(rootForThisLayout->generatingNode());
92 data->setNumber("rootNode", rootNodeId);
96 return TracedValue::fromJSONValue(data);
99 PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorSendRequestEvent::data(unsigned long identifier, LocalFrame* frame, const ResourceRequest& request)
101 String requestId = IdentifiersFactory::requestId(identifier);
103 RefPtr<JSONObject> data = JSONObject::create();
104 data->setString("requestId", requestId);
105 data->setString("frame", toHexString(frame));
106 data->setString("url", request.url().string());
107 data->setString("requestMethod", request.httpMethod());
108 return TracedValue::fromJSONValue(data);
111 PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorReceiveResponseEvent::data(unsigned long identifier, LocalFrame* frame, const ResourceResponse& response)
113 String requestId = IdentifiersFactory::requestId(identifier);
115 RefPtr<JSONObject> data = JSONObject::create();
116 data->setString("requestId", requestId);
117 data->setString("frame", toHexString(frame));
118 data->setNumber("statusCode", response.httpStatusCode());
119 data->setString("mimeType", response.mimeType());
120 return TracedValue::fromJSONValue(data);
123 PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorReceiveDataEvent::data(unsigned long identifier, LocalFrame* frame, int encodedDataLength)
125 String requestId = IdentifiersFactory::requestId(identifier);
127 RefPtr<JSONObject> data = JSONObject::create();
128 data->setString("requestId", requestId);
129 data->setString("frame", toHexString(frame));
130 data->setNumber("encodedDataLength", encodedDataLength);
131 return TracedValue::fromJSONValue(data);
134 PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorResourceFinishEvent::data(unsigned long identifier, double finishTime, bool didFail)
136 String requestId = IdentifiersFactory::requestId(identifier);
138 RefPtr<JSONObject> data = JSONObject::create();
139 data->setString("requestId", requestId);
140 data->setBoolean("didFail", didFail);
142 data->setNumber("networkTime", finishTime);
143 return TracedValue::fromJSONValue(data);
146 static LocalFrame* frameForExecutionContext(ExecutionContext* context)
148 LocalFrame* frame = 0;
149 if (context->isDocument())
150 frame = toDocument(context)->frame();
154 static PassRefPtr<JSONObject> genericTimerData(ExecutionContext* context, int timerId)
156 RefPtr<JSONObject> data = JSONObject::create();
157 data->setNumber("timerId", timerId);
158 if (LocalFrame* frame = frameForExecutionContext(context))
159 data->setString("frame", toHexString(frame));
160 return data.release();
163 PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorTimerInstallEvent::data(ExecutionContext* context, int timerId, int timeout, bool singleShot)
165 RefPtr<JSONObject> data = genericTimerData(context, timerId);
166 data->setNumber("timeout", timeout);
167 data->setBoolean("singleShot", singleShot);
168 return TracedValue::fromJSONValue(data);
171 PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorTimerRemoveEvent::data(ExecutionContext* context, int timerId)
173 return TracedValue::fromJSONValue(genericTimerData(context, timerId));
176 PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorTimerFireEvent::data(ExecutionContext* context, int timerId)
178 return TracedValue::fromJSONValue(genericTimerData(context, timerId));
181 PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorAnimationFrameEvent::data(Document* document, int callbackId)
183 RefPtr<JSONObject> data = JSONObject::create();
184 data->setNumber("id", callbackId);
185 data->setString("frame", toHexString(document->frame()));
186 return TracedValue::fromJSONValue(data);
189 PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorWebSocketCreateEvent::data(Document* document, unsigned long identifier, const KURL& url, const String& protocol)
191 RefPtr<JSONObject> data = JSONObject::create();
192 data->setNumber("identifier", identifier);
193 data->setString("url", url.string());
194 data->setString("frame", toHexString(document->frame()));
195 if (!protocol.isNull())
196 data->setString("webSocketProtocol", protocol);
197 return TracedValue::fromJSONValue(data);
200 PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorWebSocketEvent::data(Document* document, unsigned long identifier)
202 RefPtr<JSONObject> data = JSONObject::create();
203 data->setNumber("identifier", identifier);
204 data->setString("frame", toHexString(document->frame()));
205 return TracedValue::fromJSONValue(data);
208 PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorParseHtmlEvent::beginData(Document* document, unsigned startLine)
210 RefPtr<JSONObject> data = JSONObject::create();
211 data->setNumber("startLine", startLine);
212 data->setString("frame", toHexString(document->frame()));
213 return TracedValue::fromJSONValue(data);
216 PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorXhrReadyStateChangeEvent::data(ExecutionContext* context, XMLHttpRequest* request)
218 RefPtr<JSONObject> data = JSONObject::create();
219 data->setString("url", request->url().string());
220 data->setNumber("readyState", request->readyState());
221 if (LocalFrame* frame = frameForExecutionContext(context))
222 data->setString("frame", toHexString(frame));
223 return TracedValue::fromJSONValue(data);
226 PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorXhrLoadEvent::data(ExecutionContext* context, XMLHttpRequest* request)
228 RefPtr<JSONObject> data = JSONObject::create();
229 data->setString("url", request->url().string());
230 if (LocalFrame* frame = frameForExecutionContext(context))
231 data->setString("frame", toHexString(frame));
232 return TracedValue::fromJSONValue(data);
235 static void localToPageQuad(const RenderObject& renderer, const LayoutRect& rect, FloatQuad* quad)
237 LocalFrame* frame = renderer.frame();
238 FrameView* view = frame->view();
239 FloatQuad absolute = renderer.localToAbsoluteQuad(FloatQuad(rect));
240 quad->setP1(view->contentsToRootView(roundedIntPoint(absolute.p1())));
241 quad->setP2(view->contentsToRootView(roundedIntPoint(absolute.p2())));
242 quad->setP3(view->contentsToRootView(roundedIntPoint(absolute.p3())));
243 quad->setP4(view->contentsToRootView(roundedIntPoint(absolute.p4())));
246 PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorPaintEvent::data(RenderObject* renderer, const LayoutRect& clipRect, const GraphicsLayer* graphicsLayer)
248 RefPtr<JSONObject> data = JSONObject::create();
249 data->setString("frame", toHexString(renderer->frame()));
251 localToPageQuad(*renderer, clipRect, &quad);
252 data->setArray("clip", createQuad(quad));
253 int nodeId = InspectorNodeIds::idForNode(renderer->generatingNode());
254 data->setNumber("nodeId", nodeId);
255 int graphicsLayerId = graphicsLayer ? graphicsLayer->platformLayer()->id() : 0;
256 data->setNumber("layerId", graphicsLayerId);
257 return TracedValue::fromJSONValue(data);
260 PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorMarkLoadEvent::data(LocalFrame* frame)
262 RefPtr<JSONObject> data = JSONObject::create();
263 data->setString("frame", toHexString(frame));
264 bool isMainFrame = frame && frame->page()->mainFrame() == frame;
265 data->setBoolean("isMainFrame", isMainFrame);
266 return TracedValue::fromJSONValue(data);
269 PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorScrollLayerEvent::data(RenderObject* renderer)
271 RefPtr<JSONObject> data = JSONObject::create();
272 data->setString("frame", toHexString(renderer->frame()));
273 int nodeId = InspectorNodeIds::idForNode(renderer->generatingNode());
274 data->setNumber("nodeId", nodeId);
275 return TracedValue::fromJSONValue(data);
278 PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorEvaluateScriptEvent::data(LocalFrame* frame, const String& url, int lineNumber)
280 RefPtr<JSONObject> data = JSONObject::create();
281 data->setString("frame", toHexString(frame));
282 data->setString("url", url);
283 data->setNumber("lineNumber", lineNumber);
284 return TracedValue::fromJSONValue(data);
287 PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorFunctionCallEvent::data(ExecutionContext* context, int scriptId, const String& scriptName, int scriptLine)
289 RefPtr<JSONObject> data = JSONObject::create();
290 data->setString("scriptId", String::number(scriptId));
291 data->setString("scriptName", scriptName);
292 data->setNumber("scriptLine", scriptLine);
293 if (LocalFrame* frame = frameForExecutionContext(context))
294 data->setString("frame", toHexString(frame));
295 return TracedValue::fromJSONValue(data);
298 static size_t usedHeapSize()
301 ScriptGCEvent::getHeapSize(info);
302 return info.usedJSHeapSize;
305 PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorUpdateCountersEvent::data()
307 RefPtr<JSONObject> data = JSONObject::create();
308 if (isMainThread()) {
309 data->setNumber("documents", InspectorCounters::counterValue(InspectorCounters::DocumentCounter));
310 data->setNumber("nodes", InspectorCounters::counterValue(InspectorCounters::NodeCounter));
311 data->setNumber("jsEventListeners", InspectorCounters::counterValue(InspectorCounters::JSEventListenerCounter));
313 data->setNumber("jsHeapSizeUsed", static_cast<double>(usedHeapSize()));
314 return TracedValue::fromJSONValue(data);
317 PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorCallStackEvent::currentCallStack()
319 return adoptRef(new JSCallStack(createScriptCallStack(ScriptCallStack::maxCallStackSizeToCapture, true)));