Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / inspector / InspectorTraceEvents.cpp
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.
4
5 #include "config.h"
6 #include "core/inspector/InspectorTraceEvents.h"
7
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"
26 #include <inttypes.h>
27
28 namespace WebCore {
29
30 namespace {
31
32 class JSCallStack : public TraceEvent::ConvertableToTraceFormat  {
33 public:
34     explicit JSCallStack(PassRefPtr<ScriptCallStack> callstack) : m_callstack(callstack) { }
35     virtual String asTraceFormat() const
36     {
37         if (!m_callstack)
38             return "[]";
39         return m_callstack->buildInspectorArray()->toJSONString();
40     }
41
42 private:
43     RefPtr<ScriptCallStack> m_callstack;
44 };
45
46 String toHexString(void* p)
47 {
48     return String::format("0x%" PRIx64, static_cast<uint64>(reinterpret_cast<intptr_t>(p)));
49 }
50
51 }
52
53 PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorLayoutEvent::beginData(FrameView* frameView)
54 {
55     bool isPartial;
56     unsigned needsLayoutObjects;
57     unsigned totalObjects;
58     LocalFrame& frame = frameView->frame();
59     frame.countObjectsNeedingLayout(needsLayoutObjects, totalObjects, isPartial);
60
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);
67 }
68
69 static PassRefPtr<JSONArray> createQuad(const FloatQuad& quad)
70 {
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();
81 }
82
83 PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorLayoutEvent::endData(RenderObject* rootForThisLayout)
84 {
85     Vector<FloatQuad> quads;
86     rootForThisLayout->absoluteQuads(quads);
87
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);
93     } else {
94         ASSERT_NOT_REACHED();
95     }
96     return TracedValue::fromJSONValue(data);
97 }
98
99 PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorSendRequestEvent::data(unsigned long identifier, LocalFrame* frame, const ResourceRequest& request)
100 {
101     String requestId = IdentifiersFactory::requestId(identifier);
102
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);
109 }
110
111 PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorReceiveResponseEvent::data(unsigned long identifier, LocalFrame* frame, const ResourceResponse& response)
112 {
113     String requestId = IdentifiersFactory::requestId(identifier);
114
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);
121 }
122
123 PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorReceiveDataEvent::data(unsigned long identifier, LocalFrame* frame, int encodedDataLength)
124 {
125     String requestId = IdentifiersFactory::requestId(identifier);
126
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);
132 }
133
134 PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorResourceFinishEvent::data(unsigned long identifier, double finishTime, bool didFail)
135 {
136     String requestId = IdentifiersFactory::requestId(identifier);
137
138     RefPtr<JSONObject> data = JSONObject::create();
139     data->setString("requestId", requestId);
140     data->setBoolean("didFail", didFail);
141     if (finishTime)
142         data->setNumber("networkTime", finishTime);
143     return TracedValue::fromJSONValue(data);
144 }
145
146 static LocalFrame* frameForExecutionContext(ExecutionContext* context)
147 {
148     LocalFrame* frame = 0;
149     if (context->isDocument())
150         frame = toDocument(context)->frame();
151     return frame;
152 }
153
154 static PassRefPtr<JSONObject> genericTimerData(ExecutionContext* context, int timerId)
155 {
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();
161 }
162
163 PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorTimerInstallEvent::data(ExecutionContext* context, int timerId, int timeout, bool singleShot)
164 {
165     RefPtr<JSONObject> data = genericTimerData(context, timerId);
166     data->setNumber("timeout", timeout);
167     data->setBoolean("singleShot", singleShot);
168     return TracedValue::fromJSONValue(data);
169 }
170
171 PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorTimerRemoveEvent::data(ExecutionContext* context, int timerId)
172 {
173     return TracedValue::fromJSONValue(genericTimerData(context, timerId));
174 }
175
176 PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorTimerFireEvent::data(ExecutionContext* context, int timerId)
177 {
178     return TracedValue::fromJSONValue(genericTimerData(context, timerId));
179 }
180
181 PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorAnimationFrameEvent::data(Document* document, int callbackId)
182 {
183     RefPtr<JSONObject> data = JSONObject::create();
184     data->setNumber("id", callbackId);
185     data->setString("frame", toHexString(document->frame()));
186     return TracedValue::fromJSONValue(data);
187 }
188
189 PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorWebSocketCreateEvent::data(Document* document, unsigned long identifier, const KURL& url, const String& protocol)
190 {
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);
198 }
199
200 PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorWebSocketEvent::data(Document* document, unsigned long identifier)
201 {
202     RefPtr<JSONObject> data = JSONObject::create();
203     data->setNumber("identifier", identifier);
204     data->setString("frame", toHexString(document->frame()));
205     return TracedValue::fromJSONValue(data);
206 }
207
208 PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorParseHtmlEvent::beginData(Document* document, unsigned startLine)
209 {
210     RefPtr<JSONObject> data = JSONObject::create();
211     data->setNumber("startLine", startLine);
212     data->setString("frame", toHexString(document->frame()));
213     return TracedValue::fromJSONValue(data);
214 }
215
216 PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorXhrReadyStateChangeEvent::data(ExecutionContext* context, XMLHttpRequest* request)
217 {
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);
224 }
225
226 PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorXhrLoadEvent::data(ExecutionContext* context, XMLHttpRequest* request)
227 {
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);
233 }
234
235 static void localToPageQuad(const RenderObject& renderer, const LayoutRect& rect, FloatQuad* quad)
236 {
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())));
244 }
245
246 PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorPaintEvent::data(RenderObject* renderer, const LayoutRect& clipRect, const GraphicsLayer* graphicsLayer)
247 {
248     RefPtr<JSONObject> data = JSONObject::create();
249     data->setString("frame", toHexString(renderer->frame()));
250     FloatQuad quad;
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);
258 }
259
260 PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorMarkLoadEvent::data(LocalFrame* frame)
261 {
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);
267 }
268
269 PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorScrollLayerEvent::data(RenderObject* renderer)
270 {
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);
276 }
277
278 PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorEvaluateScriptEvent::data(LocalFrame* frame, const String& url, int lineNumber)
279 {
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);
285 }
286
287 PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorFunctionCallEvent::data(ExecutionContext* context, int scriptId, const String& scriptName, int scriptLine)
288 {
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);
296 }
297
298 static size_t usedHeapSize()
299 {
300     HeapInfo info;
301     ScriptGCEvent::getHeapSize(info);
302     return info.usedJSHeapSize;
303 }
304
305 PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorUpdateCountersEvent::data()
306 {
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));
312     }
313     data->setNumber("jsHeapSizeUsed", static_cast<double>(usedHeapSize()));
314     return TracedValue::fromJSONValue(data);
315 }
316
317 PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorCallStackEvent::currentCallStack()
318 {
319     return adoptRef(new JSCallStack(createScriptCallStack(ScriptCallStack::maxCallStackSizeToCapture, true)));
320 }
321
322 }