Update V8 to r5901 as required by WebKit r73109

Change-Id: Ic48c5b085ce90e0151e2e7e58c4c5afe87fce9d1
diff --git a/test/cctest/test-heap-profiler.cc b/test/cctest/test-heap-profiler.cc
index b165190..95314d7 100644
--- a/test/cctest/test-heap-profiler.cc
+++ b/test/cctest/test-heap-profiler.cc
@@ -411,8 +411,12 @@
 
 static const v8::HeapGraphNode* GetGlobalObject(
     const v8::HeapSnapshot* snapshot) {
-  CHECK_EQ(1, snapshot->GetRoot()->GetChildrenCount());
-  return snapshot->GetRoot()->GetChild(0)->GetToNode();
+  CHECK_EQ(2, snapshot->GetRoot()->GetChildrenCount());
+  const v8::HeapGraphNode* global_obj =
+      snapshot->GetRoot()->GetChild(0)->GetToNode();
+  CHECK_EQ("Object", const_cast<i::HeapEntry*>(
+      reinterpret_cast<const i::HeapEntry*>(global_obj))->name());
+  return global_obj;
 }
 
 
@@ -479,21 +483,24 @@
 
   // Verify, that JS global object of env2 has '..2' properties.
   const v8::HeapGraphNode* a2_node =
-      GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "a2");
+      GetProperty(global_env2, v8::HeapGraphEdge::kShortcut, "a2");
   CHECK_NE(NULL, a2_node);
   CHECK_NE(
-      NULL, GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "b2_1"));
+      NULL, GetProperty(global_env2, v8::HeapGraphEdge::kShortcut, "b2_1"));
   CHECK_NE(
-      NULL, GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "b2_2"));
-  CHECK_NE(NULL, GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "c2"));
+      NULL, GetProperty(global_env2, v8::HeapGraphEdge::kShortcut, "b2_2"));
+  CHECK_NE(NULL, GetProperty(global_env2, v8::HeapGraphEdge::kShortcut, "c2"));
 
-  // Verify that anything related to '[ABC]1' is not reachable.
   NamedEntriesDetector det;
   i_snapshot_env2->IterateEntries(&det);
   CHECK(det.has_A2);
   CHECK(det.has_B2);
   CHECK(det.has_C2);
 
+  /*
+    // Currently disabled. Too many retaining paths emerge, need to
+    // reduce the amount.
+
   // Verify 'a2' object retainers. They are:
   //  - (global object).a2
   //  - c2.x1, c2.x2, c2[1]
@@ -538,6 +545,7 @@
   CHECK(has_c2_1_ref);
   CHECK(has_b2_1_x_ref);
   CHECK(has_b2_2_x_ref);
+  */
 }
 
 
@@ -550,37 +558,28 @@
   CompileRun(
       "function X(a, b) { this.a = a; this.b = b; }\n"
       "x = new X(new X(), new X());\n"
-      "x.a.a = x.b;");
+      "(function() { x.a.a = x.b; })();");
   const v8::HeapSnapshot* snapshot =
       v8::HeapProfiler::TakeSnapshot(v8::String::New("sizes"));
   const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
   const v8::HeapGraphNode* x =
-      GetProperty(global, v8::HeapGraphEdge::kProperty, "x");
+      GetProperty(global, v8::HeapGraphEdge::kShortcut, "x");
   CHECK_NE(NULL, x);
-  const v8::HeapGraphNode* x_prototype =
-      GetProperty(x, v8::HeapGraphEdge::kProperty, "__proto__");
-  CHECK_NE(NULL, x_prototype);
   const v8::HeapGraphNode* x1 =
       GetProperty(x, v8::HeapGraphEdge::kProperty, "a");
   CHECK_NE(NULL, x1);
   const v8::HeapGraphNode* x2 =
       GetProperty(x, v8::HeapGraphEdge::kProperty, "b");
   CHECK_NE(NULL, x2);
-  CHECK_EQ(
-      x->GetSelfSize() * 3,
-      x->GetReachableSize() - x_prototype->GetReachableSize());
-  CHECK_EQ(
-      x->GetSelfSize() * 3, x->GetRetainedSize());
-  CHECK_EQ(
-      x1->GetSelfSize() * 2,
-      x1->GetReachableSize() - x_prototype->GetReachableSize());
-  CHECK_EQ(
-      x1->GetSelfSize(), x1->GetRetainedSize());
-  CHECK_EQ(
-      x2->GetSelfSize(),
-      x2->GetReachableSize() - x_prototype->GetReachableSize());
-  CHECK_EQ(
-      x2->GetSelfSize(), x2->GetRetainedSize());
+
+  // Test approximate sizes.
+  CHECK_EQ(x->GetSelfSize() * 3, x->GetRetainedSize(false));
+  CHECK_EQ(x1->GetSelfSize(), x1->GetRetainedSize(false));
+  CHECK_EQ(x2->GetSelfSize(), x2->GetRetainedSize(false));
+  // Test exact sizes.
+  CHECK_EQ(x->GetSelfSize() * 3, x->GetRetainedSize(true));
+  CHECK_EQ(x1->GetSelfSize(), x1->GetRetainedSize(true));
+  CHECK_EQ(x2->GetSelfSize(), x2->GetRetainedSize(true));
 }
 
 
@@ -622,15 +621,15 @@
 
   const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
   const v8::HeapGraphNode* compiled =
-      GetProperty(global, v8::HeapGraphEdge::kProperty, "compiled");
+      GetProperty(global, v8::HeapGraphEdge::kShortcut, "compiled");
   CHECK_NE(NULL, compiled);
   CHECK_EQ(v8::HeapGraphNode::kClosure, compiled->GetType());
   const v8::HeapGraphNode* lazy =
-      GetProperty(global, v8::HeapGraphEdge::kProperty, "lazy");
+      GetProperty(global, v8::HeapGraphEdge::kShortcut, "lazy");
   CHECK_NE(NULL, lazy);
   CHECK_EQ(v8::HeapGraphNode::kClosure, lazy->GetType());
   const v8::HeapGraphNode* anonymous =
-      GetProperty(global, v8::HeapGraphEdge::kProperty, "anonymous");
+      GetProperty(global, v8::HeapGraphEdge::kShortcut, "anonymous");
   CHECK_NE(NULL, anonymous);
   CHECK_EQ(v8::HeapGraphNode::kClosure, anonymous->GetType());
   v8::String::AsciiValue anonymous_name(anonymous->GetName());
@@ -682,9 +681,9 @@
   const v8::HeapSnapshot* snapshot =
       v8::HeapProfiler::TakeSnapshot(v8::String::New("numbers"));
   const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
-  CHECK_EQ(NULL, GetProperty(global, v8::HeapGraphEdge::kProperty, "a"));
+  CHECK_EQ(NULL, GetProperty(global, v8::HeapGraphEdge::kShortcut, "a"));
   const v8::HeapGraphNode* b =
-      GetProperty(global, v8::HeapGraphEdge::kProperty, "b");
+      GetProperty(global, v8::HeapGraphEdge::kShortcut, "b");
   CHECK_NE(NULL, b);
   CHECK_EQ(v8::HeapGraphNode::kHeapNumber, b->GetType());
 }
@@ -808,12 +807,12 @@
     if (node->GetType() == v8::HeapGraphNode::kObject) {
       v8::String::AsciiValue node_name(node->GetName());
       if (strcmp(*node_name, "A2") == 0) {
-        CHECK(IsNodeRetainedAs(node, v8::HeapGraphEdge::kProperty, "a"));
+        CHECK(IsNodeRetainedAs(node, v8::HeapGraphEdge::kShortcut, "a"));
         CHECK(!found_A);
         found_A = true;
         s1_A_id = node->GetId();
       } else if (strcmp(*node_name, "B") == 0) {
-        CHECK(IsNodeRetainedAs(node, v8::HeapGraphEdge::kProperty, "b2"));
+        CHECK(IsNodeRetainedAs(node, v8::HeapGraphEdge::kShortcut, "b2"));
         CHECK(!found_B);
         found_B = true;
       }
@@ -832,7 +831,7 @@
     if (node->GetType() == v8::HeapGraphNode::kObject) {
       v8::String::AsciiValue node_name(node->GetName());
       if (strcmp(*node_name, "A") == 0) {
-        CHECK(IsNodeRetainedAs(node, v8::HeapGraphEdge::kProperty, "a"));
+        CHECK(IsNodeRetainedAs(node, v8::HeapGraphEdge::kShortcut, "a"));
         CHECK(!found_A_del);
         found_A_del = true;
         s2_A_id = node->GetId();
@@ -858,37 +857,6 @@
 }
 
 
-namespace v8 {
-namespace internal {
-
-class HeapSnapshotTester {
- public:
-  static int CalculateNetworkSize(JSObject* obj) {
-    return HeapSnapshot::CalculateNetworkSize(obj);
-  }
-};
-
-} }  // namespace v8::internal
-
-// http://code.google.com/p/v8/issues/detail?id=822
-// Trying to call CalculateNetworkSize on an object with elements set
-// to non-FixedArray may cause an assertion error in debug builds.
-TEST(Issue822) {
-  v8::HandleScope scope;
-  LocalContext context;
-  const int kElementCount = 260;
-  uint8_t* pixel_data = reinterpret_cast<uint8_t*>(malloc(kElementCount));
-  i::Handle<i::PixelArray> pixels = i::Factory::NewPixelArray(kElementCount,
-                                                              pixel_data);
-  v8::Handle<v8::Object> obj = v8::Object::New();
-  // Set the elements to be the pixels.
-  obj->SetIndexedPropertiesToPixelData(pixel_data, kElementCount);
-  i::Handle<i::JSObject> jsobj = v8::Utils::OpenHandle(*obj);
-  // This call must not cause an assertion error in debug builds.
-  i::HeapSnapshotTester::CalculateNetworkSize(*jsobj);
-}
-
-
 static const v8::HeapGraphNode* GetChild(
     const v8::HeapGraphNode* node,
     v8::HeapGraphNode::Type type,
@@ -932,13 +900,13 @@
       v8::HeapProfiler::TakeSnapshot(
           v8::String::New("agg"), v8::HeapSnapshot::kAggregated);
   const v8::HeapGraphNode* strings = GetChild(snapshot->GetRoot(),
-                                              v8::HeapGraphNode::kInternal,
+                                              v8::HeapGraphNode::kHidden,
                                               "STRING_TYPE");
   CHECK_NE(NULL, strings);
   CHECK_NE(0, strings->GetSelfSize());
   CHECK_NE(0, strings->GetInstancesCount());
   const v8::HeapGraphNode* maps = GetChild(snapshot->GetRoot(),
-                                           v8::HeapGraphNode::kInternal,
+                                           v8::HeapGraphNode::kHidden,
                                            "MAP_TYPE");
   CHECK_NE(NULL, maps);
   CHECK_NE(0, maps->GetSelfSize());
@@ -998,6 +966,67 @@
   CHECK(IsNodeRetainedAs(a_from_b, 1));  // B has 1 ref to A.
 }
 
+
+TEST(HeapEntryDominator) {
+  // The graph looks like this:
+  //
+  //                   -> node1
+  //                  a    |^
+  //          -> node5     ba
+  //         a             v|
+  //   node6           -> node2
+  //         b        a    |^
+  //          -> node4     ba
+  //                  b    v|
+  //                   -> node3
+  //
+  // The dominator for all nodes is node6.
+
+  v8::HandleScope scope;
+  LocalContext env;
+
+  CompileRun(
+      "function X(a, b) { this.a = a; this.b = b; }\n"
+      "node6 = new X(new X(new X()), new X(new X(),new X()));\n"
+      "(function(){\n"
+      "node6.a.a.b = node6.b.a;  // node1 -> node2\n"
+      "node6.b.a.a = node6.a.a;  // node2 -> node1\n"
+      "node6.b.a.b = node6.b.b;  // node2 -> node3\n"
+      "node6.b.b.a = node6.b.a;  // node3 -> node2\n"
+      "})();");
+
+  const v8::HeapSnapshot* snapshot =
+      v8::HeapProfiler::TakeSnapshot(v8::String::New("dominators"));
+
+  const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
+  CHECK_NE(NULL, global);
+  const v8::HeapGraphNode* node6 =
+      GetProperty(global, v8::HeapGraphEdge::kShortcut, "node6");
+  CHECK_NE(NULL, node6);
+  const v8::HeapGraphNode* node5 =
+      GetProperty(node6, v8::HeapGraphEdge::kProperty, "a");
+  CHECK_NE(NULL, node5);
+  const v8::HeapGraphNode* node4 =
+      GetProperty(node6, v8::HeapGraphEdge::kProperty, "b");
+  CHECK_NE(NULL, node4);
+  const v8::HeapGraphNode* node3 =
+      GetProperty(node4, v8::HeapGraphEdge::kProperty, "b");
+  CHECK_NE(NULL, node3);
+  const v8::HeapGraphNode* node2 =
+      GetProperty(node4, v8::HeapGraphEdge::kProperty, "a");
+  CHECK_NE(NULL, node2);
+  const v8::HeapGraphNode* node1 =
+      GetProperty(node5, v8::HeapGraphEdge::kProperty, "a");
+  CHECK_NE(NULL, node1);
+
+  CHECK_EQ(node6, node1->GetDominatorNode());
+  CHECK_EQ(node6, node2->GetDominatorNode());
+  CHECK_EQ(node6, node3->GetDominatorNode());
+  CHECK_EQ(node6, node4->GetDominatorNode());
+  CHECK_EQ(node6, node5->GetDominatorNode());
+}
+
+
 namespace {
 
 class TestJSONStream : public v8::OutputStream {
@@ -1073,13 +1102,9 @@
   CHECK(parsed_snapshot->Has(v8::String::New("nodes")));
   CHECK(parsed_snapshot->Has(v8::String::New("strings")));
 
-  // Verify that nodes meta-info is valid JSON.
-  v8::Local<v8::Value> nodes_meta_parse_result = CompileRun(
-      "var parsed_meta = JSON.parse(parsed.nodes[0]); true;");
-  CHECK(!nodes_meta_parse_result.IsEmpty());
-
   // Get node and edge "member" offsets.
   v8::Local<v8::Value> meta_analysis_result = CompileRun(
+      "var parsed_meta = parsed.nodes[0];\n"
       "var children_count_offset ="
       "    parsed_meta.fields.indexOf('children_count');\n"
       "var children_offset ="
@@ -1094,19 +1119,21 @@
       "var child_to_node_offset ="
       "    children_meta.fields.indexOf('to_node');\n"
       "var property_type ="
-      "    children_meta.types[child_type_offset].indexOf('property');");
+      "    children_meta.types[child_type_offset].indexOf('property');\n"
+      "var shortcut_type ="
+      "    children_meta.types[child_type_offset].indexOf('shortcut');");
   CHECK(!meta_analysis_result.IsEmpty());
 
   // A helper function for processing encoded nodes.
   CompileRun(
-      "function GetChildPosByProperty(pos, prop_name) {\n"
+      "function GetChildPosByProperty(pos, prop_name, prop_type) {\n"
       "  var nodes = parsed.nodes;\n"
       "  var strings = parsed.strings;\n"
       "  for (var i = 0,\n"
       "      count = nodes[pos + children_count_offset] * child_fields_count;\n"
       "      i < count; i += child_fields_count) {\n"
       "    var child_pos = pos + children_offset + i;\n"
-      "    if (nodes[child_pos + child_type_offset] === property_type\n"
+      "    if (nodes[child_pos + child_type_offset] === prop_type\n"
       "       && strings[nodes[child_pos + child_name_offset]] === prop_name)\n"
       "        return nodes[child_pos + child_to_node_offset];\n"
       "  }\n"
@@ -1117,9 +1144,10 @@
       "GetChildPosByProperty(\n"
       "  GetChildPosByProperty(\n"
       "    GetChildPosByProperty("
-      "      parsed.nodes[1 + children_offset + child_to_node_offset],\"b\"),\n"
-      "    \"x\"),"
-      "  \"s\")");
+      "      parsed.nodes[1 + children_offset + child_to_node_offset],"
+      "      \"b\",shortcut_type),\n"
+      "    \"x\", property_type),"
+      "  \"s\", property_type)");
   CHECK(!string_obj_pos_val.IsEmpty());
   int string_obj_pos =
       static_cast<int>(string_obj_pos_val->ToNumber()->Value());
@@ -1150,4 +1178,19 @@
   CHECK_EQ(0, stream.eos_signaled());
 }
 
+
+// Must not crash in debug mode.
+TEST(AggregatedHeapSnapshotJSONSerialization) {
+  v8::HandleScope scope;
+  LocalContext env;
+
+  const v8::HeapSnapshot* snapshot =
+      v8::HeapProfiler::TakeSnapshot(
+          v8::String::New("agg"), v8::HeapSnapshot::kAggregated);
+  TestJSONStream stream;
+  snapshot->Serialize(&stream, v8::HeapSnapshot::kJSON);
+  CHECK_GT(stream.size(), 0);
+  CHECK_EQ(1, stream.eos_signaled());
+}
+
 #endif  // ENABLE_LOGGING_AND_PROFILING