test-heap-profiler.cc revision 69a99ed0b2b2ef69d393c371b03db3a98aaf880e
1257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Copyright 2011 the V8 project authors. All rights reserved. 2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Tests for heap profiler 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "v8.h" 6257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 7257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#include "cctest.h" 8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "heap-profiler.h" 99dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen#include "snapshot.h" 10257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#include "utils-inl.h" 119dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen#include "../include/v8-profiler.h" 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 139dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsennamespace { 149dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 159dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenclass NamedEntriesDetector { 169dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen public: 179dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen NamedEntriesDetector() 1890bac256d9f48d4ee52d0e08bf0e5cad57b3c51cRussell Brenner : has_A2(false), has_B2(false), has_C2(false) { 199dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen } 209dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 21756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick void Apply(i::HeapEntry** entry_ptr) { 22756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick if (IsReachableNodeWithName(*entry_ptr, "A2")) has_A2 = true; 23756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick if (IsReachableNodeWithName(*entry_ptr, "B2")) has_B2 = true; 24756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick if (IsReachableNodeWithName(*entry_ptr, "C2")) has_C2 = true; 25756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 26756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 27756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick static bool IsReachableNodeWithName(i::HeapEntry* entry, const char* name) { 28756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick return strcmp(name, entry->name()) == 0 && entry->painted_reachable(); 299dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen } 309dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 319dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen bool has_A2; 329dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen bool has_B2; 339dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen bool has_C2; 349dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen}; 359dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 369dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen} // namespace 379dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 389dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 399dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenstatic const v8::HeapGraphNode* GetGlobalObject( 409dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen const v8::HeapSnapshot* snapshot) { 418a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang CHECK_EQ(2, snapshot->GetRoot()->GetChildrenCount()); 428a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang const v8::HeapGraphNode* global_obj = 438a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang snapshot->GetRoot()->GetChild(0)->GetToNode(); 443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CHECK_EQ(0, strncmp("Object", const_cast<i::HeapEntry*>( 453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch reinterpret_cast<const i::HeapEntry*>(global_obj))->name(), 6)); 468a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang return global_obj; 479dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen} 489dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 499dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 509dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenstatic const v8::HeapGraphNode* GetProperty(const v8::HeapGraphNode* node, 519dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen v8::HeapGraphEdge::Type type, 529dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen const char* name) { 539dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen for (int i = 0, count = node->GetChildrenCount(); i < count; ++i) { 549dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen const v8::HeapGraphEdge* prop = node->GetChild(i); 559dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen v8::String::AsciiValue prop_name(prop->GetName()); 569dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen if (prop->GetType() == type && strcmp(name, *prop_name) == 0) 579dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen return prop->GetToNode(); 589dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen } 599dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen return NULL; 609dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen} 619dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 629dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 639dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenstatic bool HasString(const v8::HeapGraphNode* node, const char* contents) { 649dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen for (int i = 0, count = node->GetChildrenCount(); i < count; ++i) { 659dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen const v8::HeapGraphEdge* prop = node->GetChild(i); 669dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen const v8::HeapGraphNode* node = prop->GetToNode(); 67756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick if (node->GetType() == v8::HeapGraphNode::kString) { 689dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen v8::String::AsciiValue node_name(node->GetName()); 699dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen if (strcmp(contents, *node_name) == 0) return true; 709dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen } 719dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen } 729dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen return false; 739dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen} 749dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 759dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 769dcf7e2f83591d471e88bf7d230651900b8e424bKristian MonsenTEST(HeapSnapshot) { 779dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen v8::HandleScope scope; 783bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch LocalContext env2; 799dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 80f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch CompileRun( 819dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen "function A2() {}\n" 829dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen "function B2(x) { return function() { return typeof x; }; }\n" 839dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen "function C2(x) { this.x1 = x; this.x2 = x; this[1] = x; }\n" 849dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen "var a2 = new A2();\n" 859dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen "var b2_1 = new B2(a2), b2_2 = new B2(a2);\n" 869dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen "var c2 = new C2(a2);"); 879dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen const v8::HeapSnapshot* snapshot_env2 = 8869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::HeapProfiler::TakeSnapshot(v8_str("env2")); 89756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick i::HeapSnapshot* i_snapshot_env2 = 90756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick const_cast<i::HeapSnapshot*>( 91756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick reinterpret_cast<const i::HeapSnapshot*>(snapshot_env2)); 929dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen const v8::HeapGraphNode* global_env2 = GetGlobalObject(snapshot_env2); 93756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // Paint all nodes reachable from global object. 94756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick i_snapshot_env2->ClearPaint(); 95756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick const_cast<i::HeapEntry*>( 96756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick reinterpret_cast<const i::HeapEntry*>(global_env2))->PaintAllReachable(); 979dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 9890bac256d9f48d4ee52d0e08bf0e5cad57b3c51cRussell Brenner // Verify, that JS global object of env2 has '..2' properties. 999dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen const v8::HeapGraphNode* a2_node = 1008a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang GetProperty(global_env2, v8::HeapGraphEdge::kShortcut, "a2"); 1019dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen CHECK_NE(NULL, a2_node); 102756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CHECK_NE( 1038a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang NULL, GetProperty(global_env2, v8::HeapGraphEdge::kShortcut, "b2_1")); 104756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CHECK_NE( 1058a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang NULL, GetProperty(global_env2, v8::HeapGraphEdge::kShortcut, "b2_2")); 1068a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang CHECK_NE(NULL, GetProperty(global_env2, v8::HeapGraphEdge::kShortcut, "c2")); 1079dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 1089dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen NamedEntriesDetector det; 1099dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen i_snapshot_env2->IterateEntries(&det); 1109dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen CHECK(det.has_A2); 1119dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen CHECK(det.has_B2); 1129dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen CHECK(det.has_C2); 1139dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen} 1149dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 1159dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 116756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain MerrickTEST(HeapSnapshotObjectSizes) { 117756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick v8::HandleScope scope; 118756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick LocalContext env; 119756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 120756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // -a-> X1 --a 121756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // x -b-> X2 <-| 122f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch CompileRun( 123756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick "function X(a, b) { this.a = a; this.b = b; }\n" 124756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick "x = new X(new X(), new X());\n" 1258a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang "(function() { x.a.a = x.b; })();"); 126756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick const v8::HeapSnapshot* snapshot = 12769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::HeapProfiler::TakeSnapshot(v8_str("sizes")); 128756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick const v8::HeapGraphNode* global = GetGlobalObject(snapshot); 129756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick const v8::HeapGraphNode* x = 1308a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang GetProperty(global, v8::HeapGraphEdge::kShortcut, "x"); 131756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CHECK_NE(NULL, x); 132756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick const v8::HeapGraphNode* x1 = 133756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick GetProperty(x, v8::HeapGraphEdge::kProperty, "a"); 134756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CHECK_NE(NULL, x1); 135756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick const v8::HeapGraphNode* x2 = 136756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick GetProperty(x, v8::HeapGraphEdge::kProperty, "b"); 137756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CHECK_NE(NULL, x2); 1388a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 1398a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang // Test approximate sizes. 1408a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang CHECK_EQ(x->GetSelfSize() * 3, x->GetRetainedSize(false)); 1418a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang CHECK_EQ(x1->GetSelfSize(), x1->GetRetainedSize(false)); 1428a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang CHECK_EQ(x2->GetSelfSize(), x2->GetRetainedSize(false)); 1438a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang // Test exact sizes. 1448a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang CHECK_EQ(x->GetSelfSize() * 3, x->GetRetainedSize(true)); 1458a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang CHECK_EQ(x1->GetSelfSize(), x1->GetRetainedSize(true)); 1468a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang CHECK_EQ(x2->GetSelfSize(), x2->GetRetainedSize(true)); 147756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick} 148756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 149756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 150756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain MerrickTEST(HeapSnapshotEntryChildren) { 151756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick v8::HandleScope scope; 152756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick LocalContext env; 153756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 154f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch CompileRun( 155756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick "function A() { }\n" 156756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick "a = new A;"); 157756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick const v8::HeapSnapshot* snapshot = 15869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::HeapProfiler::TakeSnapshot(v8_str("children")); 159756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick const v8::HeapGraphNode* global = GetGlobalObject(snapshot); 160756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick for (int i = 0, count = global->GetChildrenCount(); i < count; ++i) { 161756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick const v8::HeapGraphEdge* prop = global->GetChild(i); 162756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CHECK_EQ(global, prop->GetFromNode()); 163756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 164756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick const v8::HeapGraphNode* a = 165756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick GetProperty(global, v8::HeapGraphEdge::kProperty, "a"); 166756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CHECK_NE(NULL, a); 167756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick for (int i = 0, count = a->GetChildrenCount(); i < count; ++i) { 168756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick const v8::HeapGraphEdge* prop = a->GetChild(i); 169756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CHECK_EQ(a, prop->GetFromNode()); 170756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 171756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick} 172756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 173756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1749dcf7e2f83591d471e88bf7d230651900b8e424bKristian MonsenTEST(HeapSnapshotCodeObjects) { 1759dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen v8::HandleScope scope; 1763bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch LocalContext env; 1779dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 178f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch CompileRun( 1799dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen "function lazy(x) { return x - 1; }\n" 1809dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen "function compiled(x) { return x + 1; }\n" 181791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block "var anonymous = (function() { return function() { return 0; } })();\n" 1829dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen "compiled(1)"); 1839dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen const v8::HeapSnapshot* snapshot = 18469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::HeapProfiler::TakeSnapshot(v8_str("code")); 1859dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 1869dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen const v8::HeapGraphNode* global = GetGlobalObject(snapshot); 1879dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen const v8::HeapGraphNode* compiled = 1888a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang GetProperty(global, v8::HeapGraphEdge::kShortcut, "compiled"); 1899dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen CHECK_NE(NULL, compiled); 190756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CHECK_EQ(v8::HeapGraphNode::kClosure, compiled->GetType()); 1919dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen const v8::HeapGraphNode* lazy = 1928a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang GetProperty(global, v8::HeapGraphEdge::kShortcut, "lazy"); 1939dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen CHECK_NE(NULL, lazy); 194756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CHECK_EQ(v8::HeapGraphNode::kClosure, lazy->GetType()); 195791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block const v8::HeapGraphNode* anonymous = 1968a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang GetProperty(global, v8::HeapGraphEdge::kShortcut, "anonymous"); 197791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block CHECK_NE(NULL, anonymous); 198791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block CHECK_EQ(v8::HeapGraphNode::kClosure, anonymous->GetType()); 199791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block v8::String::AsciiValue anonymous_name(anonymous->GetName()); 200f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch CHECK_EQ("", *anonymous_name); 2019dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 2029dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen // Find references to code. 2039dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen const v8::HeapGraphNode* compiled_code = 2048b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch GetProperty(compiled, v8::HeapGraphEdge::kInternal, "shared"); 2059dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen CHECK_NE(NULL, compiled_code); 2069dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen const v8::HeapGraphNode* lazy_code = 2078b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch GetProperty(lazy, v8::HeapGraphEdge::kInternal, "shared"); 2089dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen CHECK_NE(NULL, lazy_code); 2099dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 2109dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen // Verify that non-compiled code doesn't contain references to "x" 2113bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch // literal, while compiled code does. The scope info is stored in FixedArray 2123bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch // objects attached to the SharedFunctionInfo. 2139dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen bool compiled_references_x = false, lazy_references_x = false; 2149dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen for (int i = 0, count = compiled_code->GetChildrenCount(); i < count; ++i) { 2159dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen const v8::HeapGraphEdge* prop = compiled_code->GetChild(i); 2169dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen const v8::HeapGraphNode* node = prop->GetToNode(); 217756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick if (node->GetType() == v8::HeapGraphNode::kArray) { 2189dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen if (HasString(node, "x")) { 2199dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen compiled_references_x = true; 2209dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen break; 2219dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen } 2229dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen } 2239dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen } 2249dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen for (int i = 0, count = lazy_code->GetChildrenCount(); i < count; ++i) { 2259dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen const v8::HeapGraphEdge* prop = lazy_code->GetChild(i); 2269dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen const v8::HeapGraphNode* node = prop->GetToNode(); 227756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick if (node->GetType() == v8::HeapGraphNode::kArray) { 2289dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen if (HasString(node, "x")) { 2299dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen lazy_references_x = true; 2309dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen break; 2319dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen } 2329dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen } 2339dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen } 2349dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen CHECK(compiled_references_x); 2359dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen CHECK(!lazy_references_x); 2369dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen} 2379dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 2383bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 239f87a203d89e1bbb6708282e0b64dbd13d59b723dBen MurdochTEST(HeapSnapshotHeapNumbers) { 240f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch v8::HandleScope scope; 241f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch LocalContext env; 242f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch CompileRun( 243f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch "a = 1; // a is Smi\n" 244f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch "b = 2.5; // b is HeapNumber"); 245f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch const v8::HeapSnapshot* snapshot = 24669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::HeapProfiler::TakeSnapshot(v8_str("numbers")); 247f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch const v8::HeapGraphNode* global = GetGlobalObject(snapshot); 2488a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang CHECK_EQ(NULL, GetProperty(global, v8::HeapGraphEdge::kShortcut, "a")); 249f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch const v8::HeapGraphNode* b = 2508a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang GetProperty(global, v8::HeapGraphEdge::kShortcut, "b"); 251f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch CHECK_NE(NULL, b); 252f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch CHECK_EQ(v8::HeapGraphNode::kHeapNumber, b->GetType()); 253f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch} 254f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 255f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 256f87a203d89e1bbb6708282e0b64dbd13d59b723dBen MurdochTEST(HeapSnapshotInternalReferences) { 257f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch v8::HandleScope scope; 258f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch v8::Local<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); 259f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch global_template->SetInternalFieldCount(2); 260f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch LocalContext env(NULL, global_template); 261f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch v8::Handle<v8::Object> global_proxy = env->Global(); 262f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch v8::Handle<v8::Object> global = global_proxy->GetPrototype().As<v8::Object>(); 263f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch CHECK_EQ(2, global->InternalFieldCount()); 264f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch v8::Local<v8::Object> obj = v8::Object::New(); 265f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch global->SetInternalField(0, v8_num(17)); 266f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch global->SetInternalField(1, obj); 267f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch const v8::HeapSnapshot* snapshot = 26869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::HeapProfiler::TakeSnapshot(v8_str("internals")); 269f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch const v8::HeapGraphNode* global_node = GetGlobalObject(snapshot); 270f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // The first reference will not present, because it's a Smi. 271f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch CHECK_EQ(NULL, GetProperty(global_node, v8::HeapGraphEdge::kInternal, "0")); 272f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // The second reference is to an object. 273f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch CHECK_NE(NULL, GetProperty(global_node, v8::HeapGraphEdge::kInternal, "1")); 274f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch} 275f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 276f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 2773bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch// Trying to introduce a check helper for uint64_t causes many 2783bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch// overloading ambiguities, so it seems easier just to cast 2793bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch// them to a signed type. 2803bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch#define CHECK_EQ_UINT64_T(a, b) \ 2813bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch CHECK_EQ(static_cast<int64_t>(a), static_cast<int64_t>(b)) 282756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick#define CHECK_NE_UINT64_T(a, b) \ 283756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CHECK((a) != (b)) // NOLINT 2843bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 2853bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben MurdochTEST(HeapEntryIdsAndGC) { 2863bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch v8::HandleScope scope; 2873bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch LocalContext env; 2883bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 289f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch CompileRun( 2903bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch "function A() {}\n" 2913bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch "function B(x) { this.x = x; }\n" 2923bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch "var a = new A();\n" 2933bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch "var b = new B(a);"); 2943bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch const v8::HeapSnapshot* snapshot1 = 29569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::HeapProfiler::TakeSnapshot(v8_str("s1")); 2963bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 29744f0eee88ff00398ff7f715fab053374d808c90dSteve Block HEAP->CollectAllGarbage(true); // Enforce compaction. 2983bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 2993bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch const v8::HeapSnapshot* snapshot2 = 30069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::HeapProfiler::TakeSnapshot(v8_str("s2")); 3013bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 3023bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch const v8::HeapGraphNode* global1 = GetGlobalObject(snapshot1); 3033bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch const v8::HeapGraphNode* global2 = GetGlobalObject(snapshot2); 3043bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch CHECK_NE_UINT64_T(0, global1->GetId()); 3053bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch CHECK_EQ_UINT64_T(global1->GetId(), global2->GetId()); 3063bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch const v8::HeapGraphNode* A1 = 307756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick GetProperty(global1, v8::HeapGraphEdge::kProperty, "A"); 308756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CHECK_NE(NULL, A1); 3093bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch const v8::HeapGraphNode* A2 = 310756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick GetProperty(global2, v8::HeapGraphEdge::kProperty, "A"); 311756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CHECK_NE(NULL, A2); 3123bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch CHECK_NE_UINT64_T(0, A1->GetId()); 3133bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch CHECK_EQ_UINT64_T(A1->GetId(), A2->GetId()); 3143bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch const v8::HeapGraphNode* B1 = 315756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick GetProperty(global1, v8::HeapGraphEdge::kProperty, "B"); 316756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CHECK_NE(NULL, B1); 3173bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch const v8::HeapGraphNode* B2 = 318756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick GetProperty(global2, v8::HeapGraphEdge::kProperty, "B"); 319756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CHECK_NE(NULL, B2); 3203bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch CHECK_NE_UINT64_T(0, B1->GetId()); 3213bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch CHECK_EQ_UINT64_T(B1->GetId(), B2->GetId()); 3223bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch const v8::HeapGraphNode* a1 = 323756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick GetProperty(global1, v8::HeapGraphEdge::kProperty, "a"); 324756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CHECK_NE(NULL, a1); 3253bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch const v8::HeapGraphNode* a2 = 326756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick GetProperty(global2, v8::HeapGraphEdge::kProperty, "a"); 327756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CHECK_NE(NULL, a2); 3283bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch CHECK_NE_UINT64_T(0, a1->GetId()); 3293bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch CHECK_EQ_UINT64_T(a1->GetId(), a2->GetId()); 3303bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch const v8::HeapGraphNode* b1 = 331756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick GetProperty(global1, v8::HeapGraphEdge::kProperty, "b"); 332756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CHECK_NE(NULL, b1); 3333bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch const v8::HeapGraphNode* b2 = 334756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick GetProperty(global2, v8::HeapGraphEdge::kProperty, "b"); 335756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CHECK_NE(NULL, b2); 3363bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch CHECK_NE_UINT64_T(0, b1->GetId()); 3373bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch CHECK_EQ_UINT64_T(b1->GetId(), b2->GetId()); 3383bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch} 3393bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 3403bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 341f87a203d89e1bbb6708282e0b64dbd13d59b723dBen MurdochTEST(HeapSnapshotRootPreservedAfterSorting) { 342f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch v8::HandleScope scope; 343f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch LocalContext env; 344f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch const v8::HeapSnapshot* snapshot = 34569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::HeapProfiler::TakeSnapshot(v8_str("s")); 346f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch const v8::HeapGraphNode* root1 = snapshot->GetRoot(); 347f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch const_cast<i::HeapSnapshot*>(reinterpret_cast<const i::HeapSnapshot*>( 348f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch snapshot))->GetSortedEntriesList(); 349f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch const v8::HeapGraphNode* root2 = snapshot->GetRoot(); 350f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch CHECK_EQ(root1, root2); 351f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch} 352f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 353f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 3548a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) WangTEST(HeapEntryDominator) { 3558a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang // The graph looks like this: 3568a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang // 3578a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang // -> node1 3588a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang // a |^ 3598a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang // -> node5 ba 3608a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang // a v| 3618a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang // node6 -> node2 3628a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang // b a |^ 3638a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang // -> node4 ba 3648a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang // b v| 3658a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang // -> node3 3668a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang // 3678a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang // The dominator for all nodes is node6. 3688a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 3698a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang v8::HandleScope scope; 3708a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang LocalContext env; 3718a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 3728a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang CompileRun( 3738a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang "function X(a, b) { this.a = a; this.b = b; }\n" 3748a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang "node6 = new X(new X(new X()), new X(new X(),new X()));\n" 3758a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang "(function(){\n" 3768a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang "node6.a.a.b = node6.b.a; // node1 -> node2\n" 3778a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang "node6.b.a.a = node6.a.a; // node2 -> node1\n" 3788a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang "node6.b.a.b = node6.b.b; // node2 -> node3\n" 3798a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang "node6.b.b.a = node6.b.a; // node3 -> node2\n" 3808a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang "})();"); 3818a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 3828a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang const v8::HeapSnapshot* snapshot = 38369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::HeapProfiler::TakeSnapshot(v8_str("dominators")); 3848a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 3858a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang const v8::HeapGraphNode* global = GetGlobalObject(snapshot); 3868a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang CHECK_NE(NULL, global); 3878a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang const v8::HeapGraphNode* node6 = 3888a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang GetProperty(global, v8::HeapGraphEdge::kShortcut, "node6"); 3898a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang CHECK_NE(NULL, node6); 3908a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang const v8::HeapGraphNode* node5 = 3918a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang GetProperty(node6, v8::HeapGraphEdge::kProperty, "a"); 3928a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang CHECK_NE(NULL, node5); 3938a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang const v8::HeapGraphNode* node4 = 3948a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang GetProperty(node6, v8::HeapGraphEdge::kProperty, "b"); 3958a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang CHECK_NE(NULL, node4); 3968a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang const v8::HeapGraphNode* node3 = 3978a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang GetProperty(node4, v8::HeapGraphEdge::kProperty, "b"); 3988a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang CHECK_NE(NULL, node3); 3998a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang const v8::HeapGraphNode* node2 = 4008a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang GetProperty(node4, v8::HeapGraphEdge::kProperty, "a"); 4018a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang CHECK_NE(NULL, node2); 4028a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang const v8::HeapGraphNode* node1 = 4038a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang GetProperty(node5, v8::HeapGraphEdge::kProperty, "a"); 4048a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang CHECK_NE(NULL, node1); 4058a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 4068a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang CHECK_EQ(node6, node1->GetDominatorNode()); 4078a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang CHECK_EQ(node6, node2->GetDominatorNode()); 4088a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang CHECK_EQ(node6, node3->GetDominatorNode()); 4098a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang CHECK_EQ(node6, node4->GetDominatorNode()); 4108a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang CHECK_EQ(node6, node5->GetDominatorNode()); 4118a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang} 4128a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 4138a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 4140d5e116f6aee03185f237311a943491bb079a768Kristian Monsennamespace { 4150d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4160d5e116f6aee03185f237311a943491bb079a768Kristian Monsenclass TestJSONStream : public v8::OutputStream { 4170d5e116f6aee03185f237311a943491bb079a768Kristian Monsen public: 4180d5e116f6aee03185f237311a943491bb079a768Kristian Monsen TestJSONStream() : eos_signaled_(0), abort_countdown_(-1) {} 4190d5e116f6aee03185f237311a943491bb079a768Kristian Monsen explicit TestJSONStream(int abort_countdown) 4200d5e116f6aee03185f237311a943491bb079a768Kristian Monsen : eos_signaled_(0), abort_countdown_(abort_countdown) {} 4210d5e116f6aee03185f237311a943491bb079a768Kristian Monsen virtual ~TestJSONStream() {} 4220d5e116f6aee03185f237311a943491bb079a768Kristian Monsen virtual void EndOfStream() { ++eos_signaled_; } 4230d5e116f6aee03185f237311a943491bb079a768Kristian Monsen virtual WriteResult WriteAsciiChunk(char* buffer, int chars_written) { 4240d5e116f6aee03185f237311a943491bb079a768Kristian Monsen if (abort_countdown_ > 0) --abort_countdown_; 4250d5e116f6aee03185f237311a943491bb079a768Kristian Monsen if (abort_countdown_ == 0) return kAbort; 4260d5e116f6aee03185f237311a943491bb079a768Kristian Monsen CHECK_GT(chars_written, 0); 4270d5e116f6aee03185f237311a943491bb079a768Kristian Monsen i::Vector<char> chunk = buffer_.AddBlock(chars_written, '\0'); 4280d5e116f6aee03185f237311a943491bb079a768Kristian Monsen memcpy(chunk.start(), buffer, chars_written); 4290d5e116f6aee03185f237311a943491bb079a768Kristian Monsen return kContinue; 4300d5e116f6aee03185f237311a943491bb079a768Kristian Monsen } 4310d5e116f6aee03185f237311a943491bb079a768Kristian Monsen void WriteTo(i::Vector<char> dest) { buffer_.WriteTo(dest); } 4320d5e116f6aee03185f237311a943491bb079a768Kristian Monsen int eos_signaled() { return eos_signaled_; } 4330d5e116f6aee03185f237311a943491bb079a768Kristian Monsen int size() { return buffer_.size(); } 4340d5e116f6aee03185f237311a943491bb079a768Kristian Monsen private: 4350d5e116f6aee03185f237311a943491bb079a768Kristian Monsen i::Collector<char> buffer_; 4360d5e116f6aee03185f237311a943491bb079a768Kristian Monsen int eos_signaled_; 4370d5e116f6aee03185f237311a943491bb079a768Kristian Monsen int abort_countdown_; 4380d5e116f6aee03185f237311a943491bb079a768Kristian Monsen}; 4390d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4400d5e116f6aee03185f237311a943491bb079a768Kristian Monsenclass AsciiResource: public v8::String::ExternalAsciiStringResource { 4410d5e116f6aee03185f237311a943491bb079a768Kristian Monsen public: 4420d5e116f6aee03185f237311a943491bb079a768Kristian Monsen explicit AsciiResource(i::Vector<char> string): data_(string.start()) { 4430d5e116f6aee03185f237311a943491bb079a768Kristian Monsen length_ = string.length(); 4440d5e116f6aee03185f237311a943491bb079a768Kristian Monsen } 4450d5e116f6aee03185f237311a943491bb079a768Kristian Monsen virtual const char* data() const { return data_; } 4460d5e116f6aee03185f237311a943491bb079a768Kristian Monsen virtual size_t length() const { return length_; } 4470d5e116f6aee03185f237311a943491bb079a768Kristian Monsen private: 4480d5e116f6aee03185f237311a943491bb079a768Kristian Monsen const char* data_; 4490d5e116f6aee03185f237311a943491bb079a768Kristian Monsen size_t length_; 4500d5e116f6aee03185f237311a943491bb079a768Kristian Monsen}; 4510d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4520d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} // namespace 4530d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4540d5e116f6aee03185f237311a943491bb079a768Kristian MonsenTEST(HeapSnapshotJSONSerialization) { 4550d5e116f6aee03185f237311a943491bb079a768Kristian Monsen v8::HandleScope scope; 4560d5e116f6aee03185f237311a943491bb079a768Kristian Monsen LocalContext env; 4570d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4580d5e116f6aee03185f237311a943491bb079a768Kristian Monsen#define STRING_LITERAL_FOR_TEST \ 4590d5e116f6aee03185f237311a943491bb079a768Kristian Monsen "\"String \\n\\r\\u0008\\u0081\\u0101\\u0801\\u8001\"" 460f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch CompileRun( 4610d5e116f6aee03185f237311a943491bb079a768Kristian Monsen "function A(s) { this.s = s; }\n" 4620d5e116f6aee03185f237311a943491bb079a768Kristian Monsen "function B(x) { this.x = x; }\n" 4630d5e116f6aee03185f237311a943491bb079a768Kristian Monsen "var a = new A(" STRING_LITERAL_FOR_TEST ");\n" 4640d5e116f6aee03185f237311a943491bb079a768Kristian Monsen "var b = new B(a);"); 4650d5e116f6aee03185f237311a943491bb079a768Kristian Monsen const v8::HeapSnapshot* snapshot = 46669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::HeapProfiler::TakeSnapshot(v8_str("json")); 4670d5e116f6aee03185f237311a943491bb079a768Kristian Monsen TestJSONStream stream; 4680d5e116f6aee03185f237311a943491bb079a768Kristian Monsen snapshot->Serialize(&stream, v8::HeapSnapshot::kJSON); 4690d5e116f6aee03185f237311a943491bb079a768Kristian Monsen CHECK_GT(stream.size(), 0); 4700d5e116f6aee03185f237311a943491bb079a768Kristian Monsen CHECK_EQ(1, stream.eos_signaled()); 4710d5e116f6aee03185f237311a943491bb079a768Kristian Monsen i::ScopedVector<char> json(stream.size()); 4720d5e116f6aee03185f237311a943491bb079a768Kristian Monsen stream.WriteTo(json); 4730d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4740d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // Verify that snapshot string is valid JSON. 4750d5e116f6aee03185f237311a943491bb079a768Kristian Monsen AsciiResource json_res(json); 4760d5e116f6aee03185f237311a943491bb079a768Kristian Monsen v8::Local<v8::String> json_string = v8::String::NewExternal(&json_res); 47769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch env->Global()->Set(v8_str("json_snapshot"), json_string); 4780d5e116f6aee03185f237311a943491bb079a768Kristian Monsen v8::Local<v8::Value> snapshot_parse_result = CompileRun( 4790d5e116f6aee03185f237311a943491bb079a768Kristian Monsen "var parsed = JSON.parse(json_snapshot); true;"); 4800d5e116f6aee03185f237311a943491bb079a768Kristian Monsen CHECK(!snapshot_parse_result.IsEmpty()); 4810d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4820d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // Verify that snapshot object has required fields. 4830d5e116f6aee03185f237311a943491bb079a768Kristian Monsen v8::Local<v8::Object> parsed_snapshot = 48469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch env->Global()->Get(v8_str("parsed"))->ToObject(); 48569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CHECK(parsed_snapshot->Has(v8_str("snapshot"))); 48669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CHECK(parsed_snapshot->Has(v8_str("nodes"))); 48769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CHECK(parsed_snapshot->Has(v8_str("strings"))); 4880d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4890d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // Get node and edge "member" offsets. 4900d5e116f6aee03185f237311a943491bb079a768Kristian Monsen v8::Local<v8::Value> meta_analysis_result = CompileRun( 4918a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang "var parsed_meta = parsed.nodes[0];\n" 4920d5e116f6aee03185f237311a943491bb079a768Kristian Monsen "var children_count_offset =" 4930d5e116f6aee03185f237311a943491bb079a768Kristian Monsen " parsed_meta.fields.indexOf('children_count');\n" 4940d5e116f6aee03185f237311a943491bb079a768Kristian Monsen "var children_offset =" 4950d5e116f6aee03185f237311a943491bb079a768Kristian Monsen " parsed_meta.fields.indexOf('children');\n" 4960d5e116f6aee03185f237311a943491bb079a768Kristian Monsen "var children_meta =" 4970d5e116f6aee03185f237311a943491bb079a768Kristian Monsen " parsed_meta.types[children_offset];\n" 4980d5e116f6aee03185f237311a943491bb079a768Kristian Monsen "var child_fields_count = children_meta.fields.length;\n" 4990d5e116f6aee03185f237311a943491bb079a768Kristian Monsen "var child_type_offset =" 5000d5e116f6aee03185f237311a943491bb079a768Kristian Monsen " children_meta.fields.indexOf('type');\n" 5010d5e116f6aee03185f237311a943491bb079a768Kristian Monsen "var child_name_offset =" 5020d5e116f6aee03185f237311a943491bb079a768Kristian Monsen " children_meta.fields.indexOf('name_or_index');\n" 5030d5e116f6aee03185f237311a943491bb079a768Kristian Monsen "var child_to_node_offset =" 5040d5e116f6aee03185f237311a943491bb079a768Kristian Monsen " children_meta.fields.indexOf('to_node');\n" 5050d5e116f6aee03185f237311a943491bb079a768Kristian Monsen "var property_type =" 5068a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang " children_meta.types[child_type_offset].indexOf('property');\n" 5078a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang "var shortcut_type =" 5088a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang " children_meta.types[child_type_offset].indexOf('shortcut');"); 5090d5e116f6aee03185f237311a943491bb079a768Kristian Monsen CHECK(!meta_analysis_result.IsEmpty()); 5100d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5110d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // A helper function for processing encoded nodes. 5120d5e116f6aee03185f237311a943491bb079a768Kristian Monsen CompileRun( 5138a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang "function GetChildPosByProperty(pos, prop_name, prop_type) {\n" 5140d5e116f6aee03185f237311a943491bb079a768Kristian Monsen " var nodes = parsed.nodes;\n" 5150d5e116f6aee03185f237311a943491bb079a768Kristian Monsen " var strings = parsed.strings;\n" 5160d5e116f6aee03185f237311a943491bb079a768Kristian Monsen " for (var i = 0,\n" 5170d5e116f6aee03185f237311a943491bb079a768Kristian Monsen " count = nodes[pos + children_count_offset] * child_fields_count;\n" 5180d5e116f6aee03185f237311a943491bb079a768Kristian Monsen " i < count; i += child_fields_count) {\n" 5190d5e116f6aee03185f237311a943491bb079a768Kristian Monsen " var child_pos = pos + children_offset + i;\n" 5208a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang " if (nodes[child_pos + child_type_offset] === prop_type\n" 5210d5e116f6aee03185f237311a943491bb079a768Kristian Monsen " && strings[nodes[child_pos + child_name_offset]] === prop_name)\n" 5220d5e116f6aee03185f237311a943491bb079a768Kristian Monsen " return nodes[child_pos + child_to_node_offset];\n" 5230d5e116f6aee03185f237311a943491bb079a768Kristian Monsen " }\n" 5240d5e116f6aee03185f237311a943491bb079a768Kristian Monsen " return null;\n" 5250d5e116f6aee03185f237311a943491bb079a768Kristian Monsen "}\n"); 5260d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // Get the string index using the path: <root> -> <global>.b.x.s 5270d5e116f6aee03185f237311a943491bb079a768Kristian Monsen v8::Local<v8::Value> string_obj_pos_val = CompileRun( 5280d5e116f6aee03185f237311a943491bb079a768Kristian Monsen "GetChildPosByProperty(\n" 5290d5e116f6aee03185f237311a943491bb079a768Kristian Monsen " GetChildPosByProperty(\n" 5300d5e116f6aee03185f237311a943491bb079a768Kristian Monsen " GetChildPosByProperty(" 5318a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang " parsed.nodes[1 + children_offset + child_to_node_offset]," 5328a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang " \"b\",shortcut_type),\n" 5338a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang " \"x\", property_type)," 5348a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang " \"s\", property_type)"); 5350d5e116f6aee03185f237311a943491bb079a768Kristian Monsen CHECK(!string_obj_pos_val.IsEmpty()); 5360d5e116f6aee03185f237311a943491bb079a768Kristian Monsen int string_obj_pos = 5370d5e116f6aee03185f237311a943491bb079a768Kristian Monsen static_cast<int>(string_obj_pos_val->ToNumber()->Value()); 5380d5e116f6aee03185f237311a943491bb079a768Kristian Monsen v8::Local<v8::Object> nodes_array = 53969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch parsed_snapshot->Get(v8_str("nodes"))->ToObject(); 5400d5e116f6aee03185f237311a943491bb079a768Kristian Monsen int string_index = static_cast<int>( 5410d5e116f6aee03185f237311a943491bb079a768Kristian Monsen nodes_array->Get(string_obj_pos + 1)->ToNumber()->Value()); 5420d5e116f6aee03185f237311a943491bb079a768Kristian Monsen CHECK_GT(string_index, 0); 5430d5e116f6aee03185f237311a943491bb079a768Kristian Monsen v8::Local<v8::Object> strings_array = 54469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch parsed_snapshot->Get(v8_str("strings"))->ToObject(); 5450d5e116f6aee03185f237311a943491bb079a768Kristian Monsen v8::Local<v8::String> string = strings_array->Get(string_index)->ToString(); 5460d5e116f6aee03185f237311a943491bb079a768Kristian Monsen v8::Local<v8::String> ref_string = 5470d5e116f6aee03185f237311a943491bb079a768Kristian Monsen CompileRun(STRING_LITERAL_FOR_TEST)->ToString(); 5480d5e116f6aee03185f237311a943491bb079a768Kristian Monsen#undef STRING_LITERAL_FOR_TEST 5490d5e116f6aee03185f237311a943491bb079a768Kristian Monsen CHECK_EQ(*v8::String::Utf8Value(ref_string), 5500d5e116f6aee03185f237311a943491bb079a768Kristian Monsen *v8::String::Utf8Value(string)); 5510d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 5520d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5530d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5540d5e116f6aee03185f237311a943491bb079a768Kristian MonsenTEST(HeapSnapshotJSONSerializationAborting) { 5550d5e116f6aee03185f237311a943491bb079a768Kristian Monsen v8::HandleScope scope; 5560d5e116f6aee03185f237311a943491bb079a768Kristian Monsen LocalContext env; 5570d5e116f6aee03185f237311a943491bb079a768Kristian Monsen const v8::HeapSnapshot* snapshot = 55869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::HeapProfiler::TakeSnapshot(v8_str("abort")); 5590d5e116f6aee03185f237311a943491bb079a768Kristian Monsen TestJSONStream stream(5); 5600d5e116f6aee03185f237311a943491bb079a768Kristian Monsen snapshot->Serialize(&stream, v8::HeapSnapshot::kJSON); 5610d5e116f6aee03185f237311a943491bb079a768Kristian Monsen CHECK_GT(stream.size(), 0); 5620d5e116f6aee03185f237311a943491bb079a768Kristian Monsen CHECK_EQ(0, stream.eos_signaled()); 5630d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 5640d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5658a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 566b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochTEST(HeapSnapshotGetNodeById) { 567b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::HandleScope scope; 568b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch LocalContext env; 569b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 570b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const v8::HeapSnapshot* snapshot = 57169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::HeapProfiler::TakeSnapshot(v8_str("id")); 572b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const v8::HeapGraphNode* root = snapshot->GetRoot(); 573b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(root, snapshot->GetNodeById(root->GetId())); 574b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0, count = root->GetChildrenCount(); i < count; ++i) { 575b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const v8::HeapGraphEdge* prop = root->GetChild(i); 576b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ( 577b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch prop->GetToNode(), snapshot->GetNodeById(prop->GetToNode()->GetId())); 578b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 579b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Check a big id, which should not exist yet. 580b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(NULL, snapshot->GetNodeById(0x1000000UL)); 581b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 582b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 583b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 584b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochnamespace { 585b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 586b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass TestActivityControl : public v8::ActivityControl { 587b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 588b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch explicit TestActivityControl(int abort_count) 589b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch : done_(0), total_(0), abort_count_(abort_count) {} 590b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ControlOption ReportProgressValue(int done, int total) { 591b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch done_ = done; 592b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch total_ = total; 593b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return --abort_count_ != 0 ? kContinue : kAbort; 594b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 595b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int done() { return done_; } 596b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int total() { return total_; } 597b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 598b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private: 599b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int done_; 600b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int total_; 601b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int abort_count_; 602b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 603b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 604b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 605b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochTEST(TakeHeapSnapshotAborting) { 606b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::HandleScope scope; 607b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch LocalContext env; 608b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 609b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const int snapshots_count = v8::HeapProfiler::GetSnapshotsCount(); 610b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch TestActivityControl aborting_control(3); 611b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const v8::HeapSnapshot* no_snapshot = 61269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::HeapProfiler::TakeSnapshot(v8_str("abort"), 613b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::HeapSnapshot::kFull, 614b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch &aborting_control); 615b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(NULL, no_snapshot); 616b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(snapshots_count, v8::HeapProfiler::GetSnapshotsCount()); 617b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_GT(aborting_control.total(), aborting_control.done()); 618b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 619b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch TestActivityControl control(-1); // Don't abort. 620b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const v8::HeapSnapshot* snapshot = 62169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::HeapProfiler::TakeSnapshot(v8_str("full"), 622b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::HeapSnapshot::kFull, 623b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch &control); 624b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_NE(NULL, snapshot); 625b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(snapshots_count + 1, v8::HeapProfiler::GetSnapshotsCount()); 626b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(control.total(), control.done()); 627b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_GT(control.total(), 0); 628b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 629b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 63044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 63144f0eee88ff00398ff7f715fab053374d808c90dSteve Blocknamespace { 63244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 63344f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass TestRetainedObjectInfo : public v8::RetainedObjectInfo { 63444f0eee88ff00398ff7f715fab053374d808c90dSteve Block public: 63544f0eee88ff00398ff7f715fab053374d808c90dSteve Block TestRetainedObjectInfo(int hash, 63644f0eee88ff00398ff7f715fab053374d808c90dSteve Block const char* label, 63744f0eee88ff00398ff7f715fab053374d808c90dSteve Block intptr_t element_count = -1, 63844f0eee88ff00398ff7f715fab053374d808c90dSteve Block intptr_t size = -1) 63944f0eee88ff00398ff7f715fab053374d808c90dSteve Block : disposed_(false), 64044f0eee88ff00398ff7f715fab053374d808c90dSteve Block hash_(hash), 64144f0eee88ff00398ff7f715fab053374d808c90dSteve Block label_(label), 64244f0eee88ff00398ff7f715fab053374d808c90dSteve Block element_count_(element_count), 64344f0eee88ff00398ff7f715fab053374d808c90dSteve Block size_(size) { 64444f0eee88ff00398ff7f715fab053374d808c90dSteve Block instances.Add(this); 64544f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 64644f0eee88ff00398ff7f715fab053374d808c90dSteve Block virtual ~TestRetainedObjectInfo() {} 64744f0eee88ff00398ff7f715fab053374d808c90dSteve Block virtual void Dispose() { 64844f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK(!disposed_); 64944f0eee88ff00398ff7f715fab053374d808c90dSteve Block disposed_ = true; 65044f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 65144f0eee88ff00398ff7f715fab053374d808c90dSteve Block virtual bool IsEquivalent(RetainedObjectInfo* other) { 65244f0eee88ff00398ff7f715fab053374d808c90dSteve Block return GetHash() == other->GetHash(); 65344f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 65444f0eee88ff00398ff7f715fab053374d808c90dSteve Block virtual intptr_t GetHash() { return hash_; } 65544f0eee88ff00398ff7f715fab053374d808c90dSteve Block virtual const char* GetLabel() { return label_; } 65644f0eee88ff00398ff7f715fab053374d808c90dSteve Block virtual intptr_t GetElementCount() { return element_count_; } 65744f0eee88ff00398ff7f715fab053374d808c90dSteve Block virtual intptr_t GetSizeInBytes() { return size_; } 65844f0eee88ff00398ff7f715fab053374d808c90dSteve Block bool disposed() { return disposed_; } 65944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 66044f0eee88ff00398ff7f715fab053374d808c90dSteve Block static v8::RetainedObjectInfo* WrapperInfoCallback( 66144f0eee88ff00398ff7f715fab053374d808c90dSteve Block uint16_t class_id, v8::Handle<v8::Value> wrapper) { 66244f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (class_id == 1) { 66344f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (wrapper->IsString()) { 66444f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::String::AsciiValue ascii(wrapper); 66544f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (strcmp(*ascii, "AAA") == 0) 66644f0eee88ff00398ff7f715fab053374d808c90dSteve Block return new TestRetainedObjectInfo(1, "aaa", 100); 66744f0eee88ff00398ff7f715fab053374d808c90dSteve Block else if (strcmp(*ascii, "BBB") == 0) 66844f0eee88ff00398ff7f715fab053374d808c90dSteve Block return new TestRetainedObjectInfo(1, "aaa", 100); 66944f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 67044f0eee88ff00398ff7f715fab053374d808c90dSteve Block } else if (class_id == 2) { 67144f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (wrapper->IsString()) { 67244f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::String::AsciiValue ascii(wrapper); 67344f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (strcmp(*ascii, "CCC") == 0) 67444f0eee88ff00398ff7f715fab053374d808c90dSteve Block return new TestRetainedObjectInfo(2, "ccc"); 67544f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 67644f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 67744f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK(false); 67844f0eee88ff00398ff7f715fab053374d808c90dSteve Block return NULL; 67944f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 68044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 68144f0eee88ff00398ff7f715fab053374d808c90dSteve Block static i::List<TestRetainedObjectInfo*> instances; 68244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 68344f0eee88ff00398ff7f715fab053374d808c90dSteve Block private: 68444f0eee88ff00398ff7f715fab053374d808c90dSteve Block bool disposed_; 68544f0eee88ff00398ff7f715fab053374d808c90dSteve Block int category_; 68644f0eee88ff00398ff7f715fab053374d808c90dSteve Block int hash_; 68744f0eee88ff00398ff7f715fab053374d808c90dSteve Block const char* label_; 68844f0eee88ff00398ff7f715fab053374d808c90dSteve Block intptr_t element_count_; 68944f0eee88ff00398ff7f715fab053374d808c90dSteve Block intptr_t size_; 69044f0eee88ff00398ff7f715fab053374d808c90dSteve Block}; 69144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 69244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 69344f0eee88ff00398ff7f715fab053374d808c90dSteve Blocki::List<TestRetainedObjectInfo*> TestRetainedObjectInfo::instances; 69444f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 69544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 69644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 69744f0eee88ff00398ff7f715fab053374d808c90dSteve Blockstatic const v8::HeapGraphNode* GetNode(const v8::HeapGraphNode* parent, 69844f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::HeapGraphNode::Type type, 69944f0eee88ff00398ff7f715fab053374d808c90dSteve Block const char* name) { 70044f0eee88ff00398ff7f715fab053374d808c90dSteve Block for (int i = 0, count = parent->GetChildrenCount(); i < count; ++i) { 70144f0eee88ff00398ff7f715fab053374d808c90dSteve Block const v8::HeapGraphNode* node = parent->GetChild(i)->GetToNode(); 70244f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (node->GetType() == type && strcmp(name, 70344f0eee88ff00398ff7f715fab053374d808c90dSteve Block const_cast<i::HeapEntry*>( 70444f0eee88ff00398ff7f715fab053374d808c90dSteve Block reinterpret_cast<const i::HeapEntry*>(node))->name()) == 0) { 70544f0eee88ff00398ff7f715fab053374d808c90dSteve Block return node; 70644f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 70744f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 70844f0eee88ff00398ff7f715fab053374d808c90dSteve Block return NULL; 70944f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 71044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 71144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 71244f0eee88ff00398ff7f715fab053374d808c90dSteve BlockTEST(HeapSnapshotRetainedObjectInfo) { 71344f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::HandleScope scope; 71444f0eee88ff00398ff7f715fab053374d808c90dSteve Block LocalContext env; 71544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 71644f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::HeapProfiler::DefineWrapperClass( 71744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 1, TestRetainedObjectInfo::WrapperInfoCallback); 71844f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::HeapProfiler::DefineWrapperClass( 71944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 2, TestRetainedObjectInfo::WrapperInfoCallback); 72044f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::Persistent<v8::String> p_AAA = 72144f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::Persistent<v8::String>::New(v8_str("AAA")); 72244f0eee88ff00398ff7f715fab053374d808c90dSteve Block p_AAA.SetWrapperClassId(1); 72344f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::Persistent<v8::String> p_BBB = 72444f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::Persistent<v8::String>::New(v8_str("BBB")); 72544f0eee88ff00398ff7f715fab053374d808c90dSteve Block p_BBB.SetWrapperClassId(1); 72644f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::Persistent<v8::String> p_CCC = 72744f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::Persistent<v8::String>::New(v8_str("CCC")); 72844f0eee88ff00398ff7f715fab053374d808c90dSteve Block p_CCC.SetWrapperClassId(2); 72944f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(0, TestRetainedObjectInfo::instances.length()); 73044f0eee88ff00398ff7f715fab053374d808c90dSteve Block const v8::HeapSnapshot* snapshot = 73169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::HeapProfiler::TakeSnapshot(v8_str("retained")); 73244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 73344f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(3, TestRetainedObjectInfo::instances.length()); 73444f0eee88ff00398ff7f715fab053374d808c90dSteve Block for (int i = 0; i < TestRetainedObjectInfo::instances.length(); ++i) { 73544f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK(TestRetainedObjectInfo::instances[i]->disposed()); 73644f0eee88ff00398ff7f715fab053374d808c90dSteve Block delete TestRetainedObjectInfo::instances[i]; 73744f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 73844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 73944f0eee88ff00398ff7f715fab053374d808c90dSteve Block const v8::HeapGraphNode* natives = GetNode( 74044f0eee88ff00398ff7f715fab053374d808c90dSteve Block snapshot->GetRoot(), v8::HeapGraphNode::kObject, "(Native objects)"); 74144f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_NE(NULL, natives); 74244f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(2, natives->GetChildrenCount()); 74344f0eee88ff00398ff7f715fab053374d808c90dSteve Block const v8::HeapGraphNode* aaa = GetNode( 74444f0eee88ff00398ff7f715fab053374d808c90dSteve Block natives, v8::HeapGraphNode::kNative, "aaa / 100 entries"); 74544f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_NE(NULL, aaa); 74644f0eee88ff00398ff7f715fab053374d808c90dSteve Block const v8::HeapGraphNode* ccc = GetNode( 74744f0eee88ff00398ff7f715fab053374d808c90dSteve Block natives, v8::HeapGraphNode::kNative, "ccc"); 74844f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_NE(NULL, ccc); 74944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 75044f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(2, aaa->GetChildrenCount()); 75144f0eee88ff00398ff7f715fab053374d808c90dSteve Block const v8::HeapGraphNode* n_AAA = GetNode( 75244f0eee88ff00398ff7f715fab053374d808c90dSteve Block aaa, v8::HeapGraphNode::kString, "AAA"); 75344f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_NE(NULL, n_AAA); 75444f0eee88ff00398ff7f715fab053374d808c90dSteve Block const v8::HeapGraphNode* n_BBB = GetNode( 75544f0eee88ff00398ff7f715fab053374d808c90dSteve Block aaa, v8::HeapGraphNode::kString, "BBB"); 75644f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_NE(NULL, n_BBB); 75744f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(1, ccc->GetChildrenCount()); 75844f0eee88ff00398ff7f715fab053374d808c90dSteve Block const v8::HeapGraphNode* n_CCC = GetNode( 75944f0eee88ff00398ff7f715fab053374d808c90dSteve Block ccc, v8::HeapGraphNode::kString, "CCC"); 76044f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_NE(NULL, n_CCC); 76144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 7628b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch CHECK_EQ(aaa, GetProperty(n_AAA, v8::HeapGraphEdge::kInternal, "native")); 7638b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch CHECK_EQ(aaa, GetProperty(n_BBB, v8::HeapGraphEdge::kInternal, "native")); 7648b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch CHECK_EQ(ccc, GetProperty(n_CCC, v8::HeapGraphEdge::kInternal, "native")); 76544f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 76644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 76744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 76844f0eee88ff00398ff7f715fab053374d808c90dSteve BlockTEST(DeleteAllHeapSnapshots) { 76944f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::HandleScope scope; 77044f0eee88ff00398ff7f715fab053374d808c90dSteve Block LocalContext env; 77144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 77244f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(0, v8::HeapProfiler::GetSnapshotsCount()); 77344f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::HeapProfiler::DeleteAllSnapshots(); 77444f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(0, v8::HeapProfiler::GetSnapshotsCount()); 77569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CHECK_NE(NULL, v8::HeapProfiler::TakeSnapshot(v8_str("1"))); 77644f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(1, v8::HeapProfiler::GetSnapshotsCount()); 77744f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::HeapProfiler::DeleteAllSnapshots(); 77844f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(0, v8::HeapProfiler::GetSnapshotsCount()); 77969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CHECK_NE(NULL, v8::HeapProfiler::TakeSnapshot(v8_str("1"))); 78069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CHECK_NE(NULL, v8::HeapProfiler::TakeSnapshot(v8_str("2"))); 78144f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(2, v8::HeapProfiler::GetSnapshotsCount()); 78244f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::HeapProfiler::DeleteAllSnapshots(); 78344f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(0, v8::HeapProfiler::GetSnapshotsCount()); 78444f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 78544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 78644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 78744f0eee88ff00398ff7f715fab053374d808c90dSteve BlockTEST(DeleteHeapSnapshot) { 78844f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::HandleScope scope; 78944f0eee88ff00398ff7f715fab053374d808c90dSteve Block LocalContext env; 79044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 79144f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(0, v8::HeapProfiler::GetSnapshotsCount()); 79244f0eee88ff00398ff7f715fab053374d808c90dSteve Block const v8::HeapSnapshot* s1 = 79369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::HeapProfiler::TakeSnapshot(v8_str("1")); 79444f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_NE(NULL, s1); 79544f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(1, v8::HeapProfiler::GetSnapshotsCount()); 79644f0eee88ff00398ff7f715fab053374d808c90dSteve Block unsigned uid1 = s1->GetUid(); 79744f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(s1, v8::HeapProfiler::FindSnapshot(uid1)); 79844f0eee88ff00398ff7f715fab053374d808c90dSteve Block const_cast<v8::HeapSnapshot*>(s1)->Delete(); 79944f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(0, v8::HeapProfiler::GetSnapshotsCount()); 80044f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(NULL, v8::HeapProfiler::FindSnapshot(uid1)); 80144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 80244f0eee88ff00398ff7f715fab053374d808c90dSteve Block const v8::HeapSnapshot* s2 = 80369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::HeapProfiler::TakeSnapshot(v8_str("2")); 80444f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_NE(NULL, s2); 80544f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(1, v8::HeapProfiler::GetSnapshotsCount()); 80644f0eee88ff00398ff7f715fab053374d808c90dSteve Block unsigned uid2 = s2->GetUid(); 80744f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_NE(static_cast<int>(uid1), static_cast<int>(uid2)); 80844f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(s2, v8::HeapProfiler::FindSnapshot(uid2)); 80944f0eee88ff00398ff7f715fab053374d808c90dSteve Block const v8::HeapSnapshot* s3 = 81069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::HeapProfiler::TakeSnapshot(v8_str("3")); 81144f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_NE(NULL, s3); 81244f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(2, v8::HeapProfiler::GetSnapshotsCount()); 81344f0eee88ff00398ff7f715fab053374d808c90dSteve Block unsigned uid3 = s3->GetUid(); 81444f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_NE(static_cast<int>(uid1), static_cast<int>(uid3)); 81544f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(s3, v8::HeapProfiler::FindSnapshot(uid3)); 81644f0eee88ff00398ff7f715fab053374d808c90dSteve Block const_cast<v8::HeapSnapshot*>(s2)->Delete(); 81744f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(1, v8::HeapProfiler::GetSnapshotsCount()); 81844f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(NULL, v8::HeapProfiler::FindSnapshot(uid2)); 81944f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(s3, v8::HeapProfiler::FindSnapshot(uid3)); 82044f0eee88ff00398ff7f715fab053374d808c90dSteve Block const_cast<v8::HeapSnapshot*>(s3)->Delete(); 82144f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(0, v8::HeapProfiler::GetSnapshotsCount()); 82244f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(NULL, v8::HeapProfiler::FindSnapshot(uid3)); 82344f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 82444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 8253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 8263fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochTEST(DocumentURL) { 8273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch v8::HandleScope scope; 8283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch LocalContext env; 8293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 8303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CompileRun("document = { URL:\"abcdefgh\" };"); 8313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 8323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const v8::HeapSnapshot* snapshot = 83369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::HeapProfiler::TakeSnapshot(v8_str("document")); 8343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const v8::HeapGraphNode* global = GetGlobalObject(snapshot); 8353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CHECK_NE(NULL, global); 8363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CHECK_EQ("Object / abcdefgh", 8373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const_cast<i::HeapEntry*>( 8383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch reinterpret_cast<const i::HeapEntry*>(global))->name()); 8393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 8403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 8413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 8423fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochTEST(DocumentWithException) { 8433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch v8::HandleScope scope; 8443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch LocalContext env; 8453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 8463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CompileRun( 8473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "this.__defineGetter__(\"document\", function() { throw new Error(); })"); 8483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const v8::HeapSnapshot* snapshot = 84969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::HeapProfiler::TakeSnapshot(v8_str("document")); 8503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const v8::HeapGraphNode* global = GetGlobalObject(snapshot); 8513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CHECK_NE(NULL, global); 8523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CHECK_EQ("Object", 8533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const_cast<i::HeapEntry*>( 8543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch reinterpret_cast<const i::HeapEntry*>(global))->name()); 8553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 8563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 8573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 8583fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochTEST(DocumentURLWithException) { 8593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch v8::HandleScope scope; 8603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch LocalContext env; 8613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 8623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CompileRun( 8633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "function URLWithException() {}\n" 8643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "URLWithException.prototype = { get URL() { throw new Error(); } };\n" 8653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "document = { URL: new URLWithException() };"); 8663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const v8::HeapSnapshot* snapshot = 86769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::HeapProfiler::TakeSnapshot(v8_str("document")); 8683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const v8::HeapGraphNode* global = GetGlobalObject(snapshot); 8693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CHECK_NE(NULL, global); 8703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CHECK_EQ("Object", 8713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const_cast<i::HeapEntry*>( 8723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch reinterpret_cast<const i::HeapEntry*>(global))->name()); 8733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 8743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 8753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 8763fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochTEST(NodesIteration) { 8773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch v8::HandleScope scope; 8783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch LocalContext env; 8793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const v8::HeapSnapshot* snapshot = 88069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::HeapProfiler::TakeSnapshot(v8_str("iteration")); 8813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const v8::HeapGraphNode* global = GetGlobalObject(snapshot); 8823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CHECK_NE(NULL, global); 8833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Verify that we can find this object by iteration. 8843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const int nodes_count = snapshot->GetNodesCount(); 8853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int count = 0; 8863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for (int i = 0; i < nodes_count; ++i) { 8873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (snapshot->GetNode(i) == global) 8883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ++count; 8893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 8903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CHECK_EQ(1, count); 8913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 89269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 89369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 89469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochTEST(GetHeapValue) { 89569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::HandleScope scope; 89669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch LocalContext env; 89769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 89869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CompileRun("a = { s_prop: \'value\', n_prop: 0.1 };"); 89969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch const v8::HeapSnapshot* snapshot = 90069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::HeapProfiler::TakeSnapshot(v8_str("value")); 90169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch const v8::HeapGraphNode* global = GetGlobalObject(snapshot); 90269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CHECK(global->GetHeapValue()->IsObject()); 90369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::Local<v8::Object> js_global = 90469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch env->Global()->GetPrototype().As<v8::Object>(); 90569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CHECK(js_global == global->GetHeapValue()); 90669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch const v8::HeapGraphNode* obj = GetProperty( 90769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch global, v8::HeapGraphEdge::kShortcut, "a"); 90869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CHECK(obj->GetHeapValue()->IsObject()); 90969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::Local<v8::Object> js_obj = js_global->Get(v8_str("a")).As<v8::Object>(); 91069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CHECK(js_obj == obj->GetHeapValue()); 91169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch const v8::HeapGraphNode* s_prop = 91269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch GetProperty(obj, v8::HeapGraphEdge::kProperty, "s_prop"); 91369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::Local<v8::String> js_s_prop = 91469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch js_obj->Get(v8_str("s_prop")).As<v8::String>(); 91569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CHECK(js_s_prop == s_prop->GetHeapValue()); 91669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch const v8::HeapGraphNode* n_prop = 91769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch GetProperty(obj, v8::HeapGraphEdge::kProperty, "n_prop"); 91869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::Local<v8::Number> js_n_prop = 91969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch js_obj->Get(v8_str("n_prop")).As<v8::Number>(); 92069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CHECK(js_n_prop == n_prop->GetHeapValue()); 92169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch} 92269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 92369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 92469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochTEST(GetHeapValueForDeletedObject) { 92569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::HandleScope scope; 92669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch LocalContext env; 92769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 92869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // It is impossible to delete a global property, so we are about to delete a 92969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // property of the "a" object. Also, the "p" object can't be an empty one 93069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // because the empty object is static and isn't actually deleted. 93169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CompileRun("a = { p: { r: {} } };"); 93269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch const v8::HeapSnapshot* snapshot = 93369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::HeapProfiler::TakeSnapshot(v8_str("snapshot")); 93469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch const v8::HeapGraphNode* global = GetGlobalObject(snapshot); 93569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch const v8::HeapGraphNode* obj = GetProperty( 93669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch global, v8::HeapGraphEdge::kShortcut, "a"); 93769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch const v8::HeapGraphNode* prop = GetProperty( 93869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch obj, v8::HeapGraphEdge::kProperty, "p"); 93969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch { 94069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Perform the check inside a nested local scope to avoid creating a 94169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // reference to the object we are deleting. 94269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::HandleScope scope; 94369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CHECK(prop->GetHeapValue()->IsObject()); 94469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 94569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CompileRun("delete a.p;"); 94669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CHECK(prop->GetHeapValue()->IsUndefined()); 94769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch} 94869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 94969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 95069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochstatic int StringCmp(const char* ref, i::String* act) { 95169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch i::SmartPointer<char> s_act = act->ToCString(); 95269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch int result = strcmp(ref, *s_act); 95369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (result != 0) 95469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch fprintf(stderr, "Expected: \"%s\", Actual: \"%s\"\n", ref, *s_act); 95569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return result; 95669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch} 95769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 95869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 95969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochTEST(GetConstructorName) { 96069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::HandleScope scope; 96169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch LocalContext env; 96269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 96369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CompileRun( 96469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch "function Constructor1() {};\n" 96569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch "var obj1 = new Constructor1();\n" 96669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch "var Constructor2 = function() {};\n" 96769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch "var obj2 = new Constructor2();\n" 96869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch "var obj3 = {};\n" 96969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch "obj3.constructor = function Constructor3() {};\n" 97069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch "var obj4 = {};\n" 97169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch "// Slow properties\n" 97269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch "for (var i=0; i<2000; ++i) obj4[\"p\" + i] = i;\n" 97369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch "obj4.constructor = function Constructor4() {};\n" 97469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch "var obj5 = {};\n" 97569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch "var obj6 = {};\n" 97669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch "obj6.constructor = 6;"); 97769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::Local<v8::Object> js_global = 97869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch env->Global()->GetPrototype().As<v8::Object>(); 97969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::Local<v8::Object> obj1 = js_global->Get(v8_str("obj1")).As<v8::Object>(); 98069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch i::Handle<i::JSObject> js_obj1 = v8::Utils::OpenHandle(*obj1); 98169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CHECK_EQ(0, StringCmp( 98269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch "Constructor1", i::V8HeapExplorer::GetConstructorName(*js_obj1))); 98369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::Local<v8::Object> obj2 = js_global->Get(v8_str("obj2")).As<v8::Object>(); 98469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch i::Handle<i::JSObject> js_obj2 = v8::Utils::OpenHandle(*obj2); 98569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CHECK_EQ(0, StringCmp( 98669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch "Constructor2", i::V8HeapExplorer::GetConstructorName(*js_obj2))); 98769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::Local<v8::Object> obj3 = js_global->Get(v8_str("obj3")).As<v8::Object>(); 98869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch i::Handle<i::JSObject> js_obj3 = v8::Utils::OpenHandle(*obj3); 98969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CHECK_EQ(0, StringCmp( 99069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch "Constructor3", i::V8HeapExplorer::GetConstructorName(*js_obj3))); 99169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::Local<v8::Object> obj4 = js_global->Get(v8_str("obj4")).As<v8::Object>(); 99269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch i::Handle<i::JSObject> js_obj4 = v8::Utils::OpenHandle(*obj4); 99369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CHECK_EQ(0, StringCmp( 99469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch "Constructor4", i::V8HeapExplorer::GetConstructorName(*js_obj4))); 99569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::Local<v8::Object> obj5 = js_global->Get(v8_str("obj5")).As<v8::Object>(); 99669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch i::Handle<i::JSObject> js_obj5 = v8::Utils::OpenHandle(*obj5); 99769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CHECK_EQ(0, StringCmp( 99869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch "Object", i::V8HeapExplorer::GetConstructorName(*js_obj5))); 99969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::Local<v8::Object> obj6 = js_global->Get(v8_str("obj6")).As<v8::Object>(); 100069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch i::Handle<i::JSObject> js_obj6 = v8::Utils::OpenHandle(*obj6); 100169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CHECK_EQ(0, StringCmp( 100269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch "Object", i::V8HeapExplorer::GetConstructorName(*js_obj6))); 100369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch} 1004