DevTools: Refactor Profiler domain interface

Flatten nodes into an array.

Review-Url: https://codereview.chromium.org/2244783004
Cr-Original-Commit-Position: refs/heads/master@{#412613}
Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src
Cr-Mirrored-Commit: 3b17e107b6801bc18861154e707dfa57ba23a909
diff --git a/V8ProfilerAgentImpl.cpp b/V8ProfilerAgentImpl.cpp
index aecea81..a7df314 100644
--- a/V8ProfilerAgentImpl.cpp
+++ b/V8ProfilerAgentImpl.cpp
@@ -50,12 +50,10 @@
 {
     v8::HandleScope handleScope(isolate);
 
-    std::unique_ptr<protocol::Array<protocol::Profiler::CPUProfileNode>> children = protocol::Array<protocol::Profiler::CPUProfileNode>::create();
+    std::unique_ptr<protocol::Array<int>> children = protocol::Array<int>::create();
     const int childrenCount = node->GetChildrenCount();
-    for (int i = 0; i < childrenCount; i++) {
-        const v8::CpuProfileNode* child = node->GetChild(i);
-        children->addItem(buildInspectorObjectFor(isolate, child));
-    }
+    for (int i = 0; i < childrenCount; i++)
+        children->addItem(node->GetChild(i)->GetNodeId());
 
     std::unique_ptr<protocol::Array<protocol::Profiler::PositionTickInfo>> positionTicks = buildInspectorObjectForPositionTicks(node);
 
@@ -94,10 +92,21 @@
     return array;
 }
 
+void flattenNodesTree(v8::Isolate* isolate, const v8::CpuProfileNode* node, protocol::Array<protocol::Profiler::CPUProfileNode>* list)
+{
+    list->addItem(buildInspectorObjectFor(isolate, node));
+    const int childrenCount = node->GetChildrenCount();
+    for (int i = 0; i < childrenCount; i++)
+        flattenNodesTree(isolate, node->GetChild(i), list);
+}
+
 std::unique_ptr<protocol::Profiler::CPUProfile> createCPUProfile(v8::Isolate* isolate, v8::CpuProfile* v8profile)
 {
+    std::unique_ptr<protocol::Array<protocol::Profiler::CPUProfileNode>> nodes = protocol::Array<protocol::Profiler::CPUProfileNode>::create();
+    flattenNodesTree(isolate, v8profile->GetTopDownRoot(), nodes.get());
+
     std::unique_ptr<protocol::Profiler::CPUProfile> profile = protocol::Profiler::CPUProfile::create()
-        .setHead(buildInspectorObjectFor(isolate, v8profile->GetTopDownRoot()))
+        .setNodes(std::move(nodes))
         .setStartTime(static_cast<double>(v8profile->GetStartTime()) / 1000000)
         .setEndTime(static_cast<double>(v8profile->GetEndTime()) / 1000000).build();
     profile->setSamples(buildInspectorObjectForSamples(v8profile));
diff --git a/js_protocol.json b/js_protocol.json
index ce52422..c30ec47 100644
--- a/js_protocol.json
+++ b/js_protocol.json
@@ -777,12 +777,12 @@
                 "type": "object",
                 "description": "CPU Profile node. Holds callsite information, execution statistics and child nodes.",
                 "properties": [
+                    { "name": "id", "type": "integer", "description": "Unique id of the node." },
                     { "name": "callFrame", "$ref": "Runtime.CallFrame", "description": "Function location." },
                     { "name": "hitCount", "type": "integer", "description": "Number of samples where this node was on top of the call stack." },
-                    { "name": "children", "type": "array", "items": { "$ref": "CPUProfileNode" }, "description": "Child nodes." },
-                    { "name": "deoptReason", "type": "string", "description": "The reason of being not optimized. The function may be deoptimized or marked as don't optimize."},
-                    { "name": "id", "type": "integer", "description": "Unique id of the node." },
-                    { "name": "positionTicks", "type": "array", "items": { "$ref": "PositionTickInfo" }, "description": "An array of source position ticks." }
+                    { "name": "children", "type": "array", "items": { "type": "integer" }, "description": "Child node ids." },
+                    { "name": "deoptReason", "type": "string", "experimental": true, "description": "The reason of being not optimized. The function may be deoptimized or marked as don't optimize."},
+                    { "name": "positionTicks", "type": "array", "items": { "$ref": "PositionTickInfo" }, "experimental": true, "description": "An array of source position ticks." }
                 ]
             },
             {
@@ -790,7 +790,7 @@
                 "type": "object",
                 "description": "Profile.",
                 "properties": [
-                    { "name": "head", "$ref": "CPUProfileNode" },
+                    { "name": "nodes", "type": "array", "items": { "$ref": "CPUProfileNode" }, "description": "The list of profile nodes. First item is the root node." },
                     { "name": "startTime", "type": "number", "description": "Profiling start time in seconds." },
                     { "name": "endTime", "type": "number", "description": "Profiling end time in seconds." },
                     { "name": "samples", "optional": true, "type": "array", "items": { "type": "integer" }, "description": "Ids of samples top nodes." },
@@ -800,6 +800,7 @@
             {
                 "id": "PositionTickInfo",
                 "type": "object",
+                "experimental": true,
                 "description": "Specifies a number of samples attributed to a certain source position.",
                 "properties": [
                     { "name": "line", "type": "integer", "description": "Source line number (1-based)." },
@@ -837,7 +838,7 @@
                 "parameters": [
                     { "name": "id", "type": "string" },
                     { "name": "location", "$ref": "Debugger.Location", "description": "Location of console.profile()." },
-                    { "name": "title", "type": "string", "optional": true, "description": "Profile title passed as argument to console.profile()." }
+                    { "name": "title", "type": "string", "optional": true, "description": "Profile title passed as an argument to console.profile()." }
                 ],
                 "description": "Sent when new profile recodring is started using console.profile() call."
             },
@@ -847,7 +848,7 @@
                     { "name": "id", "type": "string" },
                     { "name": "location", "$ref": "Debugger.Location", "description": "Location of console.profileEnd()." },
                     { "name": "profile", "$ref": "CPUProfile" },
-                    { "name": "title", "type": "string", "optional": true, "description": "Profile title passed as argunet to console.profile()." }
+                    { "name": "title", "type": "string", "optional": true, "description": "Profile title passed as an argument to console.profile()." }
                 ]
             }
         ]