1257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Copyright 2011 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Redistribution and use in source and binary forms, with or without 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// modification, are permitted provided that the following conditions are 4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// met: 5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// * Redistributions of source code must retain the above copyright 7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// notice, this list of conditions and the following disclaimer. 8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// * Redistributions in binary form must reproduce the above 9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// copyright notice, this list of conditions and the following 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// disclaimer in the documentation and/or other materials provided 11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// with the distribution. 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// * Neither the name of Google Inc. nor the names of its 13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// contributors may be used to endorse or promote products derived 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// from this software without specific prior written permission. 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Tests for heap profiler 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <ctype.h> 31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/v8.h" 33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "include/v8-profiler.h" 35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/allocation-tracker.h" 36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/debug.h" 37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/hashmap.h" 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/heap-profiler.h" 39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/snapshot.h" 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/utils-inl.h" 41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "test/cctest/cctest.h" 42257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochusing i::AllocationTraceNode; 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochusing i::AllocationTraceTree; 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochusing i::AllocationTracker; 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochusing i::HashMap; 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochusing i::Vector; 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 499dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsennamespace { 509dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 519dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenclass NamedEntriesDetector { 529dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen public: 539dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen NamedEntriesDetector() 5490bac256d9f48d4ee52d0e08bf0e5cad57b3c51cRussell Brenner : has_A2(false), has_B2(false), has_C2(false) { 559dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen } 569dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void CheckEntry(i::HeapEntry* entry) { 583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (strcmp(entry->name(), "A2") == 0) has_A2 = true; 593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (strcmp(entry->name(), "B2") == 0) has_B2 = true; 603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (strcmp(entry->name(), "C2") == 0) has_C2 = true; 61756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 62756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static bool AddressesMatch(void* key1, void* key2) { 64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return key1 == key2; 65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void CheckAllReachables(i::HeapEntry* root) { 68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch i::HashMap visited(AddressesMatch); 693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch i::List<i::HeapEntry*> list(10); 703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch list.Add(root); 713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CheckEntry(root); 723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch while (!list.is_empty()) { 733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch i::HeapEntry* entry = list.RemoveLast(); 74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch i::Vector<i::HeapGraphEdge*> children = entry->children(); 753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < children.length(); ++i) { 76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (children[i]->type() == i::HeapGraphEdge::kShortcut) continue; 77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch i::HeapEntry* child = children[i]->to(); 78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch i::HashMap::Entry* entry = visited.Lookup( 79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<void*>(child), 80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<uint32_t>(reinterpret_cast<uintptr_t>(child)), 81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch true); 82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (entry->value) 83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch continue; 84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entry->value = reinterpret_cast<void*>(1); 85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch list.Add(child); 86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CheckEntry(child); 873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 899dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen } 909dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 919dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen bool has_A2; 929dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen bool has_B2; 939dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen bool has_C2; 949dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen}; 959dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 969dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen} // namespace 979dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 989dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 999dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenstatic const v8::HeapGraphNode* GetGlobalObject( 1009dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen const v8::HeapSnapshot* snapshot) { 1018a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang CHECK_EQ(2, snapshot->GetRoot()->GetChildrenCount()); 102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The 0th-child is (GC Roots), 1st is the user root. 1038a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang const v8::HeapGraphNode* global_obj = 104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch snapshot->GetRoot()->GetChild(1)->GetToNode(); 1053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CHECK_EQ(0, strncmp("Object", const_cast<i::HeapEntry*>( 1063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch reinterpret_cast<const i::HeapEntry*>(global_obj))->name(), 6)); 1078a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang return global_obj; 1089dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen} 1099dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 1109dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 1119dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenstatic const v8::HeapGraphNode* GetProperty(const v8::HeapGraphNode* node, 1129dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen v8::HeapGraphEdge::Type type, 1139dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen const char* name) { 1149dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen for (int i = 0, count = node->GetChildrenCount(); i < count; ++i) { 1159dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen const v8::HeapGraphEdge* prop = node->GetChild(i); 116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::Utf8Value prop_name(prop->GetName()); 1179dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen if (prop->GetType() == type && strcmp(name, *prop_name) == 0) 1189dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen return prop->GetToNode(); 1199dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen } 1209dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen return NULL; 1219dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen} 1229dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 1239dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 1249dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenstatic bool HasString(const v8::HeapGraphNode* node, const char* contents) { 1259dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen for (int i = 0, count = node->GetChildrenCount(); i < count; ++i) { 1269dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen const v8::HeapGraphEdge* prop = node->GetChild(i); 1279dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen const v8::HeapGraphNode* node = prop->GetToNode(); 128756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick if (node->GetType() == v8::HeapGraphNode::kString) { 129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::Utf8Value node_name(node->GetName()); 1309dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen if (strcmp(contents, *node_name) == 0) return true; 1319dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen } 1329dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen } 1339dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen return false; 1349dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen} 1359dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 1369dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic bool AddressesMatch(void* key1, void* key2) { 138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return key1 == key2; 139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Check that snapshot has no unretained entries except root. 143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic bool ValidateSnapshot(const v8::HeapSnapshot* snapshot, int depth = 3) { 144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch i::HeapSnapshot* heap_snapshot = const_cast<i::HeapSnapshot*>( 145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<const i::HeapSnapshot*>(snapshot)); 146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch i::HashMap visited(AddressesMatch); 148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch i::List<i::HeapGraphEdge>& edges = heap_snapshot->edges(); 149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < edges.length(); ++i) { 150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch i::HashMap::Entry* entry = visited.Lookup( 151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<void*>(edges[i].to()), 152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<uint32_t>(reinterpret_cast<uintptr_t>(edges[i].to())), 153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch true); 154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t ref_count = static_cast<uint32_t>( 155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<uintptr_t>(entry->value)); 156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entry->value = reinterpret_cast<void*>(ref_count + 1); 157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t unretained_entries_count = 0; 159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch i::List<i::HeapEntry>& entries = heap_snapshot->entries(); 160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < entries.length(); ++i) { 161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch i::HashMap::Entry* entry = visited.Lookup( 162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<void*>(&entries[i]), 163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<uint32_t>(reinterpret_cast<uintptr_t>(&entries[i])), 164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch false); 165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!entry && entries[i].id() != 1) { 166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entries[i].Print("entry with no retainer", "", depth, 0); 167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ++unretained_entries_count; 168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return unretained_entries_count == 0; 171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1749dcf7e2f83591d471e88bf7d230651900b8e424bKristian MonsenTEST(HeapSnapshot) { 1753bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch LocalContext env2; 176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env2->GetIsolate()); 177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env2->GetIsolate()->GetHeapProfiler(); 1789dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 179f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch CompileRun( 1809dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen "function A2() {}\n" 1819dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen "function B2(x) { return function() { return typeof x; }; }\n" 1829dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen "function C2(x) { this.x1 = x; this.x2 = x; this[1] = x; }\n" 1839dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen "var a2 = new A2();\n" 1849dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen "var b2_1 = new B2(a2), b2_2 = new B2(a2);\n" 1859dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen "var c2 = new C2(a2);"); 1869dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen const v8::HeapSnapshot* snapshot_env2 = 187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("env2")); 188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot_env2)); 1899dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen const v8::HeapGraphNode* global_env2 = GetGlobalObject(snapshot_env2); 1909dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 19190bac256d9f48d4ee52d0e08bf0e5cad57b3c51cRussell Brenner // Verify, that JS global object of env2 has '..2' properties. 1929dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen const v8::HeapGraphNode* a2_node = 193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "a2"); 1949dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen CHECK_NE(NULL, a2_node); 195756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CHECK_NE( 196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NULL, GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "b2_1")); 197756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CHECK_NE( 198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NULL, GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "b2_2")); 199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "c2")); 2009dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 2019dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen NamedEntriesDetector det; 2023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch det.CheckAllReachables(const_cast<i::HeapEntry*>( 2033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch reinterpret_cast<const i::HeapEntry*>(global_env2))); 2049dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen CHECK(det.has_A2); 2059dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen CHECK(det.has_B2); 2069dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen CHECK(det.has_C2); 2079dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen} 2089dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 2099dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 210756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain MerrickTEST(HeapSnapshotObjectSizes) { 211756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick LocalContext env; 212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 214756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 215756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // -a-> X1 --a 216756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // x -b-> X2 <-| 217f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch CompileRun( 218756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick "function X(a, b) { this.a = a; this.b = b; }\n" 219756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick "x = new X(new X(), new X());\n" 220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "dummy = new X();\n" 2218a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang "(function() { x.a.a = x.b; })();"); 222756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick const v8::HeapSnapshot* snapshot = 223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("sizes")); 224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot)); 225756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick const v8::HeapGraphNode* global = GetGlobalObject(snapshot); 226756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick const v8::HeapGraphNode* x = 227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(global, v8::HeapGraphEdge::kProperty, "x"); 228756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CHECK_NE(NULL, x); 229756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick const v8::HeapGraphNode* x1 = 230756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick GetProperty(x, v8::HeapGraphEdge::kProperty, "a"); 231756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CHECK_NE(NULL, x1); 232756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick const v8::HeapGraphNode* x2 = 233756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick GetProperty(x, v8::HeapGraphEdge::kProperty, "b"); 234756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CHECK_NE(NULL, x2); 2358a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 2363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Test sizes. 237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(0, static_cast<int>(x->GetShallowSize())); 238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(0, static_cast<int>(x1->GetShallowSize())); 239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(0, static_cast<int>(x2->GetShallowSize())); 2403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 2413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2433ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochTEST(BoundFunctionInSnapshot) { 2443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LocalContext env; 245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 2473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CompileRun( 2483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "function myFunction(a, b) { this.a = a; this.b = b; }\n" 2493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "function AAAAA() {}\n" 2503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "boundFunction = myFunction.bind(new AAAAA(), 20, new Number(12)); \n"); 2513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const v8::HeapSnapshot* snapshot = 252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("sizes")); 253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot)); 2543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const v8::HeapGraphNode* global = GetGlobalObject(snapshot); 2553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const v8::HeapGraphNode* f = 256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(global, v8::HeapGraphEdge::kProperty, "boundFunction"); 2573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK(f); 258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(v8::String::NewFromUtf8(env->GetIsolate(), "native_bind"), 259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch f->GetName()); 2603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const v8::HeapGraphNode* bindings = 2613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GetProperty(f, v8::HeapGraphEdge::kInternal, "bindings"); 2623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_NE(NULL, bindings); 2633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(v8::HeapGraphNode::kArray, bindings->GetType()); 2643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(4, bindings->GetChildrenCount()); 2653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const v8::HeapGraphNode* bound_this = GetProperty( 2673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch f, v8::HeapGraphEdge::kShortcut, "bound_this"); 2683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK(bound_this); 2693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(v8::HeapGraphNode::kObject, bound_this->GetType()); 2703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const v8::HeapGraphNode* bound_function = GetProperty( 2723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch f, v8::HeapGraphEdge::kShortcut, "bound_function"); 2733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK(bound_function); 2743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(v8::HeapGraphNode::kClosure, bound_function->GetType()); 2753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const v8::HeapGraphNode* bound_argument = GetProperty( 2773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch f, v8::HeapGraphEdge::kShortcut, "bound_argument_1"); 2783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK(bound_argument); 2793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(v8::HeapGraphNode::kObject, bound_argument->GetType()); 280756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick} 281756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 282756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 283756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain MerrickTEST(HeapSnapshotEntryChildren) { 284756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick LocalContext env; 285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 287756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 288f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch CompileRun( 289756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick "function A() { }\n" 290756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick "a = new A;"); 291756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick const v8::HeapSnapshot* snapshot = 292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("children")); 293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot)); 294756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick const v8::HeapGraphNode* global = GetGlobalObject(snapshot); 295756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick for (int i = 0, count = global->GetChildrenCount(); i < count; ++i) { 296756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick const v8::HeapGraphEdge* prop = global->GetChild(i); 297756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CHECK_EQ(global, prop->GetFromNode()); 298756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 299756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick const v8::HeapGraphNode* a = 300756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick GetProperty(global, v8::HeapGraphEdge::kProperty, "a"); 301756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CHECK_NE(NULL, a); 302756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick for (int i = 0, count = a->GetChildrenCount(); i < count; ++i) { 303756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick const v8::HeapGraphEdge* prop = a->GetChild(i); 304756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CHECK_EQ(a, prop->GetFromNode()); 305756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 306756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick} 307756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 308756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 3099dcf7e2f83591d471e88bf7d230651900b8e424bKristian MonsenTEST(HeapSnapshotCodeObjects) { 3103bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch LocalContext env; 311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 3139dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 314f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch CompileRun( 3159dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen "function lazy(x) { return x - 1; }\n" 3169dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen "function compiled(x) { return x + 1; }\n" 317791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block "var anonymous = (function() { return function() { return 0; } })();\n" 3189dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen "compiled(1)"); 3199dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen const v8::HeapSnapshot* snapshot = 320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("code")); 321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot)); 3229dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 3239dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen const v8::HeapGraphNode* global = GetGlobalObject(snapshot); 3249dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen const v8::HeapGraphNode* compiled = 325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(global, v8::HeapGraphEdge::kProperty, "compiled"); 3269dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen CHECK_NE(NULL, compiled); 327756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CHECK_EQ(v8::HeapGraphNode::kClosure, compiled->GetType()); 3289dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen const v8::HeapGraphNode* lazy = 329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(global, v8::HeapGraphEdge::kProperty, "lazy"); 3309dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen CHECK_NE(NULL, lazy); 331756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CHECK_EQ(v8::HeapGraphNode::kClosure, lazy->GetType()); 332791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block const v8::HeapGraphNode* anonymous = 333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(global, v8::HeapGraphEdge::kProperty, "anonymous"); 334791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block CHECK_NE(NULL, anonymous); 335791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block CHECK_EQ(v8::HeapGraphNode::kClosure, anonymous->GetType()); 336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::Utf8Value anonymous_name(anonymous->GetName()); 337f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch CHECK_EQ("", *anonymous_name); 3389dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 3399dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen // Find references to code. 3409dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen const v8::HeapGraphNode* compiled_code = 3418b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch GetProperty(compiled, v8::HeapGraphEdge::kInternal, "shared"); 3429dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen CHECK_NE(NULL, compiled_code); 3439dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen const v8::HeapGraphNode* lazy_code = 3448b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch GetProperty(lazy, v8::HeapGraphEdge::kInternal, "shared"); 3459dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen CHECK_NE(NULL, lazy_code); 3469dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check that there's no strong next_code_link. There might be a weak one 348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // but might be not, so we can't check that fact. 349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* code = 350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(compiled_code, v8::HeapGraphEdge::kInternal, "code"); 351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, code); 352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* next_code_link = 353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(code, v8::HeapGraphEdge::kInternal, "code"); 354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(NULL, next_code_link); 355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3569dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen // Verify that non-compiled code doesn't contain references to "x" 3573bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch // literal, while compiled code does. The scope info is stored in FixedArray 3583bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch // objects attached to the SharedFunctionInfo. 3599dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen bool compiled_references_x = false, lazy_references_x = false; 3609dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen for (int i = 0, count = compiled_code->GetChildrenCount(); i < count; ++i) { 3619dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen const v8::HeapGraphEdge* prop = compiled_code->GetChild(i); 3629dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen const v8::HeapGraphNode* node = prop->GetToNode(); 363756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick if (node->GetType() == v8::HeapGraphNode::kArray) { 3649dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen if (HasString(node, "x")) { 3659dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen compiled_references_x = true; 3669dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen break; 3679dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen } 3689dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen } 3699dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen } 3709dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen for (int i = 0, count = lazy_code->GetChildrenCount(); i < count; ++i) { 3719dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen const v8::HeapGraphEdge* prop = lazy_code->GetChild(i); 3729dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen const v8::HeapGraphNode* node = prop->GetToNode(); 373756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick if (node->GetType() == v8::HeapGraphNode::kArray) { 3749dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen if (HasString(node, "x")) { 3759dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen lazy_references_x = true; 3769dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen break; 3779dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen } 3789dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen } 3799dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen } 3809dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen CHECK(compiled_references_x); 3819dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen CHECK(!lazy_references_x); 3829dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen} 3839dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 3843bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 385f87a203d89e1bbb6708282e0b64dbd13d59b723dBen MurdochTEST(HeapSnapshotHeapNumbers) { 386f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch LocalContext env; 387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 389f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch CompileRun( 390f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch "a = 1; // a is Smi\n" 391f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch "b = 2.5; // b is HeapNumber"); 392f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch const v8::HeapSnapshot* snapshot = 393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("numbers")); 394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot)); 395f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch const v8::HeapGraphNode* global = GetGlobalObject(snapshot); 396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(NULL, GetProperty(global, v8::HeapGraphEdge::kProperty, "a")); 397f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch const v8::HeapGraphNode* b = 398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(global, v8::HeapGraphEdge::kProperty, "b"); 399f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch CHECK_NE(NULL, b); 400f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch CHECK_EQ(v8::HeapGraphNode::kHeapNumber, b->GetType()); 401f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch} 402f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4043ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochTEST(HeapSnapshotSlicedString) { 4053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LocalContext env; 406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 4083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CompileRun( 4093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "parent_string = \"123456789.123456789.123456789.123456789.123456789." 4103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "123456789.123456789.123456789.123456789.123456789." 4113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "123456789.123456789.123456789.123456789.123456789." 4123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "123456789.123456789.123456789.123456789.123456789.\";" 4133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "child_string = parent_string.slice(100);"); 4143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const v8::HeapSnapshot* snapshot = 415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("strings")); 416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot)); 4173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const v8::HeapGraphNode* global = GetGlobalObject(snapshot); 4183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const v8::HeapGraphNode* parent_string = 419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(global, v8::HeapGraphEdge::kProperty, "parent_string"); 4203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_NE(NULL, parent_string); 4213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const v8::HeapGraphNode* child_string = 422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(global, v8::HeapGraphEdge::kProperty, "child_string"); 4233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_NE(NULL, child_string); 424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(v8::HeapGraphNode::kSlicedString, child_string->GetType()); 4253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const v8::HeapGraphNode* parent = 4263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GetProperty(child_string, v8::HeapGraphEdge::kInternal, "parent"); 4273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(parent_string, parent); 428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->DeleteAllHeapSnapshots(); 429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(HeapSnapshotConsString) { 433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate = CcTest::isolate(); 434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(isolate); 435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::ObjectTemplate> global_template = 436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::ObjectTemplate::New(isolate); 437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch global_template->SetInternalFieldCount(1); 438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LocalContext env(NULL, global_template); 439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Object> global_proxy = env->Global(); 440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Object> global = global_proxy->GetPrototype().As<v8::Object>(); 441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1, global->InternalFieldCount()); 442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch i::Factory* factory = CcTest::i_isolate()->factory(); 444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch i::Handle<i::String> first = factory->NewStringFromStaticChars("0123456789"); 445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch i::Handle<i::String> second = factory->NewStringFromStaticChars("0123456789"); 446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch i::Handle<i::String> cons_string = 447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->NewConsString(first, second).ToHandleChecked(); 448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch global->SetInternalField(0, v8::ToApiHandle<v8::String>(cons_string)); 450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = isolate->GetHeapProfiler(); 452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapSnapshot* snapshot = 453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("cons_strings")); 454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot)); 455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* global_node = GetGlobalObject(snapshot); 456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* string_node = 458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(global_node, v8::HeapGraphEdge::kInternal, "0"); 459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, string_node); 460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(v8::HeapGraphNode::kConsString, string_node->GetType()); 461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* first_node = 463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(string_node, v8::HeapGraphEdge::kInternal, "first"); 464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(v8::HeapGraphNode::kString, first_node->GetType()); 465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* second_node = 467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(string_node, v8::HeapGraphEdge::kInternal, "second"); 468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(v8::HeapGraphNode::kString, second_node->GetType()); 469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->DeleteAllHeapSnapshots(); 471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(HeapSnapshotSymbol) { 475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LocalContext env; 476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileRun("a = Symbol('mySymbol');\n"); 480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapSnapshot* snapshot = 481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("Symbol")); 482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot)); 483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* global = GetGlobalObject(snapshot); 484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* a = 485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(global, v8::HeapGraphEdge::kProperty, "a"); 486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, a); 487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(a->GetType(), v8::HeapGraphNode::kSymbol); 488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(v8_str("symbol"), a->GetName()); 489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* name = 490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(a, v8::HeapGraphEdge::kInternal, "name"); 491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, name); 492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(v8_str("mySymbol"), name->GetName()); 493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(HeapSnapshotWeakCollection) { 497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LocalContext env; 498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileRun( 502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "k = {}; v = {}; s = 'str';\n" 503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "ws = new WeakSet(); ws.add(k); ws.add(v); ws[s] = s;\n" 504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "wm = new WeakMap(); wm.set(k, v); wm[s] = s;\n"); 505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapSnapshot* snapshot = 506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("WeakCollections")); 507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot)); 508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* global = GetGlobalObject(snapshot); 509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* k = 510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(global, v8::HeapGraphEdge::kProperty, "k"); 511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, k); 512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* v = 513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(global, v8::HeapGraphEdge::kProperty, "v"); 514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, v); 515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* s = 516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(global, v8::HeapGraphEdge::kProperty, "s"); 517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, s); 518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* ws = 520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(global, v8::HeapGraphEdge::kProperty, "ws"); 521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, ws); 522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(v8::HeapGraphNode::kObject, ws->GetType()); 523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(v8_str("WeakSet"), ws->GetName()); 524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* ws_table = 526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(ws, v8::HeapGraphEdge::kInternal, "table"); 527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(v8::HeapGraphNode::kArray, ws_table->GetType()); 528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_GT(ws_table->GetChildrenCount(), 0); 529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int weak_entries = 0; 530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0, count = ws_table->GetChildrenCount(); i < count; ++i) { 531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphEdge* prop = ws_table->GetChild(i); 532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (prop->GetType() != v8::HeapGraphEdge::kWeak) continue; 533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (k->GetId() == prop->GetToNode()->GetId()) { 534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ++weak_entries; 535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1, weak_entries); 538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* ws_s = 539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(ws, v8::HeapGraphEdge::kProperty, "str"); 540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, ws_s); 541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(static_cast<int>(s->GetId()), static_cast<int>(ws_s->GetId())); 542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* wm = 544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(global, v8::HeapGraphEdge::kProperty, "wm"); 545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, wm); 546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(v8::HeapGraphNode::kObject, wm->GetType()); 547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(v8_str("WeakMap"), wm->GetName()); 548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* wm_table = 550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(wm, v8::HeapGraphEdge::kInternal, "table"); 551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(v8::HeapGraphNode::kArray, wm_table->GetType()); 552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_GT(wm_table->GetChildrenCount(), 0); 553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch weak_entries = 0; 554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0, count = wm_table->GetChildrenCount(); i < count; ++i) { 555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphEdge* prop = wm_table->GetChild(i); 556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (prop->GetType() != v8::HeapGraphEdge::kWeak) continue; 557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::SnapshotObjectId to_node_id = prop->GetToNode()->GetId(); 558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (to_node_id == k->GetId() || to_node_id == v->GetId()) { 559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ++weak_entries; 560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(2, weak_entries); 563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* wm_s = 564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(wm, v8::HeapGraphEdge::kProperty, "str"); 565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, wm_s); 566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(static_cast<int>(s->GetId()), static_cast<int>(wm_s->GetId())); 5673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 568f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(HeapSnapshotCollection) { 571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LocalContext env; 572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileRun( 576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "k = {}; v = {}; s = 'str';\n" 577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "set = new Set(); set.add(k); set.add(v); set[s] = s;\n" 578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "map = new Map(); map.set(k, v); map[s] = s;\n"); 579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapSnapshot* snapshot = 580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("Collections")); 581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot)); 582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* global = GetGlobalObject(snapshot); 583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* k = 584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(global, v8::HeapGraphEdge::kProperty, "k"); 585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, k); 586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* v = 587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(global, v8::HeapGraphEdge::kProperty, "v"); 588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, v); 589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* s = 590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(global, v8::HeapGraphEdge::kProperty, "s"); 591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, s); 592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* set = 594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(global, v8::HeapGraphEdge::kProperty, "set"); 595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, set); 596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(v8::HeapGraphNode::kObject, set->GetType()); 597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(v8_str("Set"), set->GetName()); 598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* set_table = 600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(set, v8::HeapGraphEdge::kInternal, "table"); 601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(v8::HeapGraphNode::kArray, set_table->GetType()); 602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_GT(set_table->GetChildrenCount(), 0); 603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int entries = 0; 604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0, count = set_table->GetChildrenCount(); i < count; ++i) { 605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphEdge* prop = set_table->GetChild(i); 606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::SnapshotObjectId to_node_id = prop->GetToNode()->GetId(); 607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (to_node_id == k->GetId() || to_node_id == v->GetId()) { 608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ++entries; 609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(2, entries); 612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* set_s = 613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(set, v8::HeapGraphEdge::kProperty, "str"); 614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, set_s); 615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(static_cast<int>(s->GetId()), static_cast<int>(set_s->GetId())); 616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* map = 618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(global, v8::HeapGraphEdge::kProperty, "map"); 619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, map); 620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(v8::HeapGraphNode::kObject, map->GetType()); 621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(v8_str("Map"), map->GetName()); 622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* map_table = 624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(map, v8::HeapGraphEdge::kInternal, "table"); 625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(v8::HeapGraphNode::kArray, map_table->GetType()); 626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_GT(map_table->GetChildrenCount(), 0); 627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entries = 0; 628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0, count = map_table->GetChildrenCount(); i < count; ++i) { 629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphEdge* prop = map_table->GetChild(i); 630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::SnapshotObjectId to_node_id = prop->GetToNode()->GetId(); 631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (to_node_id == k->GetId() || to_node_id == v->GetId()) { 632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ++entries; 633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(2, entries); 636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* map_s = 637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(map, v8::HeapGraphEdge::kProperty, "str"); 638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, map_s); 639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(static_cast<int>(s->GetId()), static_cast<int>(map_s->GetId())); 640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 643f87a203d89e1bbb6708282e0b64dbd13d59b723dBen MurdochTEST(HeapSnapshotInternalReferences) { 644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate = CcTest::isolate(); 645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(isolate); 646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::ObjectTemplate> global_template = 647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::ObjectTemplate::New(isolate); 648f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch global_template->SetInternalFieldCount(2); 649f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch LocalContext env(NULL, global_template); 650f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch v8::Handle<v8::Object> global_proxy = env->Global(); 651f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch v8::Handle<v8::Object> global = global_proxy->GetPrototype().As<v8::Object>(); 652f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch CHECK_EQ(2, global->InternalFieldCount()); 653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Object> obj = v8::Object::New(isolate); 654f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch global->SetInternalField(0, v8_num(17)); 655f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch global->SetInternalField(1, obj); 656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = isolate->GetHeapProfiler(); 657f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch const v8::HeapSnapshot* snapshot = 658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("internals")); 659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot)); 660f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch const v8::HeapGraphNode* global_node = GetGlobalObject(snapshot); 661f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // The first reference will not present, because it's a Smi. 662f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch CHECK_EQ(NULL, GetProperty(global_node, v8::HeapGraphEdge::kInternal, "0")); 663f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // The second reference is to an object. 664f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch CHECK_NE(NULL, GetProperty(global_node, v8::HeapGraphEdge::kInternal, "1")); 665f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch} 666f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 667f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Trying to introduce a check helper for uint32_t causes many 6693bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch// overloading ambiguities, so it seems easier just to cast 6703bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch// them to a signed type. 671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define CHECK_EQ_SNAPSHOT_OBJECT_ID(a, b) \ 672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(static_cast<int32_t>(a), static_cast<int32_t>(b)) 673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define CHECK_NE_SNAPSHOT_OBJECT_ID(a, b) \ 674756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CHECK((a) != (b)) // NOLINT 6753bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(HeapSnapshotAddressReuse) { 677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LocalContext env; 678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileRun( 682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "function A() {}\n" 683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "var a = [];\n" 684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "for (var i = 0; i < 10000; ++i)\n" 685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " a[i] = new A();\n"); 686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapSnapshot* snapshot1 = 687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("snapshot1")); 688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot1)); 689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::SnapshotObjectId maxId1 = snapshot1->GetMaxSnapshotJSObjectId(); 690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileRun( 692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "for (var i = 0; i < 10000; ++i)\n" 693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " a[i] = new A();\n"); 694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); 695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapSnapshot* snapshot2 = 697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("snapshot2")); 698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot2)); 699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* global2 = GetGlobalObject(snapshot2); 700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* array_node = 702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(global2, v8::HeapGraphEdge::kProperty, "a"); 703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, array_node); 704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int wrong_count = 0; 705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0, count = array_node->GetChildrenCount(); i < count; ++i) { 706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphEdge* prop = array_node->GetChild(i); 707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (prop->GetType() != v8::HeapGraphEdge::kElement) 708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch continue; 709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::SnapshotObjectId id = prop->GetToNode()->GetId(); 710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (id < maxId1) 711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ++wrong_count; 712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0, wrong_count); 714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7173ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochTEST(HeapEntryIdsAndArrayShift) { 7183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LocalContext env; 719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 7213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CompileRun( 7233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "function AnObject() {\n" 7243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch " this.first = 'first';\n" 7253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch " this.second = 'second';\n" 7263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "}\n" 7273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "var a = new Array();\n" 7283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "for (var i = 0; i < 10; ++i)\n" 7293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch " a.push(new AnObject());\n"); 7303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const v8::HeapSnapshot* snapshot1 = 731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("s1")); 732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot1)); 7333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CompileRun( 7353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "for (var i = 0; i < 1; ++i)\n" 7363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch " a.shift();\n"); 7373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); 7393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const v8::HeapSnapshot* snapshot2 = 741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("s2")); 742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot2)); 7433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const v8::HeapGraphNode* global1 = GetGlobalObject(snapshot1); 7453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const v8::HeapGraphNode* global2 = GetGlobalObject(snapshot2); 746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE_SNAPSHOT_OBJECT_ID(0, global1->GetId()); 747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ_SNAPSHOT_OBJECT_ID(global1->GetId(), global2->GetId()); 7483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const v8::HeapGraphNode* a1 = 7503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GetProperty(global1, v8::HeapGraphEdge::kProperty, "a"); 7513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_NE(NULL, a1); 7523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const v8::HeapGraphNode* k1 = 753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(a1, v8::HeapGraphEdge::kInternal, "elements"); 7543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_NE(NULL, k1); 7553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const v8::HeapGraphNode* a2 = 7563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GetProperty(global2, v8::HeapGraphEdge::kProperty, "a"); 7573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_NE(NULL, a2); 7583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const v8::HeapGraphNode* k2 = 759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(a2, v8::HeapGraphEdge::kInternal, "elements"); 7603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_NE(NULL, k2); 7613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ_SNAPSHOT_OBJECT_ID(a1->GetId(), a2->GetId()); 763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ_SNAPSHOT_OBJECT_ID(k1->GetId(), k2->GetId()); 7643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 7653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7673bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben MurdochTEST(HeapEntryIdsAndGC) { 7683bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch LocalContext env; 769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 7713bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 772f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch CompileRun( 7733bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch "function A() {}\n" 7743bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch "function B(x) { this.x = x; }\n" 7753bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch "var a = new A();\n" 7763bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch "var b = new B(a);"); 777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::String> s1_str = v8_str("s1"); 778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::String> s2_str = v8_str("s2"); 7793bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch const v8::HeapSnapshot* snapshot1 = 780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(s1_str); 781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot1)); 7823bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); 7843bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 7853bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch const v8::HeapSnapshot* snapshot2 = 786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(s2_str); 787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot2)); 788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_GT(snapshot1->GetMaxSnapshotJSObjectId(), 7000); 790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(snapshot1->GetMaxSnapshotJSObjectId() <= 791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch snapshot2->GetMaxSnapshotJSObjectId()); 7923bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 7933bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch const v8::HeapGraphNode* global1 = GetGlobalObject(snapshot1); 7943bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch const v8::HeapGraphNode* global2 = GetGlobalObject(snapshot2); 795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE_SNAPSHOT_OBJECT_ID(0, global1->GetId()); 796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ_SNAPSHOT_OBJECT_ID(global1->GetId(), global2->GetId()); 7973bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch const v8::HeapGraphNode* A1 = 798756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick GetProperty(global1, v8::HeapGraphEdge::kProperty, "A"); 799756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CHECK_NE(NULL, A1); 8003bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch const v8::HeapGraphNode* A2 = 801756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick GetProperty(global2, v8::HeapGraphEdge::kProperty, "A"); 802756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CHECK_NE(NULL, A2); 803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE_SNAPSHOT_OBJECT_ID(0, A1->GetId()); 804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ_SNAPSHOT_OBJECT_ID(A1->GetId(), A2->GetId()); 8053bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch const v8::HeapGraphNode* B1 = 806756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick GetProperty(global1, v8::HeapGraphEdge::kProperty, "B"); 807756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CHECK_NE(NULL, B1); 8083bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch const v8::HeapGraphNode* B2 = 809756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick GetProperty(global2, v8::HeapGraphEdge::kProperty, "B"); 810756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CHECK_NE(NULL, B2); 811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE_SNAPSHOT_OBJECT_ID(0, B1->GetId()); 812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ_SNAPSHOT_OBJECT_ID(B1->GetId(), B2->GetId()); 8133bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch const v8::HeapGraphNode* a1 = 814756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick GetProperty(global1, v8::HeapGraphEdge::kProperty, "a"); 815756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CHECK_NE(NULL, a1); 8163bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch const v8::HeapGraphNode* a2 = 817756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick GetProperty(global2, v8::HeapGraphEdge::kProperty, "a"); 818756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CHECK_NE(NULL, a2); 819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE_SNAPSHOT_OBJECT_ID(0, a1->GetId()); 820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ_SNAPSHOT_OBJECT_ID(a1->GetId(), a2->GetId()); 8213bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch const v8::HeapGraphNode* b1 = 822756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick GetProperty(global1, v8::HeapGraphEdge::kProperty, "b"); 823756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CHECK_NE(NULL, b1); 8243bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch const v8::HeapGraphNode* b2 = 825756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick GetProperty(global2, v8::HeapGraphEdge::kProperty, "b"); 826756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CHECK_NE(NULL, b2); 827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE_SNAPSHOT_OBJECT_ID(0, b1->GetId()); 828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ_SNAPSHOT_OBJECT_ID(b1->GetId(), b2->GetId()); 8293bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch} 8303bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 8313bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 832f87a203d89e1bbb6708282e0b64dbd13d59b723dBen MurdochTEST(HeapSnapshotRootPreservedAfterSorting) { 833f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch LocalContext env; 834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 836f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch const v8::HeapSnapshot* snapshot = 837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("s")); 838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot)); 839f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch const v8::HeapGraphNode* root1 = snapshot->GetRoot(); 840f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch const_cast<i::HeapSnapshot*>(reinterpret_cast<const i::HeapSnapshot*>( 841f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch snapshot))->GetSortedEntriesList(); 842f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch const v8::HeapGraphNode* root2 = snapshot->GetRoot(); 843f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch CHECK_EQ(root1, root2); 844f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch} 845f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 846f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 8470d5e116f6aee03185f237311a943491bb079a768Kristian Monsennamespace { 8480d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 8490d5e116f6aee03185f237311a943491bb079a768Kristian Monsenclass TestJSONStream : public v8::OutputStream { 8500d5e116f6aee03185f237311a943491bb079a768Kristian Monsen public: 8510d5e116f6aee03185f237311a943491bb079a768Kristian Monsen TestJSONStream() : eos_signaled_(0), abort_countdown_(-1) {} 8520d5e116f6aee03185f237311a943491bb079a768Kristian Monsen explicit TestJSONStream(int abort_countdown) 8530d5e116f6aee03185f237311a943491bb079a768Kristian Monsen : eos_signaled_(0), abort_countdown_(abort_countdown) {} 8540d5e116f6aee03185f237311a943491bb079a768Kristian Monsen virtual ~TestJSONStream() {} 8550d5e116f6aee03185f237311a943491bb079a768Kristian Monsen virtual void EndOfStream() { ++eos_signaled_; } 8560d5e116f6aee03185f237311a943491bb079a768Kristian Monsen virtual WriteResult WriteAsciiChunk(char* buffer, int chars_written) { 8570d5e116f6aee03185f237311a943491bb079a768Kristian Monsen if (abort_countdown_ > 0) --abort_countdown_; 8580d5e116f6aee03185f237311a943491bb079a768Kristian Monsen if (abort_countdown_ == 0) return kAbort; 8590d5e116f6aee03185f237311a943491bb079a768Kristian Monsen CHECK_GT(chars_written, 0); 8600d5e116f6aee03185f237311a943491bb079a768Kristian Monsen i::Vector<char> chunk = buffer_.AddBlock(chars_written, '\0'); 861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch i::MemCopy(chunk.start(), buffer, chars_written); 8620d5e116f6aee03185f237311a943491bb079a768Kristian Monsen return kContinue; 8630d5e116f6aee03185f237311a943491bb079a768Kristian Monsen } 864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch virtual WriteResult WriteUint32Chunk(uint32_t* buffer, int chars_written) { 865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(false); 866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return kAbort; 867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8680d5e116f6aee03185f237311a943491bb079a768Kristian Monsen void WriteTo(i::Vector<char> dest) { buffer_.WriteTo(dest); } 8690d5e116f6aee03185f237311a943491bb079a768Kristian Monsen int eos_signaled() { return eos_signaled_; } 8700d5e116f6aee03185f237311a943491bb079a768Kristian Monsen int size() { return buffer_.size(); } 871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8720d5e116f6aee03185f237311a943491bb079a768Kristian Monsen private: 8730d5e116f6aee03185f237311a943491bb079a768Kristian Monsen i::Collector<char> buffer_; 8740d5e116f6aee03185f237311a943491bb079a768Kristian Monsen int eos_signaled_; 8750d5e116f6aee03185f237311a943491bb079a768Kristian Monsen int abort_countdown_; 8760d5e116f6aee03185f237311a943491bb079a768Kristian Monsen}; 8770d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass OneByteResource : public v8::String::ExternalOneByteStringResource { 8790d5e116f6aee03185f237311a943491bb079a768Kristian Monsen public: 880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit OneByteResource(i::Vector<char> string) : data_(string.start()) { 8810d5e116f6aee03185f237311a943491bb079a768Kristian Monsen length_ = string.length(); 8820d5e116f6aee03185f237311a943491bb079a768Kristian Monsen } 8830d5e116f6aee03185f237311a943491bb079a768Kristian Monsen virtual const char* data() const { return data_; } 8840d5e116f6aee03185f237311a943491bb079a768Kristian Monsen virtual size_t length() const { return length_; } 8850d5e116f6aee03185f237311a943491bb079a768Kristian Monsen private: 8860d5e116f6aee03185f237311a943491bb079a768Kristian Monsen const char* data_; 8870d5e116f6aee03185f237311a943491bb079a768Kristian Monsen size_t length_; 8880d5e116f6aee03185f237311a943491bb079a768Kristian Monsen}; 8890d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 8900d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} // namespace 8910d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 8920d5e116f6aee03185f237311a943491bb079a768Kristian MonsenTEST(HeapSnapshotJSONSerialization) { 8930d5e116f6aee03185f237311a943491bb079a768Kristian Monsen LocalContext env; 894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 8960d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 8970d5e116f6aee03185f237311a943491bb079a768Kristian Monsen#define STRING_LITERAL_FOR_TEST \ 8980d5e116f6aee03185f237311a943491bb079a768Kristian Monsen "\"String \\n\\r\\u0008\\u0081\\u0101\\u0801\\u8001\"" 899f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch CompileRun( 9000d5e116f6aee03185f237311a943491bb079a768Kristian Monsen "function A(s) { this.s = s; }\n" 9010d5e116f6aee03185f237311a943491bb079a768Kristian Monsen "function B(x) { this.x = x; }\n" 9020d5e116f6aee03185f237311a943491bb079a768Kristian Monsen "var a = new A(" STRING_LITERAL_FOR_TEST ");\n" 9030d5e116f6aee03185f237311a943491bb079a768Kristian Monsen "var b = new B(a);"); 9040d5e116f6aee03185f237311a943491bb079a768Kristian Monsen const v8::HeapSnapshot* snapshot = 905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("json")); 906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot)); 907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9080d5e116f6aee03185f237311a943491bb079a768Kristian Monsen TestJSONStream stream; 9090d5e116f6aee03185f237311a943491bb079a768Kristian Monsen snapshot->Serialize(&stream, v8::HeapSnapshot::kJSON); 9100d5e116f6aee03185f237311a943491bb079a768Kristian Monsen CHECK_GT(stream.size(), 0); 9110d5e116f6aee03185f237311a943491bb079a768Kristian Monsen CHECK_EQ(1, stream.eos_signaled()); 9120d5e116f6aee03185f237311a943491bb079a768Kristian Monsen i::ScopedVector<char> json(stream.size()); 9130d5e116f6aee03185f237311a943491bb079a768Kristian Monsen stream.WriteTo(json); 9140d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 9150d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // Verify that snapshot string is valid JSON. 916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OneByteResource* json_res = new OneByteResource(json); 917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::String> json_string = 918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewExternal(env->GetIsolate(), json_res); 91969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch env->Global()->Set(v8_str("json_snapshot"), json_string); 9200d5e116f6aee03185f237311a943491bb079a768Kristian Monsen v8::Local<v8::Value> snapshot_parse_result = CompileRun( 9210d5e116f6aee03185f237311a943491bb079a768Kristian Monsen "var parsed = JSON.parse(json_snapshot); true;"); 9220d5e116f6aee03185f237311a943491bb079a768Kristian Monsen CHECK(!snapshot_parse_result.IsEmpty()); 9230d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 9240d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // Verify that snapshot object has required fields. 9250d5e116f6aee03185f237311a943491bb079a768Kristian Monsen v8::Local<v8::Object> parsed_snapshot = 92669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch env->Global()->Get(v8_str("parsed"))->ToObject(); 92769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CHECK(parsed_snapshot->Has(v8_str("snapshot"))); 92869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CHECK(parsed_snapshot->Has(v8_str("nodes"))); 929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(parsed_snapshot->Has(v8_str("edges"))); 93069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CHECK(parsed_snapshot->Has(v8_str("strings"))); 9310d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 9320d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // Get node and edge "member" offsets. 9330d5e116f6aee03185f237311a943491bb079a768Kristian Monsen v8::Local<v8::Value> meta_analysis_result = CompileRun( 934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "var meta = parsed.snapshot.meta;\n" 935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "var edge_count_offset = meta.node_fields.indexOf('edge_count');\n" 936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "var node_fields_count = meta.node_fields.length;\n" 937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "var edge_fields_count = meta.edge_fields.length;\n" 938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "var edge_type_offset = meta.edge_fields.indexOf('type');\n" 939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "var edge_name_offset = meta.edge_fields.indexOf('name_or_index');\n" 940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "var edge_to_node_offset = meta.edge_fields.indexOf('to_node');\n" 9410d5e116f6aee03185f237311a943491bb079a768Kristian Monsen "var property_type =" 942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " meta.edge_types[edge_type_offset].indexOf('property');\n" 9438a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang "var shortcut_type =" 944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " meta.edge_types[edge_type_offset].indexOf('shortcut');\n" 945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "var node_count = parsed.nodes.length / node_fields_count;\n" 946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "var first_edge_indexes = parsed.first_edge_indexes = [];\n" 947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "for (var i = 0, first_edge_index = 0; i < node_count; ++i) {\n" 948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " first_edge_indexes[i] = first_edge_index;\n" 949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " first_edge_index += edge_fields_count *\n" 950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " parsed.nodes[i * node_fields_count + edge_count_offset];\n" 951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "}\n" 952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "first_edge_indexes[node_count] = first_edge_index;\n"); 9530d5e116f6aee03185f237311a943491bb079a768Kristian Monsen CHECK(!meta_analysis_result.IsEmpty()); 9540d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 9550d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // A helper function for processing encoded nodes. 9560d5e116f6aee03185f237311a943491bb079a768Kristian Monsen CompileRun( 9578a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang "function GetChildPosByProperty(pos, prop_name, prop_type) {\n" 9580d5e116f6aee03185f237311a943491bb079a768Kristian Monsen " var nodes = parsed.nodes;\n" 959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " var edges = parsed.edges;\n" 9600d5e116f6aee03185f237311a943491bb079a768Kristian Monsen " var strings = parsed.strings;\n" 961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " var node_ordinal = pos / node_fields_count;\n" 962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " for (var i = parsed.first_edge_indexes[node_ordinal],\n" 963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " count = parsed.first_edge_indexes[node_ordinal + 1];\n" 964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " i < count; i += edge_fields_count) {\n" 965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " if (edges[i + edge_type_offset] === prop_type\n" 966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " && strings[edges[i + edge_name_offset]] === prop_name)\n" 967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " return edges[i + edge_to_node_offset];\n" 9680d5e116f6aee03185f237311a943491bb079a768Kristian Monsen " }\n" 9690d5e116f6aee03185f237311a943491bb079a768Kristian Monsen " return null;\n" 9700d5e116f6aee03185f237311a943491bb079a768Kristian Monsen "}\n"); 9710d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // Get the string index using the path: <root> -> <global>.b.x.s 9720d5e116f6aee03185f237311a943491bb079a768Kristian Monsen v8::Local<v8::Value> string_obj_pos_val = CompileRun( 9730d5e116f6aee03185f237311a943491bb079a768Kristian Monsen "GetChildPosByProperty(\n" 9740d5e116f6aee03185f237311a943491bb079a768Kristian Monsen " GetChildPosByProperty(\n" 9750d5e116f6aee03185f237311a943491bb079a768Kristian Monsen " GetChildPosByProperty(" 976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " parsed.edges[edge_fields_count + edge_to_node_offset]," 977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " \"b\", property_type),\n" 9788a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang " \"x\", property_type)," 9798a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang " \"s\", property_type)"); 9800d5e116f6aee03185f237311a943491bb079a768Kristian Monsen CHECK(!string_obj_pos_val.IsEmpty()); 9810d5e116f6aee03185f237311a943491bb079a768Kristian Monsen int string_obj_pos = 9820d5e116f6aee03185f237311a943491bb079a768Kristian Monsen static_cast<int>(string_obj_pos_val->ToNumber()->Value()); 9830d5e116f6aee03185f237311a943491bb079a768Kristian Monsen v8::Local<v8::Object> nodes_array = 98469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch parsed_snapshot->Get(v8_str("nodes"))->ToObject(); 9850d5e116f6aee03185f237311a943491bb079a768Kristian Monsen int string_index = static_cast<int>( 9860d5e116f6aee03185f237311a943491bb079a768Kristian Monsen nodes_array->Get(string_obj_pos + 1)->ToNumber()->Value()); 9870d5e116f6aee03185f237311a943491bb079a768Kristian Monsen CHECK_GT(string_index, 0); 9880d5e116f6aee03185f237311a943491bb079a768Kristian Monsen v8::Local<v8::Object> strings_array = 98969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch parsed_snapshot->Get(v8_str("strings"))->ToObject(); 9900d5e116f6aee03185f237311a943491bb079a768Kristian Monsen v8::Local<v8::String> string = strings_array->Get(string_index)->ToString(); 9910d5e116f6aee03185f237311a943491bb079a768Kristian Monsen v8::Local<v8::String> ref_string = 9920d5e116f6aee03185f237311a943491bb079a768Kristian Monsen CompileRun(STRING_LITERAL_FOR_TEST)->ToString(); 9930d5e116f6aee03185f237311a943491bb079a768Kristian Monsen#undef STRING_LITERAL_FOR_TEST 9940d5e116f6aee03185f237311a943491bb079a768Kristian Monsen CHECK_EQ(*v8::String::Utf8Value(ref_string), 9950d5e116f6aee03185f237311a943491bb079a768Kristian Monsen *v8::String::Utf8Value(string)); 9960d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 9970d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 9980d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 9990d5e116f6aee03185f237311a943491bb079a768Kristian MonsenTEST(HeapSnapshotJSONSerializationAborting) { 10000d5e116f6aee03185f237311a943491bb079a768Kristian Monsen LocalContext env; 1001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 1002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 10030d5e116f6aee03185f237311a943491bb079a768Kristian Monsen const v8::HeapSnapshot* snapshot = 1004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("abort")); 1005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot)); 10060d5e116f6aee03185f237311a943491bb079a768Kristian Monsen TestJSONStream stream(5); 10070d5e116f6aee03185f237311a943491bb079a768Kristian Monsen snapshot->Serialize(&stream, v8::HeapSnapshot::kJSON); 10080d5e116f6aee03185f237311a943491bb079a768Kristian Monsen CHECK_GT(stream.size(), 0); 10090d5e116f6aee03185f237311a943491bb079a768Kristian Monsen CHECK_EQ(0, stream.eos_signaled()); 10100d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 10110d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 1012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace { 1013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass TestStatsStream : public v8::OutputStream { 1015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 1016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TestStatsStream() 1017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : eos_signaled_(0), 1018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch updates_written_(0), 1019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entries_count_(0), 1020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entries_size_(0), 1021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch intervals_count_(0), 1022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch first_interval_index_(-1) { } 1023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TestStatsStream(const TestStatsStream& stream) 1024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : v8::OutputStream(stream), 1025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch eos_signaled_(stream.eos_signaled_), 1026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch updates_written_(stream.updates_written_), 1027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entries_count_(stream.entries_count_), 1028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entries_size_(stream.entries_size_), 1029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch intervals_count_(stream.intervals_count_), 1030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch first_interval_index_(stream.first_interval_index_) { } 1031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch virtual ~TestStatsStream() {} 1032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch virtual void EndOfStream() { ++eos_signaled_; } 1033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch virtual WriteResult WriteAsciiChunk(char* buffer, int chars_written) { 1034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(false); 1035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return kAbort; 1036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch virtual WriteResult WriteHeapStatsChunk(v8::HeapStatsUpdate* buffer, 1038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int updates_written) { 1039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ++intervals_count_; 1040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(updates_written); 1041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch updates_written_ += updates_written; 1042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entries_count_ = 0; 1043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (first_interval_index_ == -1 && updates_written != 0) 1044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch first_interval_index_ = buffer[0].index; 1045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < updates_written; ++i) { 1046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entries_count_ += buffer[i].count; 1047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entries_size_ += buffer[i].size; 1048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return kContinue; 1051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int eos_signaled() { return eos_signaled_; } 1053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int updates_written() { return updates_written_; } 1054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t entries_count() const { return entries_count_; } 1055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t entries_size() const { return entries_size_; } 1056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int intervals_count() const { return intervals_count_; } 1057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int first_interval_index() const { return first_interval_index_; } 1058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 1060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int eos_signaled_; 1061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int updates_written_; 1062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t entries_count_; 1063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t entries_size_; 1064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int intervals_count_; 1065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int first_interval_index_; 1066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 1067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} // namespace 1069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic TestStatsStream GetHeapStatsUpdate( 1071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler, 1072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::SnapshotObjectId* object_id = NULL) { 1073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TestStatsStream stream; 1074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::SnapshotObjectId last_seen_id = heap_profiler->GetHeapStats(&stream); 1075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (object_id) 1076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *object_id = last_seen_id; 1077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1, stream.eos_signaled()); 1078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return stream; 1079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(HeapSnapshotObjectsStats) { 1083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LocalContext env; 1084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 1085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 1086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->StartTrackingHeapObjects(); 1088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We have to call GC 6 times. In other case the garbage will be 1089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the reason of flakiness. 1090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < 6; ++i) { 1091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); 1092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::SnapshotObjectId initial_id; 1095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Single chunk of data expected in update. Initial data. 1097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TestStatsStream stats_update = GetHeapStatsUpdate(heap_profiler, 1098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &initial_id); 1099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1, stats_update.intervals_count()); 1100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1, stats_update.updates_written()); 1101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_LT(0, stats_update.entries_size()); 1102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0, stats_update.first_interval_index()); 1103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // No data expected in update because nothing has happened. 1106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::SnapshotObjectId same_id; 1107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0, GetHeapStatsUpdate(heap_profiler, &same_id).updates_written()); 1108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ_SNAPSHOT_OBJECT_ID(initial_id, same_id); 1109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::SnapshotObjectId additional_string_id; 1112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope inner_scope_1(env->GetIsolate()); 1113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8_str("string1"); 1114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Single chunk of data with one new entry expected in update. 1116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TestStatsStream stats_update = GetHeapStatsUpdate(heap_profiler, 1117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &additional_string_id); 1118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_LT(same_id, additional_string_id); 1119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1, stats_update.intervals_count()); 1120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1, stats_update.updates_written()); 1121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_LT(0, stats_update.entries_size()); 1122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1, stats_update.entries_count()); 1123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(2, stats_update.first_interval_index()); 1124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // No data expected in update because nothing happened. 1127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::SnapshotObjectId last_id; 1128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0, GetHeapStatsUpdate(heap_profiler, &last_id).updates_written()); 1129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ_SNAPSHOT_OBJECT_ID(additional_string_id, last_id); 1130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope inner_scope_2(env->GetIsolate()); 1133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8_str("string2"); 1134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t entries_size; 1136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope inner_scope_3(env->GetIsolate()); 1138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8_str("string3"); 1139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8_str("string4"); 1140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Single chunk of data with three new entries expected in update. 1143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TestStatsStream stats_update = GetHeapStatsUpdate(heap_profiler); 1144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1, stats_update.intervals_count()); 1145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1, stats_update.updates_written()); 1146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_LT(0, entries_size = stats_update.entries_size()); 1147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(3, stats_update.entries_count()); 1148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(4, stats_update.first_interval_index()); 1149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Single chunk of data with two left entries expected in update. 1154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TestStatsStream stats_update = GetHeapStatsUpdate(heap_profiler); 1155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1, stats_update.intervals_count()); 1156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1, stats_update.updates_written()); 1157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_GT(entries_size, stats_update.entries_size()); 1158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1, stats_update.entries_count()); 1159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Two strings from forth interval were released. 1160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(4, stats_update.first_interval_index()); 1161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Single chunk of data with 0 left entries expected in update. 1166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TestStatsStream stats_update = GetHeapStatsUpdate(heap_profiler); 1167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1, stats_update.intervals_count()); 1168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1, stats_update.updates_written()); 1169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0, stats_update.entries_size()); 1170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0, stats_update.entries_count()); 1171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The last string from forth interval was released. 1172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(4, stats_update.first_interval_index()); 1173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Single chunk of data with 0 left entries expected in update. 1177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TestStatsStream stats_update = GetHeapStatsUpdate(heap_profiler); 1178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1, stats_update.intervals_count()); 1179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1, stats_update.updates_written()); 1180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0, stats_update.entries_size()); 1181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0, stats_update.entries_count()); 1182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The only string from the second interval was released. 1183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(2, stats_update.first_interval_index()); 1184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Array> array = v8::Array::New(env->GetIsolate()); 1187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0, array->Length()); 1188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Force array's buffer allocation. 1189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch array->Set(2, v8_num(7)); 1190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t entries_size; 1192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Single chunk of data with 2 entries expected in update. 1194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TestStatsStream stats_update = GetHeapStatsUpdate(heap_profiler); 1195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1, stats_update.intervals_count()); 1196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1, stats_update.updates_written()); 1197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_LT(0, entries_size = stats_update.entries_size()); 1198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // They are the array and its buffer. 1199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(2, stats_update.entries_count()); 1200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(8, stats_update.first_interval_index()); 1201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < 100; ++i) 1204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch array->Set(i, v8_num(i)); 1205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 1207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Single chunk of data with 1 entry expected in update. 1208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TestStatsStream stats_update = GetHeapStatsUpdate(heap_profiler); 1209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1, stats_update.intervals_count()); 1210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The first interval was changed because old buffer was collected. 1211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The second interval was changed because new buffer was allocated. 1212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(2, stats_update.updates_written()); 1213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_LT(entries_size, stats_update.entries_size()); 1214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(2, stats_update.entries_count()); 1215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(8, stats_update.first_interval_index()); 1216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->StopTrackingHeapObjects(); 1219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(HeapObjectIds) { 1223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LocalContext env; 1224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate = env->GetIsolate(); 1225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(isolate); 1226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 1227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int kLength = 10; 1229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Object> objects[kLength]; 1230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::SnapshotObjectId ids[kLength]; 1231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->StartTrackingHeapObjects(false); 1233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < kLength; i++) { 1235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch objects[i] = v8::Object::New(isolate); 1236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetHeapStatsUpdate(heap_profiler); 1238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < kLength; i++) { 1240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::SnapshotObjectId id = heap_profiler->GetObjectId(objects[i]); 1241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(v8::HeapProfiler::kUnknownObjectId, static_cast<int>(id)); 1242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ids[i] = id; 1243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->StopTrackingHeapObjects(); 1246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::heap()->CollectAllAvailableGarbage(); 1247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < kLength; i++) { 1249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::SnapshotObjectId id = heap_profiler->GetObjectId(objects[i]); 1250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(static_cast<int>(ids[i]), static_cast<int>(id)); 1251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Value> obj = heap_profiler->FindObjectById(ids[i]); 1252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(objects[i], obj); 1253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->ClearObjectIds(); 1256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < kLength; i++) { 1257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::SnapshotObjectId id = heap_profiler->GetObjectId(objects[i]); 1258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(v8::HeapProfiler::kUnknownObjectId, static_cast<int>(id)); 1259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Value> obj = heap_profiler->FindObjectById(ids[i]); 1260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(obj.IsEmpty()); 1261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 12648a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 12653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic void CheckChildrenIds(const v8::HeapSnapshot* snapshot, 12663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const v8::HeapGraphNode* node, 12673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int level, int max_level) { 12683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (level > max_level) return; 12693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(node, snapshot->GetNodeById(node->GetId())); 12703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0, count = node->GetChildrenCount(); i < count; ++i) { 12713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const v8::HeapGraphEdge* prop = node->GetChild(i); 12723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const v8::HeapGraphNode* child = 12733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch snapshot->GetNodeById(prop->GetToNode()->GetId()); 1274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ_SNAPSHOT_OBJECT_ID(prop->GetToNode()->GetId(), child->GetId()); 12753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(prop->GetToNode(), child); 12763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CheckChildrenIds(snapshot, child, level + 1, max_level); 12773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 12783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 12793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1281b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochTEST(HeapSnapshotGetNodeById) { 1282b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch LocalContext env; 1283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 1284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 1285b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1286b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const v8::HeapSnapshot* snapshot = 1287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("id")); 1288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot)); 1289b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const v8::HeapGraphNode* root = snapshot->GetRoot(); 12903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CheckChildrenIds(snapshot, root, 0, 3); 1291b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Check a big id, which should not exist yet. 1292b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(NULL, snapshot->GetNodeById(0x1000000UL)); 1293b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1294b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1295b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(HeapSnapshotGetSnapshotObjectId) { 1297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LocalContext env; 1298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 1299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 1300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileRun("globalObject = {};\n"); 1301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapSnapshot* snapshot = 1302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("get_snapshot_object_id")); 1303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot)); 1304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* global = GetGlobalObject(snapshot); 1305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* global_object = 1306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(global, v8::HeapGraphEdge::kProperty, "globalObject"); 1307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(global_object); 1308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Value> globalObjectHandle = env->Global()->Get( 1310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(env->GetIsolate(), "globalObject")); 1311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(!globalObjectHandle.IsEmpty()); 1312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(globalObjectHandle->IsObject()); 1313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::SnapshotObjectId id = heap_profiler->GetObjectId(globalObjectHandle); 1315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(static_cast<int>(v8::HeapProfiler::kUnknownObjectId), 1316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch id); 1317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(static_cast<int>(id), global_object->GetId()); 1318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(HeapSnapshotUnknownSnapshotObjectId) { 1322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LocalContext env; 1323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 1324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 1325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileRun("globalObject = {};\n"); 1326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapSnapshot* snapshot = 1327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("unknown_object_id")); 1328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot)); 1329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* node = 1330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch snapshot->GetNodeById(v8::HeapProfiler::kUnknownObjectId); 1331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(NULL, node); 1332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1335b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochnamespace { 1336b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1337b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass TestActivityControl : public v8::ActivityControl { 1338b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 1339b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch explicit TestActivityControl(int abort_count) 1340b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch : done_(0), total_(0), abort_count_(abort_count) {} 1341b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ControlOption ReportProgressValue(int done, int total) { 1342b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch done_ = done; 1343b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch total_ = total; 1344b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return --abort_count_ != 0 ? kContinue : kAbort; 1345b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1346b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int done() { return done_; } 1347b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int total() { return total_; } 1348b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1349b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private: 1350b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int done_; 1351b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int total_; 1352b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int abort_count_; 1353b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 1354b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1355b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1357b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochTEST(TakeHeapSnapshotAborting) { 1358b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch LocalContext env; 1359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 1360b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 1362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int snapshots_count = heap_profiler->GetSnapshotCount(); 13633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch TestActivityControl aborting_control(1); 1364b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const v8::HeapSnapshot* no_snapshot = 1365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("abort"), 1366b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch &aborting_control); 1367b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(NULL, no_snapshot); 1368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(snapshots_count, heap_profiler->GetSnapshotCount()); 1369b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_GT(aborting_control.total(), aborting_control.done()); 1370b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1371b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch TestActivityControl control(-1); // Don't abort. 1372b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const v8::HeapSnapshot* snapshot = 1373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("full"), 1374b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch &control); 1375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot)); 1376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1377b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_NE(NULL, snapshot); 1378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(snapshots_count + 1, heap_profiler->GetSnapshotCount()); 1379b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(control.total(), control.done()); 1380b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_GT(control.total(), 0); 1381b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1382b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 138344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 138444f0eee88ff00398ff7f715fab053374d808c90dSteve Blocknamespace { 138544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 138644f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass TestRetainedObjectInfo : public v8::RetainedObjectInfo { 138744f0eee88ff00398ff7f715fab053374d808c90dSteve Block public: 138844f0eee88ff00398ff7f715fab053374d808c90dSteve Block TestRetainedObjectInfo(int hash, 13893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const char* group_label, 139044f0eee88ff00398ff7f715fab053374d808c90dSteve Block const char* label, 139144f0eee88ff00398ff7f715fab053374d808c90dSteve Block intptr_t element_count = -1, 139244f0eee88ff00398ff7f715fab053374d808c90dSteve Block intptr_t size = -1) 139344f0eee88ff00398ff7f715fab053374d808c90dSteve Block : disposed_(false), 139444f0eee88ff00398ff7f715fab053374d808c90dSteve Block hash_(hash), 13953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch group_label_(group_label), 139644f0eee88ff00398ff7f715fab053374d808c90dSteve Block label_(label), 139744f0eee88ff00398ff7f715fab053374d808c90dSteve Block element_count_(element_count), 139844f0eee88ff00398ff7f715fab053374d808c90dSteve Block size_(size) { 139944f0eee88ff00398ff7f715fab053374d808c90dSteve Block instances.Add(this); 140044f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 140144f0eee88ff00398ff7f715fab053374d808c90dSteve Block virtual ~TestRetainedObjectInfo() {} 140244f0eee88ff00398ff7f715fab053374d808c90dSteve Block virtual void Dispose() { 140344f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK(!disposed_); 140444f0eee88ff00398ff7f715fab053374d808c90dSteve Block disposed_ = true; 140544f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 140644f0eee88ff00398ff7f715fab053374d808c90dSteve Block virtual bool IsEquivalent(RetainedObjectInfo* other) { 140744f0eee88ff00398ff7f715fab053374d808c90dSteve Block return GetHash() == other->GetHash(); 140844f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 140944f0eee88ff00398ff7f715fab053374d808c90dSteve Block virtual intptr_t GetHash() { return hash_; } 14103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual const char* GetGroupLabel() { return group_label_; } 141144f0eee88ff00398ff7f715fab053374d808c90dSteve Block virtual const char* GetLabel() { return label_; } 141244f0eee88ff00398ff7f715fab053374d808c90dSteve Block virtual intptr_t GetElementCount() { return element_count_; } 141344f0eee88ff00398ff7f715fab053374d808c90dSteve Block virtual intptr_t GetSizeInBytes() { return size_; } 141444f0eee88ff00398ff7f715fab053374d808c90dSteve Block bool disposed() { return disposed_; } 141544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 141644f0eee88ff00398ff7f715fab053374d808c90dSteve Block static v8::RetainedObjectInfo* WrapperInfoCallback( 141744f0eee88ff00398ff7f715fab053374d808c90dSteve Block uint16_t class_id, v8::Handle<v8::Value> wrapper) { 141844f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (class_id == 1) { 141944f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (wrapper->IsString()) { 1420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::Utf8Value utf8(wrapper); 1421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (strcmp(*utf8, "AAA") == 0) 14223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return new TestRetainedObjectInfo(1, "aaa-group", "aaa", 100); 1423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch else if (strcmp(*utf8, "BBB") == 0) 14243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return new TestRetainedObjectInfo(1, "aaa-group", "aaa", 100); 142544f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 142644f0eee88ff00398ff7f715fab053374d808c90dSteve Block } else if (class_id == 2) { 142744f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (wrapper->IsString()) { 1428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::Utf8Value utf8(wrapper); 1429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (strcmp(*utf8, "CCC") == 0) 14303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return new TestRetainedObjectInfo(2, "ccc-group", "ccc"); 143144f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 143244f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 143344f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK(false); 143444f0eee88ff00398ff7f715fab053374d808c90dSteve Block return NULL; 143544f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 143644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 143744f0eee88ff00398ff7f715fab053374d808c90dSteve Block static i::List<TestRetainedObjectInfo*> instances; 143844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 143944f0eee88ff00398ff7f715fab053374d808c90dSteve Block private: 144044f0eee88ff00398ff7f715fab053374d808c90dSteve Block bool disposed_; 144144f0eee88ff00398ff7f715fab053374d808c90dSteve Block int hash_; 14423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const char* group_label_; 144344f0eee88ff00398ff7f715fab053374d808c90dSteve Block const char* label_; 144444f0eee88ff00398ff7f715fab053374d808c90dSteve Block intptr_t element_count_; 144544f0eee88ff00398ff7f715fab053374d808c90dSteve Block intptr_t size_; 144644f0eee88ff00398ff7f715fab053374d808c90dSteve Block}; 144744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 144844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 144944f0eee88ff00398ff7f715fab053374d808c90dSteve Blocki::List<TestRetainedObjectInfo*> TestRetainedObjectInfo::instances; 145044f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 145144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 145244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 145344f0eee88ff00398ff7f715fab053374d808c90dSteve Blockstatic const v8::HeapGraphNode* GetNode(const v8::HeapGraphNode* parent, 145444f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::HeapGraphNode::Type type, 145544f0eee88ff00398ff7f715fab053374d808c90dSteve Block const char* name) { 145644f0eee88ff00398ff7f715fab053374d808c90dSteve Block for (int i = 0, count = parent->GetChildrenCount(); i < count; ++i) { 145744f0eee88ff00398ff7f715fab053374d808c90dSteve Block const v8::HeapGraphNode* node = parent->GetChild(i)->GetToNode(); 145844f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (node->GetType() == type && strcmp(name, 145944f0eee88ff00398ff7f715fab053374d808c90dSteve Block const_cast<i::HeapEntry*>( 146044f0eee88ff00398ff7f715fab053374d808c90dSteve Block reinterpret_cast<const i::HeapEntry*>(node))->name()) == 0) { 146144f0eee88ff00398ff7f715fab053374d808c90dSteve Block return node; 146244f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 146344f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 146444f0eee88ff00398ff7f715fab053374d808c90dSteve Block return NULL; 146544f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 146644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 146744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 146844f0eee88ff00398ff7f715fab053374d808c90dSteve BlockTEST(HeapSnapshotRetainedObjectInfo) { 146944f0eee88ff00398ff7f715fab053374d808c90dSteve Block LocalContext env; 1470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate = env->GetIsolate(); 1471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(isolate); 1472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = isolate->GetHeapProfiler(); 147344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 1474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->SetWrapperClassInfoProvider( 147544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 1, TestRetainedObjectInfo::WrapperInfoCallback); 1476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->SetWrapperClassInfoProvider( 147744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 2, TestRetainedObjectInfo::WrapperInfoCallback); 1478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Persistent<v8::String> p_AAA(isolate, v8_str("AAA")); 147944f0eee88ff00398ff7f715fab053374d808c90dSteve Block p_AAA.SetWrapperClassId(1); 1480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Persistent<v8::String> p_BBB(isolate, v8_str("BBB")); 148144f0eee88ff00398ff7f715fab053374d808c90dSteve Block p_BBB.SetWrapperClassId(1); 1482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Persistent<v8::String> p_CCC(isolate, v8_str("CCC")); 148344f0eee88ff00398ff7f715fab053374d808c90dSteve Block p_CCC.SetWrapperClassId(2); 148444f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(0, TestRetainedObjectInfo::instances.length()); 148544f0eee88ff00398ff7f715fab053374d808c90dSteve Block const v8::HeapSnapshot* snapshot = 1486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("retained")); 1487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot)); 148844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 148944f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(3, TestRetainedObjectInfo::instances.length()); 149044f0eee88ff00398ff7f715fab053374d808c90dSteve Block for (int i = 0; i < TestRetainedObjectInfo::instances.length(); ++i) { 149144f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK(TestRetainedObjectInfo::instances[i]->disposed()); 149244f0eee88ff00398ff7f715fab053374d808c90dSteve Block delete TestRetainedObjectInfo::instances[i]; 149344f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 149444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 14953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const v8::HeapGraphNode* native_group_aaa = GetNode( 14963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch snapshot->GetRoot(), v8::HeapGraphNode::kSynthetic, "aaa-group"); 14973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_NE(NULL, native_group_aaa); 14983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(1, native_group_aaa->GetChildrenCount()); 149944f0eee88ff00398ff7f715fab053374d808c90dSteve Block const v8::HeapGraphNode* aaa = GetNode( 15003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch native_group_aaa, v8::HeapGraphNode::kNative, "aaa / 100 entries"); 150144f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_NE(NULL, aaa); 15023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(2, aaa->GetChildrenCount()); 15033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const v8::HeapGraphNode* native_group_ccc = GetNode( 15053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch snapshot->GetRoot(), v8::HeapGraphNode::kSynthetic, "ccc-group"); 150644f0eee88ff00398ff7f715fab053374d808c90dSteve Block const v8::HeapGraphNode* ccc = GetNode( 15073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch native_group_ccc, v8::HeapGraphNode::kNative, "ccc"); 150844f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_NE(NULL, ccc); 150944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 151044f0eee88ff00398ff7f715fab053374d808c90dSteve Block const v8::HeapGraphNode* n_AAA = GetNode( 151144f0eee88ff00398ff7f715fab053374d808c90dSteve Block aaa, v8::HeapGraphNode::kString, "AAA"); 151244f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_NE(NULL, n_AAA); 151344f0eee88ff00398ff7f715fab053374d808c90dSteve Block const v8::HeapGraphNode* n_BBB = GetNode( 151444f0eee88ff00398ff7f715fab053374d808c90dSteve Block aaa, v8::HeapGraphNode::kString, "BBB"); 151544f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_NE(NULL, n_BBB); 151644f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(1, ccc->GetChildrenCount()); 151744f0eee88ff00398ff7f715fab053374d808c90dSteve Block const v8::HeapGraphNode* n_CCC = GetNode( 151844f0eee88ff00398ff7f715fab053374d808c90dSteve Block ccc, v8::HeapGraphNode::kString, "CCC"); 151944f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_NE(NULL, n_CCC); 152044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 15218b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch CHECK_EQ(aaa, GetProperty(n_AAA, v8::HeapGraphEdge::kInternal, "native")); 15228b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch CHECK_EQ(aaa, GetProperty(n_BBB, v8::HeapGraphEdge::kInternal, "native")); 15238b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch CHECK_EQ(ccc, GetProperty(n_CCC, v8::HeapGraphEdge::kInternal, "native")); 152444f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 152544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 152644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 15273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass GraphWithImplicitRefs { 15283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 15293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static const int kObjectsCount = 4; 15303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch explicit GraphWithImplicitRefs(LocalContext* env) { 15313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(NULL, instance_); 15323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch instance_ = this; 1533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_ = (*env)->GetIsolate(); 15343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < kObjectsCount; i++) { 1535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch objects_[i].Reset(isolate_, v8::Object::New(isolate_)); 15363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (*env)->Global()->Set(v8_str("root_object"), 1538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Value>::New(isolate_, objects_[0])); 15393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 15403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ~GraphWithImplicitRefs() { 15413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch instance_ = NULL; 15423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 15433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void gcPrologue(v8::GCType type, v8::GCCallbackFlags flags) { 15453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch instance_->AddImplicitReferences(); 15463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 15473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private: 15493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void AddImplicitReferences() { 15503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // 0 -> 1 1551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->SetObjectGroupId(objects_[0], 1552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::UniqueId(1)); 1553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->SetReferenceFromGroup( 1554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::UniqueId(1), objects_[1]); 1555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Adding two more references: 1 -> 2, 1 -> 3 1556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->SetReference(objects_[1].As<v8::Object>(), 1557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch objects_[2]); 1558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->SetReference(objects_[1].As<v8::Object>(), 1559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch objects_[3]); 15603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 15613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::Persistent<v8::Value> objects_[kObjectsCount]; 15633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static GraphWithImplicitRefs* instance_; 1564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate_; 15653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 15663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15673ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochGraphWithImplicitRefs* GraphWithImplicitRefs::instance_ = NULL; 15683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15703ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochTEST(HeapSnapshotImplicitReferences) { 15713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LocalContext env; 1572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 1573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 15743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GraphWithImplicitRefs graph(&env); 1576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::V8::AddGCPrologueCallback(&GraphWithImplicitRefs::gcPrologue); 15773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const v8::HeapSnapshot* snapshot = 1579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("implicit_refs")); 1580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot)); 15813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const v8::HeapGraphNode* global_object = GetGlobalObject(snapshot); 15833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const v8::HeapGraphNode* obj0 = GetProperty( 1584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch global_object, v8::HeapGraphEdge::kProperty, "root_object"); 15853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK(obj0); 15863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(v8::HeapGraphNode::kObject, obj0->GetType()); 15873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const v8::HeapGraphNode* obj1 = GetProperty( 15883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch obj0, v8::HeapGraphEdge::kInternal, "native"); 15893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK(obj1); 15903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int implicit_targets_count = 0; 15913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0, count = obj1->GetChildrenCount(); i < count; ++i) { 15923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const v8::HeapGraphEdge* prop = obj1->GetChild(i); 1593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::Utf8Value prop_name(prop->GetName()); 15943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (prop->GetType() == v8::HeapGraphEdge::kInternal && 15953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch strcmp("native", *prop_name) == 0) { 15963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ++implicit_targets_count; 15973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 15983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 15993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(2, implicit_targets_count); 1600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::V8::RemoveGCPrologueCallback(&GraphWithImplicitRefs::gcPrologue); 16013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 16023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 16033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 160444f0eee88ff00398ff7f715fab053374d808c90dSteve BlockTEST(DeleteAllHeapSnapshots) { 160544f0eee88ff00398ff7f715fab053374d808c90dSteve Block LocalContext env; 1606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 1607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 1608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0, heap_profiler->GetSnapshotCount()); 1610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->DeleteAllHeapSnapshots(); 1611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0, heap_profiler->GetSnapshotCount()); 1612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, heap_profiler->TakeHeapSnapshot(v8_str("1"))); 1613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1, heap_profiler->GetSnapshotCount()); 1614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->DeleteAllHeapSnapshots(); 1615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0, heap_profiler->GetSnapshotCount()); 1616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, heap_profiler->TakeHeapSnapshot(v8_str("1"))); 1617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, heap_profiler->TakeHeapSnapshot(v8_str("2"))); 1618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(2, heap_profiler->GetSnapshotCount()); 1619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->DeleteAllHeapSnapshots(); 1620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0, heap_profiler->GetSnapshotCount()); 1621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 162344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 1624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const v8::HeapSnapshot* FindHeapSnapshot(v8::HeapProfiler* profiler, 1625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned uid) { 1626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int length = profiler->GetSnapshotCount(); 1627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < length; i++) { 1628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapSnapshot* snapshot = profiler->GetHeapSnapshot(i); 1629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (snapshot->GetUid() == uid) { 1630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return snapshot; 1631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 163444f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 163544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 163644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 163744f0eee88ff00398ff7f715fab053374d808c90dSteve BlockTEST(DeleteHeapSnapshot) { 163844f0eee88ff00398ff7f715fab053374d808c90dSteve Block LocalContext env; 1639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 1640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 164144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 1642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0, heap_profiler->GetSnapshotCount()); 164344f0eee88ff00398ff7f715fab053374d808c90dSteve Block const v8::HeapSnapshot* s1 = 1644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("1")); 1645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 164644f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_NE(NULL, s1); 1647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1, heap_profiler->GetSnapshotCount()); 164844f0eee88ff00398ff7f715fab053374d808c90dSteve Block unsigned uid1 = s1->GetUid(); 1649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(s1, FindHeapSnapshot(heap_profiler, uid1)); 165044f0eee88ff00398ff7f715fab053374d808c90dSteve Block const_cast<v8::HeapSnapshot*>(s1)->Delete(); 1651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0, heap_profiler->GetSnapshotCount()); 1652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(NULL, FindHeapSnapshot(heap_profiler, uid1)); 165344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 165444f0eee88ff00398ff7f715fab053374d808c90dSteve Block const v8::HeapSnapshot* s2 = 1655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("2")); 165644f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_NE(NULL, s2); 1657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1, heap_profiler->GetSnapshotCount()); 165844f0eee88ff00398ff7f715fab053374d808c90dSteve Block unsigned uid2 = s2->GetUid(); 165944f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_NE(static_cast<int>(uid1), static_cast<int>(uid2)); 1660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(s2, FindHeapSnapshot(heap_profiler, uid2)); 166144f0eee88ff00398ff7f715fab053374d808c90dSteve Block const v8::HeapSnapshot* s3 = 1662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("3")); 166344f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_NE(NULL, s3); 1664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(2, heap_profiler->GetSnapshotCount()); 166544f0eee88ff00398ff7f715fab053374d808c90dSteve Block unsigned uid3 = s3->GetUid(); 166644f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_NE(static_cast<int>(uid1), static_cast<int>(uid3)); 1667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(s3, FindHeapSnapshot(heap_profiler, uid3)); 166844f0eee88ff00398ff7f715fab053374d808c90dSteve Block const_cast<v8::HeapSnapshot*>(s2)->Delete(); 1669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1, heap_profiler->GetSnapshotCount()); 1670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(NULL, FindHeapSnapshot(heap_profiler, uid2)); 1671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(s3, FindHeapSnapshot(heap_profiler, uid3)); 167244f0eee88ff00398ff7f715fab053374d808c90dSteve Block const_cast<v8::HeapSnapshot*>(s3)->Delete(); 1673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0, heap_profiler->GetSnapshotCount()); 1674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(NULL, FindHeapSnapshot(heap_profiler, uid3)); 167544f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 167644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 16773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass NameResolver : public v8::HeapProfiler::ObjectNameResolver { 1679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 1680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch virtual const char* GetName(v8::Handle<v8::Object> object) { 1681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return "Global object name"; 1682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 16843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 16853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(GlobalObjectName) { 16873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch LocalContext env; 1688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 1689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 16903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileRun("document = { URL:\"abcdefgh\" };"); 1692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NameResolver name_resolver; 16943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const v8::HeapSnapshot* snapshot = 1695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("document"), 1696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NULL, 1697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &name_resolver); 1698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot)); 16993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const v8::HeapGraphNode* global = GetGlobalObject(snapshot); 17003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CHECK_NE(NULL, global); 1701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ("Object / Global object name" , 17023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const_cast<i::HeapEntry*>( 17033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch reinterpret_cast<const i::HeapEntry*>(global))->name()); 17043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 17053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 17063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(GlobalObjectFields) { 17083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch LocalContext env; 1709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 1710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 1711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileRun("obj = {};"); 17123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const v8::HeapSnapshot* snapshot = 1713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("snapshot")); 1714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot)); 17153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const v8::HeapGraphNode* global = GetGlobalObject(snapshot); 1716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* builtins = 1717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(global, v8::HeapGraphEdge::kInternal, "builtins"); 1718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, builtins); 1719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* native_context = 1720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(global, v8::HeapGraphEdge::kInternal, "native_context"); 1721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, native_context); 1722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* global_context = 1723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(global, v8::HeapGraphEdge::kInternal, "global_context"); 1724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, global_context); 1725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* global_proxy = 1726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(global, v8::HeapGraphEdge::kInternal, "global_proxy"); 1727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, global_proxy); 17283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 17293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 17303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 17313ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochTEST(NoHandleLeaks) { 17323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LocalContext env; 1733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 1734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 17353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 17363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CompileRun("document = { URL:\"abcdefgh\" };"); 17373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 17383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::Handle<v8::String> name(v8_str("leakz")); 1739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch i::Isolate* isolate = CcTest::i_isolate(); 1740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int count_before = i::HandleScope::NumberOfHandles(isolate); 1741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(name); 1742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int count_after = i::HandleScope::NumberOfHandles(isolate); 17433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(count_before, count_after); 17443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 17453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 17463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 17473fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochTEST(NodesIteration) { 17483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch LocalContext env; 1749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 1750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 17513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const v8::HeapSnapshot* snapshot = 1752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("iteration")); 1753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot)); 17543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const v8::HeapGraphNode* global = GetGlobalObject(snapshot); 17553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CHECK_NE(NULL, global); 17563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Verify that we can find this object by iteration. 17573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const int nodes_count = snapshot->GetNodesCount(); 17583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int count = 0; 17593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for (int i = 0; i < nodes_count; ++i) { 17603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (snapshot->GetNode(i) == global) 17613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ++count; 17623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 17633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CHECK_EQ(1, count); 17643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 176569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 176669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 1767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(GetHeapValueForNode) { 176869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch LocalContext env; 1769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 1770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 177169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 1772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileRun("a = { s_prop: \'value\', n_prop: \'value2\' };"); 177369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch const v8::HeapSnapshot* snapshot = 1774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("value")); 1775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot)); 177669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch const v8::HeapGraphNode* global = GetGlobalObject(snapshot); 1777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(heap_profiler->FindObjectById(global->GetId())->IsObject()); 177869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::Local<v8::Object> js_global = 177969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch env->Global()->GetPrototype().As<v8::Object>(); 1780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(js_global == heap_profiler->FindObjectById(global->GetId())); 178169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch const v8::HeapGraphNode* obj = GetProperty( 1782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch global, v8::HeapGraphEdge::kProperty, "a"); 1783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(heap_profiler->FindObjectById(obj->GetId())->IsObject()); 178469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::Local<v8::Object> js_obj = js_global->Get(v8_str("a")).As<v8::Object>(); 1785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(js_obj == heap_profiler->FindObjectById(obj->GetId())); 178669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch const v8::HeapGraphNode* s_prop = 178769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch GetProperty(obj, v8::HeapGraphEdge::kProperty, "s_prop"); 178869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::Local<v8::String> js_s_prop = 178969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch js_obj->Get(v8_str("s_prop")).As<v8::String>(); 1790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(js_s_prop == heap_profiler->FindObjectById(s_prop->GetId())); 179169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch const v8::HeapGraphNode* n_prop = 179269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch GetProperty(obj, v8::HeapGraphEdge::kProperty, "n_prop"); 1793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::String> js_n_prop = 1794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch js_obj->Get(v8_str("n_prop")).As<v8::String>(); 1795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(js_n_prop == heap_profiler->FindObjectById(n_prop->GetId())); 179669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch} 179769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 179869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 179969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochTEST(GetHeapValueForDeletedObject) { 180069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch LocalContext env; 1801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 1802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 180369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 180469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // It is impossible to delete a global property, so we are about to delete a 180569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // property of the "a" object. Also, the "p" object can't be an empty one 180669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // because the empty object is static and isn't actually deleted. 180769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CompileRun("a = { p: { r: {} } };"); 180869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch const v8::HeapSnapshot* snapshot = 1809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("snapshot")); 1810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot)); 181169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch const v8::HeapGraphNode* global = GetGlobalObject(snapshot); 181269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch const v8::HeapGraphNode* obj = GetProperty( 1813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch global, v8::HeapGraphEdge::kProperty, "a"); 181469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch const v8::HeapGraphNode* prop = GetProperty( 181569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch obj, v8::HeapGraphEdge::kProperty, "p"); 181669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch { 181769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Perform the check inside a nested local scope to avoid creating a 181869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // reference to the object we are deleting. 1819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 1820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(heap_profiler->FindObjectById(prop->GetId())->IsObject()); 182169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 182269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CompileRun("delete a.p;"); 1823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(heap_profiler->FindObjectById(prop->GetId()).IsEmpty()); 182469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch} 182569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 182669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 182769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochstatic int StringCmp(const char* ref, i::String* act) { 1828589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch i::SmartArrayPointer<char> s_act = act->ToCString(); 1829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int result = strcmp(ref, s_act.get()); 183069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (result != 0) 1831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fprintf(stderr, "Expected: \"%s\", Actual: \"%s\"\n", ref, s_act.get()); 183269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return result; 183369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch} 183469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 183569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 183669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochTEST(GetConstructorName) { 183769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch LocalContext env; 1838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 183969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 184069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CompileRun( 184169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch "function Constructor1() {};\n" 184269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch "var obj1 = new Constructor1();\n" 184369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch "var Constructor2 = function() {};\n" 184469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch "var obj2 = new Constructor2();\n" 184569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch "var obj3 = {};\n" 184669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch "obj3.constructor = function Constructor3() {};\n" 184769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch "var obj4 = {};\n" 184869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch "// Slow properties\n" 184969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch "for (var i=0; i<2000; ++i) obj4[\"p\" + i] = i;\n" 185069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch "obj4.constructor = function Constructor4() {};\n" 185169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch "var obj5 = {};\n" 185269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch "var obj6 = {};\n" 185369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch "obj6.constructor = 6;"); 185469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::Local<v8::Object> js_global = 185569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch env->Global()->GetPrototype().As<v8::Object>(); 185669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::Local<v8::Object> obj1 = js_global->Get(v8_str("obj1")).As<v8::Object>(); 185769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch i::Handle<i::JSObject> js_obj1 = v8::Utils::OpenHandle(*obj1); 185869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CHECK_EQ(0, StringCmp( 185969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch "Constructor1", i::V8HeapExplorer::GetConstructorName(*js_obj1))); 186069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::Local<v8::Object> obj2 = js_global->Get(v8_str("obj2")).As<v8::Object>(); 186169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch i::Handle<i::JSObject> js_obj2 = v8::Utils::OpenHandle(*obj2); 186269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CHECK_EQ(0, StringCmp( 186369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch "Constructor2", i::V8HeapExplorer::GetConstructorName(*js_obj2))); 186469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::Local<v8::Object> obj3 = js_global->Get(v8_str("obj3")).As<v8::Object>(); 186569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch i::Handle<i::JSObject> js_obj3 = v8::Utils::OpenHandle(*obj3); 1866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(verwaest): Restore to Constructor3 once supported by the 1867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // heap-snapshot-generator. 1868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ( 1869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 0, StringCmp("Object", i::V8HeapExplorer::GetConstructorName(*js_obj3))); 187069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::Local<v8::Object> obj4 = js_global->Get(v8_str("obj4")).As<v8::Object>(); 187169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch i::Handle<i::JSObject> js_obj4 = v8::Utils::OpenHandle(*obj4); 1872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(verwaest): Restore to Constructor4 once supported by the 1873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // heap-snapshot-generator. 1874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ( 1875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 0, StringCmp("Object", i::V8HeapExplorer::GetConstructorName(*js_obj4))); 187669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::Local<v8::Object> obj5 = js_global->Get(v8_str("obj5")).As<v8::Object>(); 187769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch i::Handle<i::JSObject> js_obj5 = v8::Utils::OpenHandle(*obj5); 187869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CHECK_EQ(0, StringCmp( 187969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch "Object", i::V8HeapExplorer::GetConstructorName(*js_obj5))); 188069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::Local<v8::Object> obj6 = js_global->Get(v8_str("obj6")).As<v8::Object>(); 188169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch i::Handle<i::JSObject> js_obj6 = v8::Utils::OpenHandle(*obj6); 188269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CHECK_EQ(0, StringCmp( 188369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch "Object", i::V8HeapExplorer::GetConstructorName(*js_obj6))); 188469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch} 18853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 18863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(FastCaseAccessors) { 18883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LocalContext env; 1889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 1890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 18913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 18923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CompileRun("var obj1 = {};\n" 18933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "obj1.__defineGetter__('propWithGetter', function Y() {\n" 18943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch " return 42;\n" 18953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "});\n" 18963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "obj1.__defineSetter__('propWithSetter', function Z(value) {\n" 18973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch " return this.value_ = value;\n" 18983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "});\n"); 18993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const v8::HeapSnapshot* snapshot = 1900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("fastCaseAccessors")); 1901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot)); 19023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 19033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const v8::HeapGraphNode* global = GetGlobalObject(snapshot); 19043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_NE(NULL, global); 19053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const v8::HeapGraphNode* obj1 = 1906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(global, v8::HeapGraphEdge::kProperty, "obj1"); 19073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_NE(NULL, obj1); 1908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* func; 1909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch func = GetProperty(obj1, v8::HeapGraphEdge::kProperty, "get propWithGetter"); 1910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, func); 1911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch func = GetProperty(obj1, v8::HeapGraphEdge::kProperty, "set propWithGetter"); 1912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(NULL, func); 1913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch func = GetProperty(obj1, v8::HeapGraphEdge::kProperty, "set propWithSetter"); 1914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, func); 1915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch func = GetProperty(obj1, v8::HeapGraphEdge::kProperty, "get propWithSetter"); 1916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(NULL, func); 1917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(SlowCaseAccessors) { 1921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LocalContext env; 1922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 1923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 1924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileRun("var obj1 = {};\n" 1926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "for (var i = 0; i < 100; ++i) obj1['z' + i] = {};" 1927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "obj1.__defineGetter__('propWithGetter', function Y() {\n" 1928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " return 42;\n" 1929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "});\n" 1930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "obj1.__defineSetter__('propWithSetter', function Z(value) {\n" 1931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " return this.value_ = value;\n" 1932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "});\n"); 1933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapSnapshot* snapshot = 1934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("slowCaseAccessors")); 1935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot)); 1936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* global = GetGlobalObject(snapshot); 1938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, global); 1939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* obj1 = 1940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(global, v8::HeapGraphEdge::kProperty, "obj1"); 1941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, obj1); 1942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* func; 1943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch func = GetProperty(obj1, v8::HeapGraphEdge::kProperty, "get propWithGetter"); 1944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, func); 1945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch func = GetProperty(obj1, v8::HeapGraphEdge::kProperty, "set propWithGetter"); 1946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(NULL, func); 1947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch func = GetProperty(obj1, v8::HeapGraphEdge::kProperty, "set propWithSetter"); 1948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, func); 1949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch func = GetProperty(obj1, v8::HeapGraphEdge::kProperty, "get propWithSetter"); 1950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(NULL, func); 1951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(HiddenPropertiesFastCase) { 1955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LocalContext env; 1956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 1957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 1958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileRun( 1960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "function C(x) { this.a = this; this.b = x; }\n" 1961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "c = new C(2012);\n"); 1962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapSnapshot* snapshot = 1963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("HiddenPropertiesFastCase1")); 1964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot)); 1965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* global = GetGlobalObject(snapshot); 1966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* c = 1967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(global, v8::HeapGraphEdge::kProperty, "c"); 1968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, c); 1969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* hidden_props = 1970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(c, v8::HeapGraphEdge::kInternal, "hidden_properties"); 1971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(NULL, hidden_props); 1972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Value> cHandle = 1974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "c")); 1975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(!cHandle.IsEmpty() && cHandle->IsObject()); 1976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cHandle->ToObject()->SetHiddenValue(v8_str("key"), v8_str("val")); 1977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch snapshot = heap_profiler->TakeHeapSnapshot( 1979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8_str("HiddenPropertiesFastCase2")); 1980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot)); 1981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch global = GetGlobalObject(snapshot); 1982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch c = GetProperty(global, v8::HeapGraphEdge::kProperty, "c"); 1983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, c); 1984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch hidden_props = GetProperty(c, v8::HeapGraphEdge::kInternal, 1985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "hidden_properties"); 1986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, hidden_props); 1987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(AccessorInfo) { 1991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LocalContext env; 1992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 1993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 1994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileRun("function foo(x) { }\n"); 1996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapSnapshot* snapshot = 1997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("AccessorInfoTest")); 1998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot)); 1999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* global = GetGlobalObject(snapshot); 2000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* foo = 2001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(global, v8::HeapGraphEdge::kProperty, "foo"); 2002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, foo); 2003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* map = 2004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(foo, v8::HeapGraphEdge::kInternal, "map"); 2005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, map); 2006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* descriptors = 2007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(map, v8::HeapGraphEdge::kInternal, "descriptors"); 2008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, descriptors); 2009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* length_name = 2010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(descriptors, v8::HeapGraphEdge::kInternal, "2"); 2011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, length_name); 2012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ("length", *v8::String::Utf8Value(length_name->GetName())); 2013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* length_accessor = 2014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(descriptors, v8::HeapGraphEdge::kInternal, "4"); 2015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, length_accessor); 2016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ("system / ExecutableAccessorInfo", 2017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *v8::String::Utf8Value(length_accessor->GetName())); 2018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* name = 2019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(length_accessor, v8::HeapGraphEdge::kInternal, "name"); 2020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, name); 2021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* getter = 2022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(length_accessor, v8::HeapGraphEdge::kInternal, "getter"); 2023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, getter); 2024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* setter = 2025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(length_accessor, v8::HeapGraphEdge::kInternal, "setter"); 2026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, setter); 20273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 20283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 20293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 20303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool HasWeakEdge(const v8::HeapGraphNode* node) { 20313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < node->GetChildrenCount(); ++i) { 20323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const v8::HeapGraphEdge* handle_edge = node->GetChild(i); 20333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (handle_edge->GetType() == v8::HeapGraphEdge::kWeak) return true; 20343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 20353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return false; 20363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 20373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 20383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 20393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool HasWeakGlobalHandle() { 2040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate = CcTest::isolate(); 2041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = isolate->GetHeapProfiler(); 20423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const v8::HeapSnapshot* snapshot = 2043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("weaks")); 2044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot)); 20453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const v8::HeapGraphNode* gc_roots = GetNode( 2046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch snapshot->GetRoot(), v8::HeapGraphNode::kSynthetic, "(GC roots)"); 20473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_NE(NULL, gc_roots); 20483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const v8::HeapGraphNode* global_handles = GetNode( 2049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch gc_roots, v8::HeapGraphNode::kSynthetic, "(Global handles)"); 20503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_NE(NULL, global_handles); 20513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return HasWeakEdge(global_handles); 20523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 20533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 20543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void PersistentHandleCallback( 2056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::WeakCallbackData<v8::Object, v8::Persistent<v8::Object> >& data) { 2057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch data.GetParameter()->Reset(); 2058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch delete data.GetParameter(); 20593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 20603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 20613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 20623ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochTEST(WeakGlobalHandle) { 20633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LocalContext env; 2064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 20653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 20663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK(!HasWeakGlobalHandle()); 20673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Persistent<v8::Object> handle(env->GetIsolate(), 2069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Object::New(env->GetIsolate())); 2070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch handle.SetWeak(&handle, PersistentHandleCallback); 20713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 20723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK(HasWeakGlobalHandle()); 20733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 20743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 20753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(SfiAndJsFunctionWeakRefs) { 2077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LocalContext env; 2078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 2079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 2080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileRun( 2082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "fun = (function (x) { return function () { return x + 1; } })(1);"); 2083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapSnapshot* snapshot = 2084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("fun")); 2085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot)); 2086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* global = GetGlobalObject(snapshot); 2087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, global); 2088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* fun = 2089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(global, v8::HeapGraphEdge::kProperty, "fun"); 2090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(!HasWeakEdge(fun)); 2091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* shared = 2092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(fun, v8::HeapGraphEdge::kInternal, "shared"); 2093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(!HasWeakEdge(shared)); 2094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(NoDebugObjectInSnapshot) { 2098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LocalContext env; 2099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 2100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 2101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(CcTest::i_isolate()->debug()->Load()); 2103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileRun("foo = {};"); 2104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapSnapshot* snapshot = 2105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("snapshot")); 2106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot)); 2107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* root = snapshot->GetRoot(); 2108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int globals_count = 0; 2109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < root->GetChildrenCount(); ++i) { 2110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphEdge* edge = root->GetChild(i); 2111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (edge->GetType() == v8::HeapGraphEdge::kShortcut) { 2112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ++globals_count; 2113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* global = edge->GetToNode(); 2114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* foo = 2115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(global, v8::HeapGraphEdge::kProperty, "foo"); 2116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, foo); 2117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1, globals_count); 2120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(AllStrongGcRootsHaveNames) { 21243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LocalContext env; 2125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 2126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 21273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileRun("foo = {};"); 21293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const v8::HeapSnapshot* snapshot = 2130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("snapshot")); 2131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot)); 21323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const v8::HeapGraphNode* gc_roots = GetNode( 2133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch snapshot->GetRoot(), v8::HeapGraphNode::kSynthetic, "(GC roots)"); 21343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_NE(NULL, gc_roots); 2135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* strong_roots = GetNode( 2136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch gc_roots, v8::HeapGraphNode::kSynthetic, "(Strong roots)"); 2137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, strong_roots); 2138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < strong_roots->GetChildrenCount(); ++i) { 2139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphEdge* edge = strong_roots->GetChild(i); 2140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(v8::HeapGraphEdge::kInternal, edge->GetType()); 2141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::Utf8Value name(edge->GetName()); 2142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(isalpha(**name)); 2143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 21443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 21453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 21463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(NoRefsToNonEssentialEntries) { 2148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LocalContext env; 2149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 2150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 2151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileRun("global_object = {};\n"); 2152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapSnapshot* snapshot = 2153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("snapshot")); 2154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot)); 2155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* global = GetGlobalObject(snapshot); 2156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* global_object = 2157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(global, v8::HeapGraphEdge::kProperty, "global_object"); 2158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, global_object); 2159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* properties = 2160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(global_object, v8::HeapGraphEdge::kInternal, "properties"); 2161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(NULL, properties); 2162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* elements = 2163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(global_object, v8::HeapGraphEdge::kInternal, "elements"); 2164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(NULL, elements); 2165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(MapHasDescriptorsAndTransitions) { 21693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LocalContext env; 2170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 2171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 2172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileRun("obj = { a: 10 };\n"); 2173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapSnapshot* snapshot = 2174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("snapshot")); 2175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot)); 2176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* global = GetGlobalObject(snapshot); 2177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* global_object = 2178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(global, v8::HeapGraphEdge::kProperty, "obj"); 2179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, global_object); 2180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* map = 2182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(global_object, v8::HeapGraphEdge::kInternal, "map"); 2183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, map); 2184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* own_descriptors = GetProperty( 2185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map, v8::HeapGraphEdge::kInternal, "descriptors"); 2186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, own_descriptors); 2187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* own_transitions = GetProperty( 2188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map, v8::HeapGraphEdge::kInternal, "transitions"); 2189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(NULL, own_transitions); 2190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 21923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(ManyLocalsInSharedContext) { 2194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LocalContext env; 2195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 2196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 2197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int num_objects = 6000; 21983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CompileRun( 2199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "var n = 6000;" 2200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "var result = [];" 2201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "result.push('(function outer() {');" 2202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "for (var i = 0; i < n; i++) {" 2203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " var f = 'function f_' + i + '() { ';" 2204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " if (i > 0)" 2205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " f += 'f_' + (i - 1) + '();';" 2206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " f += ' }';" 2207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " result.push(f);" 2208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "}" 2209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "result.push('return f_' + (n - 1) + ';');" 2210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "result.push('})()');" 2211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "var ok = eval(result.join('\\n'));"); 22123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const v8::HeapSnapshot* snapshot = 2213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("snapshot")); 2214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot)); 2215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 22163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const v8::HeapGraphNode* global = GetGlobalObject(snapshot); 22173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_NE(NULL, global); 2218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* ok_object = 2219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(global, v8::HeapGraphEdge::kProperty, "ok"); 2220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, ok_object); 2221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* context_object = 2222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(ok_object, v8::HeapGraphEdge::kInternal, "context"); 2223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, context_object); 2224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check the objects are not duplicated in the context. 2225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(v8::internal::Context::MIN_CONTEXT_SLOTS + num_objects - 1, 2226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context_object->GetChildrenCount()); 2227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check all the objects have got their names. 2228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // ... well check just every 15th because otherwise it's too slow in debug. 2229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < num_objects - 1; i += 15) { 2230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch i::EmbeddedVector<char, 100> var_name; 2231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch i::SNPrintF(var_name, "f_%d", i); 2232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* f_object = GetProperty( 2233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context_object, v8::HeapGraphEdge::kContextVariable, var_name.start()); 2234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, f_object); 2235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 22363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 22373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 22383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(AllocationSitesAreVisible) { 22403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LocalContext env; 2241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate = env->GetIsolate(); 2242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(isolate); 2243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = isolate->GetHeapProfiler(); 2244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileRun( 2245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "fun = function () { var a = [3, 2, 1]; return a; }\n" 2246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "fun();"); 2247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapSnapshot* snapshot = 2248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("snapshot")); 2249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot)); 2250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* global = GetGlobalObject(snapshot); 2252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, global); 2253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* fun_code = 2254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(global, v8::HeapGraphEdge::kProperty, "fun"); 2255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, fun_code); 2256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* literals = 2257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(fun_code, v8::HeapGraphEdge::kInternal, "literals"); 2258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, literals); 2259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(v8::HeapGraphNode::kArray, literals->GetType()); 2260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(2, literals->GetChildrenCount()); 2261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The second value in the literals array should be the boilerplate, 2263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // after an AllocationSite. 2264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphEdge* prop = literals->GetChild(1); 2265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* allocation_site = prop->GetToNode(); 2266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::Utf8Value name(allocation_site->GetName()); 2267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ("system / AllocationSite", *name); 2268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* transition_info = 2269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(allocation_site, v8::HeapGraphEdge::kInternal, 2270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "transition_info"); 2271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, transition_info); 2272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* elements = 2274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(transition_info, v8::HeapGraphEdge::kInternal, 2275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "elements"); 2276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, elements); 2277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(v8::HeapGraphNode::kArray, elements->GetType()); 2278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(v8::internal::FixedArray::SizeFor(3), 2279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int>(elements->GetShallowSize())); 2280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Value> array_val = 2282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->FindObjectById(transition_info->GetId()); 2283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(array_val->IsArray()); 2284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(array_val); 2285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Verify the array is "a" in the code above. 2286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(3, array->Length()); 2287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(v8::Integer::New(isolate, 3), 2288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch array->Get(v8::Integer::New(isolate, 0))); 2289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(v8::Integer::New(isolate, 2), 2290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch array->Get(v8::Integer::New(isolate, 1))); 2291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(v8::Integer::New(isolate, 1), 2292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch array->Get(v8::Integer::New(isolate, 2))); 2293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(JSFunctionHasCodeLink) { 2297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LocalContext env; 2298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 2299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 2300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileRun("function foo(x, y) { return x + y; }\n"); 2301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapSnapshot* snapshot = 2302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("snapshot")); 2303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot)); 2304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* global = GetGlobalObject(snapshot); 2305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* foo_func = 2306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(global, v8::HeapGraphEdge::kProperty, "foo"); 2307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, foo_func); 2308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* code = 2309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(foo_func, v8::HeapGraphEdge::kInternal, "code"); 2310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, code); 2311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const v8::HeapGraphNode* GetNodeByPath(const v8::HeapSnapshot* snapshot, 2315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* path[], 2316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int depth) { 2317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* node = snapshot->GetRoot(); 2318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int current_depth = 0; current_depth < depth; ++current_depth) { 2319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int i, count = node->GetChildrenCount(); 2320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (i = 0; i < count; ++i) { 2321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphEdge* edge = node->GetChild(i); 2322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* to_node = edge->GetToNode(); 2323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::Utf8Value edge_name(edge->GetName()); 2324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::Utf8Value node_name(to_node->GetName()); 2325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch i::EmbeddedVector<char, 100> name; 2326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch i::SNPrintF(name, "%s::%s", *edge_name, *node_name); 2327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (strstr(name.start(), path[current_depth])) { 2328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch node = to_node; 2329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 2330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (i == count) return NULL; 2333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return node; 2335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(CheckCodeNames) { 2339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LocalContext env; 2340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 2341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 2342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileRun("var a = 1.1;"); 2343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapSnapshot* snapshot = 2344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("CheckCodeNames")); 2345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot)); 2346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* stub_path[] = { 2348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "::(GC roots)", 2349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "::(Strong roots)", 2350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "code_stubs::", 2351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "::(ArraySingleArgumentConstructorStub code)" 2352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 2353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* node = GetNodeByPath(snapshot, 2354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch stub_path, arraysize(stub_path)); 2355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, node); 2356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* builtin_path1[] = { 2358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "::(GC roots)", 2359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "::(Builtins)", 2360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "::(KeyedLoadIC_Generic builtin)" 2361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 2362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch node = GetNodeByPath(snapshot, builtin_path1, arraysize(builtin_path1)); 2363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, node); 2364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* builtin_path2[] = {"::(GC roots)", "::(Builtins)", 2366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "::(CompileLazy builtin)"}; 2367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch node = GetNodeByPath(snapshot, builtin_path2, arraysize(builtin_path2)); 2368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, node); 2369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::Utf8Value node_name(node->GetName()); 2370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ("(CompileLazy builtin)", *node_name); 2371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const char* record_trace_tree_source = 2375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch"var topFunctions = [];\n" 2376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch"var global = this;\n" 2377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch"function generateFunctions(width, depth) {\n" 2378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch" var script = [];\n" 2379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch" for (var i = 0; i < width; i++) {\n" 2380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch" for (var j = 0; j < depth; j++) {\n" 2381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch" script.push('function f_' + i + '_' + j + '(x) {\\n');\n" 2382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch" script.push(' try {\\n');\n" 2383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch" if (j < depth-2) {\n" 2384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch" script.push(' return f_' + i + '_' + (j+1) + '(x+1);\\n');\n" 2385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch" } else if (j == depth - 2) {\n" 2386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch" script.push(' return new f_' + i + '_' + (depth - 1) + '();\\n');\n" 2387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch" } else if (j == depth - 1) {\n" 2388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch" script.push(' this.ts = Date.now();\\n');\n" 2389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch" }\n" 2390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch" script.push(' } catch (e) {}\\n');\n" 2391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch" script.push('}\\n');\n" 2392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch" \n" 2393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch" }\n" 2394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch" }\n" 2395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch" var script = script.join('');\n" 2396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch" // throw script;\n" 2397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch" global.eval(script);\n" 2398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch" for (var i = 0; i < width; i++) {\n" 2399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch" topFunctions.push(this['f_' + i + '_0']);\n" 2400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch" }\n" 2401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch"}\n" 2402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch"\n" 2403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch"var width = 3;\n" 2404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch"var depth = 3;\n" 2405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch"generateFunctions(width, depth);\n" 2406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch"var instances = [];\n" 2407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch"function start() {\n" 2408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch" for (var i = 0; i < width; i++) {\n" 2409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch" instances.push(topFunctions[i](0));\n" 2410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch" }\n" 2411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch"}\n" 2412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch"\n" 2413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch"for (var i = 0; i < 100; i++) start();\n"; 2414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic AllocationTraceNode* FindNode( 2417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationTracker* tracker, const Vector<const char*>& names) { 2418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationTraceNode* node = tracker->trace_tree()->root(); 2419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; node != NULL && i < names.length(); i++) { 2420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* name = names[i]; 2421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Vector<AllocationTraceNode*> children = node->children(); 2422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch node = NULL; 2423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int j = 0; j < children.length(); j++) { 2424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned index = children[j]->function_info_index(); 2425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationTracker::FunctionInfo* info = 2426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch tracker->function_info_list()[index]; 2427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (info && strcmp(info->name, name) == 0) { 2428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch node = children[j]; 2429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 2430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return node; 2434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(ArrayGrowLeftTrim) { 2438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LocalContext env; 2439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 2440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 2441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->StartTrackingHeapObjects(true); 2442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileRun( 2444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "var a = [];\n" 2445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "for (var i = 0; i < 5; ++i)\n" 2446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " a[i] = i;\n" 2447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "for (var i = 0; i < 3; ++i)\n" 2448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " a.shift();\n"); 2449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* names[] = {""}; 2451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationTracker* tracker = 2452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<i::HeapProfiler*>(heap_profiler)->allocation_tracker(); 2453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, tracker); 2454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Resolve all function locations. 2455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch tracker->PrepareForSerialization(); 2456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Print for better diagnostics in case of failure. 2457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch tracker->trace_tree()->Print(tracker); 2458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationTraceNode* node = 2460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FindNode(tracker, Vector<const char*>(names, arraysize(names))); 2461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, node); 2462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_GE(node->allocation_count(), 2); 2463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_GE(node->allocation_size(), 4 * 5); 2464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->StopTrackingHeapObjects(); 2465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(TrackHeapAllocations) { 2469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(v8::Isolate::GetCurrent()); 2470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LocalContext env; 2471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 2473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->StartTrackingHeapObjects(true); 2474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileRun(record_trace_tree_source); 2476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationTracker* tracker = 2478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<i::HeapProfiler*>(heap_profiler)->allocation_tracker(); 2479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, tracker); 2480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Resolve all function locations. 2481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch tracker->PrepareForSerialization(); 2482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Print for better diagnostics in case of failure. 2483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch tracker->trace_tree()->Print(tracker); 2484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* names[] = {"", "start", "f_0_0", "f_0_1", "f_0_2"}; 2486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationTraceNode* node = 2487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FindNode(tracker, Vector<const char*>(names, arraysize(names))); 2488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, node); 2489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_GE(node->allocation_count(), 100); 2490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_GE(node->allocation_size(), 4 * node->allocation_count()); 2491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->StopTrackingHeapObjects(); 2492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const char* inline_heap_allocation_source = 2496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch"function f_0(x) {\n" 2497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch" return f_1(x+1);\n" 2498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch"}\n" 2499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch"%NeverOptimizeFunction(f_0);\n" 2500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch"function f_1(x) {\n" 2501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch" return new f_2(x+1);\n" 2502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch"}\n" 2503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch"function f_2(x) {\n" 2504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch" this.foo = x;\n" 2505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch"}\n" 2506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch"var instances = [];\n" 2507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch"function start() {\n" 2508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch" instances.push(f_0(0));\n" 2509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch"}\n" 2510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch"\n" 2511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch"for (var i = 0; i < 100; i++) start();\n"; 2512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(TrackBumpPointerAllocations) { 2515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch i::FLAG_allow_natives_syntax = true; 2516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(v8::Isolate::GetCurrent()); 2517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LocalContext env; 2518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 2520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* names[] = {"", "start", "f_0", "f_1"}; 2521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // First check that normally all allocations are recorded. 2522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 2523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->StartTrackingHeapObjects(true); 2524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileRun(inline_heap_allocation_source); 2526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationTracker* tracker = 2528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<i::HeapProfiler*>(heap_profiler)->allocation_tracker(); 2529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, tracker); 2530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Resolve all function locations. 2531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch tracker->PrepareForSerialization(); 2532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Print for better diagnostics in case of failure. 2533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch tracker->trace_tree()->Print(tracker); 2534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationTraceNode* node = 2536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FindNode(tracker, Vector<const char*>(names, arraysize(names))); 2537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, node); 2538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_GE(node->allocation_count(), 100); 2539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_GE(node->allocation_size(), 4 * node->allocation_count()); 2540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->StopTrackingHeapObjects(); 2541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 2544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->StartTrackingHeapObjects(true); 2545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Now check that not all allocations are tracked if we manually reenable 2547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // inline allocations. 2548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(CcTest::heap()->inline_allocation_disabled()); 2549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::heap()->EnableInlineAllocation(); 2550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileRun(inline_heap_allocation_source); 2552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationTracker* tracker = 2554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<i::HeapProfiler*>(heap_profiler)->allocation_tracker(); 2555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, tracker); 2556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Resolve all function locations. 2557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch tracker->PrepareForSerialization(); 2558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Print for better diagnostics in case of failure. 2559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch tracker->trace_tree()->Print(tracker); 2560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationTraceNode* node = 2562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FindNode(tracker, Vector<const char*>(names, arraysize(names))); 2563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, node); 2564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_LT(node->allocation_count(), 100); 2565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::heap()->DisableInlineAllocation(); 2567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->StopTrackingHeapObjects(); 2568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(TrackV8ApiAllocation) { 2573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(v8::Isolate::GetCurrent()); 2574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LocalContext env; 2575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 2577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* names[] = { "(V8 API)" }; 2578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->StartTrackingHeapObjects(true); 2579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Object> o1 = v8::Object::New(env->GetIsolate()); 2581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch o1->Clone(); 2582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationTracker* tracker = 2584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<i::HeapProfiler*>(heap_profiler)->allocation_tracker(); 2585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, tracker); 2586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Resolve all function locations. 2587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch tracker->PrepareForSerialization(); 2588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Print for better diagnostics in case of failure. 2589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch tracker->trace_tree()->Print(tracker); 2590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationTraceNode* node = 2592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FindNode(tracker, Vector<const char*>(names, arraysize(names))); 2593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, node); 2594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_GE(node->allocation_count(), 2); 2595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_GE(node->allocation_size(), 4 * node->allocation_count()); 2596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->StopTrackingHeapObjects(); 2597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(ArrayBufferAndArrayBufferView) { 2601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LocalContext env; 2602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 2603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 2604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileRun("arr1 = new Uint32Array(100);\n"); 2605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapSnapshot* snapshot = 2606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("snapshot")); 2607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot)); 2608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* global = GetGlobalObject(snapshot); 2609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* arr1_obj = 2610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(global, v8::HeapGraphEdge::kProperty, "arr1"); 2611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, arr1_obj); 2612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* arr1_buffer = 2613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(arr1_obj, v8::HeapGraphEdge::kInternal, "buffer"); 2614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, arr1_buffer); 2615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* first_view = 2616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(arr1_buffer, v8::HeapGraphEdge::kWeak, "weak_first_view"); 2617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, first_view); 2618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* backing_store = 2619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(arr1_buffer, v8::HeapGraphEdge::kInternal, "backing_store"); 2620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, backing_store); 2621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(400, static_cast<int>(backing_store->GetShallowSize())); 2622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic int GetRetainersCount(const v8::HeapSnapshot* snapshot, 2626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* node) { 2627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int count = 0; 2628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0, l = snapshot->GetNodesCount(); i < l; ++i) { 2629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* parent = snapshot->GetNode(i); 2630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int j = 0, l2 = parent->GetChildrenCount(); j < l2; ++j) { 2631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (parent->GetChild(j)->GetToNode() == node) { 2632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ++count; 2633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return count; 2637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(ArrayBufferSharedBackingStore) { 2641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LocalContext env; 2642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate = env->GetIsolate(); 2643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope handle_scope(isolate); 2644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = isolate->GetHeapProfiler(); 2645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(isolate, 1024); 2647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1024, static_cast<int>(ab->ByteLength())); 2648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(!ab->IsExternal()); 2649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::ArrayBuffer::Contents ab_contents = ab->Externalize(); 2650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ab->IsExternal()); 2651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1024, static_cast<int>(ab_contents.ByteLength())); 2653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void* data = ab_contents.Data(); 2654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(data != NULL); 2655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::ArrayBuffer> ab2 = 2656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::ArrayBuffer::New(isolate, data, ab_contents.ByteLength()); 2657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ab2->IsExternal()); 2658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Set(v8_str("ab1"), ab); 2659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Set(v8_str("ab2"), ab2); 2660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Value> result = CompileRun("ab2.byteLength"); 2662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1024, result->Int32Value()); 2663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapSnapshot* snapshot = 2665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("snapshot")); 2666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot)); 2667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* global = GetGlobalObject(snapshot); 2668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* ab1_node = 2669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(global, v8::HeapGraphEdge::kProperty, "ab1"); 2670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, ab1_node); 2671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* ab1_data = 2672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(ab1_node, v8::HeapGraphEdge::kInternal, "backing_store"); 2673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, ab1_data); 2674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* ab2_node = 2675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(global, v8::HeapGraphEdge::kProperty, "ab2"); 2676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, ab2_node); 2677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* ab2_data = 2678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(ab2_node, v8::HeapGraphEdge::kInternal, "backing_store"); 2679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, ab2_data); 2680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(ab1_data, ab2_data); 2681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(2, GetRetainersCount(snapshot, ab1_data)); 2682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch free(data); 2683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(BoxObject) { 2687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate = CcTest::isolate(); 2688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(isolate); 2689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LocalContext env; 2690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Object> global_proxy = env->Global(); 2691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Object> global = global_proxy->GetPrototype().As<v8::Object>(); 2692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch i::Factory* factory = CcTest::i_isolate()->factory(); 2694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch i::Handle<i::String> string = factory->NewStringFromStaticChars("string"); 2695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch i::Handle<i::Object> box = factory->NewBox(string); 2696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch global->Set(0, v8::ToApiHandle<v8::Object>(box)); 2697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = isolate->GetHeapProfiler(); 2699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapSnapshot* snapshot = 2700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("snapshot")); 2701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot)); 2702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* global_node = GetGlobalObject(snapshot); 2703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* box_node = 2704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(global_node, v8::HeapGraphEdge::kElement, "0"); 2705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, box_node); 2706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::Utf8Value box_node_name(box_node->GetName()); 2707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ("system / Box", *box_node_name); 2708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* box_value = 2709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(box_node, v8::HeapGraphEdge::kInternal, "value"); 2710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, box_value); 2711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(WeakContainers) { 2715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch i::FLAG_allow_natives_syntax = true; 2716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LocalContext env; 2717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 2718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!CcTest::i_isolate()->use_crankshaft()) return; 2719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); 2720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileRun( 2721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "function foo(a) { return a.x; }\n" 2722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "obj = {x : 123};\n" 2723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "foo(obj);\n" 2724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "foo(obj);\n" 2725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "%OptimizeFunctionOnNextCall(foo);\n" 2726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "foo(obj);\n"); 2727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapSnapshot* snapshot = 2728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap_profiler->TakeHeapSnapshot(v8_str("snapshot")); 2729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(ValidateSnapshot(snapshot)); 2730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* global = GetGlobalObject(snapshot); 2731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* obj = 2732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(global, v8::HeapGraphEdge::kProperty, "obj"); 2733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, obj); 2734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* map = 2735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(obj, v8::HeapGraphEdge::kInternal, "map"); 2736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(NULL, map); 2737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphNode* dependent_code = 2738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetProperty(map, v8::HeapGraphEdge::kInternal, "dependent_code"); 2739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!dependent_code) return; 2740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int count = dependent_code->GetChildrenCount(); 2741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(0, count); 2742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < count; ++i) { 2743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::HeapGraphEdge* prop = dependent_code->GetChild(i); 2744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(v8::HeapGraphEdge::kWeak, prop->GetType()); 2745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic inline i::Address ToAddress(int n) { 2750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return reinterpret_cast<i::Address>(n); 2751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 27533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(AddressToTraceMap) { 2755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch i::AddressToTraceMap map; 2756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0, map.GetTraceNodeId(ToAddress(150))); 2758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // [0x100, 0x200) -> 1 2760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map.AddRange(ToAddress(0x100), 0x100, 1U); 2761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0, map.GetTraceNodeId(ToAddress(0x50))); 2762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1, map.GetTraceNodeId(ToAddress(0x100))); 2763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1, map.GetTraceNodeId(ToAddress(0x150))); 2764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0, map.GetTraceNodeId(ToAddress(0x100 + 0x100))); 2765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1, static_cast<int>(map.size())); 2766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // [0x100, 0x200) -> 1, [0x200, 0x300) -> 2 2768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map.AddRange(ToAddress(0x200), 0x100, 2U); 2769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(2, map.GetTraceNodeId(ToAddress(0x2a0))); 2770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(2, static_cast<int>(map.size())); 2771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // [0x100, 0x180) -> 1, [0x180, 0x280) -> 3, [0x280, 0x300) -> 2 2773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map.AddRange(ToAddress(0x180), 0x100, 3U); 2774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1, map.GetTraceNodeId(ToAddress(0x17F))); 2775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(2, map.GetTraceNodeId(ToAddress(0x280))); 2776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(3, map.GetTraceNodeId(ToAddress(0x180))); 2777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(3, static_cast<int>(map.size())); 2778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // [0x100, 0x180) -> 1, [0x180, 0x280) -> 3, [0x280, 0x300) -> 2, 2780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // [0x400, 0x500) -> 4 2781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map.AddRange(ToAddress(0x400), 0x100, 4U); 2782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1, map.GetTraceNodeId(ToAddress(0x17F))); 2783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(2, map.GetTraceNodeId(ToAddress(0x280))); 2784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(3, map.GetTraceNodeId(ToAddress(0x180))); 2785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(4, map.GetTraceNodeId(ToAddress(0x450))); 2786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0, map.GetTraceNodeId(ToAddress(0x500))); 2787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0, map.GetTraceNodeId(ToAddress(0x350))); 2788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(4, static_cast<int>(map.size())); 2789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // [0x100, 0x180) -> 1, [0x180, 0x200) -> 3, [0x200, 0x600) -> 5 2791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map.AddRange(ToAddress(0x200), 0x400, 5U); 2792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(5, map.GetTraceNodeId(ToAddress(0x200))); 2793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(5, map.GetTraceNodeId(ToAddress(0x400))); 2794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(3, static_cast<int>(map.size())); 2795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // [0x100, 0x180) -> 1, [0x180, 0x200) -> 7, [0x200, 0x600) ->5 2797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map.AddRange(ToAddress(0x180), 0x80, 6U); 2798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map.AddRange(ToAddress(0x180), 0x80, 7U); 2799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(7, map.GetTraceNodeId(ToAddress(0x180))); 2800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(5, map.GetTraceNodeId(ToAddress(0x200))); 2801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(3, static_cast<int>(map.size())); 2802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map.Clear(); 2804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0, static_cast<int>(map.size())); 2805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0, map.GetTraceNodeId(ToAddress(0x400))); 28063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 2807