| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // | 2 // |
| 3 // Tests for heap profiler | 3 // Tests for heap profiler |
| 4 | 4 |
| 5 #include "v8.h" | 5 #include "v8.h" |
| 6 | 6 |
| 7 #include "cctest.h" | 7 #include "cctest.h" |
| 8 #include "heap-profiler.h" | 8 #include "heap-profiler.h" |
| 9 #include "snapshot.h" | 9 #include "snapshot.h" |
| 10 #include "utils-inl.h" | 10 #include "utils-inl.h" |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 102 "var c2 = new C2(a2);"); | 102 "var c2 = new C2(a2);"); |
| 103 const v8::HeapSnapshot* snapshot_env2 = | 103 const v8::HeapSnapshot* snapshot_env2 = |
| 104 v8::HeapProfiler::TakeSnapshot(v8_str("env2")); | 104 v8::HeapProfiler::TakeSnapshot(v8_str("env2")); |
| 105 i::HeapSnapshot* i_snapshot_env2 = | 105 i::HeapSnapshot* i_snapshot_env2 = |
| 106 const_cast<i::HeapSnapshot*>( | 106 const_cast<i::HeapSnapshot*>( |
| 107 reinterpret_cast<const i::HeapSnapshot*>(snapshot_env2)); | 107 reinterpret_cast<const i::HeapSnapshot*>(snapshot_env2)); |
| 108 const v8::HeapGraphNode* global_env2 = GetGlobalObject(snapshot_env2); | 108 const v8::HeapGraphNode* global_env2 = GetGlobalObject(snapshot_env2); |
| 109 | 109 |
| 110 // Verify, that JS global object of env2 has '..2' properties. | 110 // Verify, that JS global object of env2 has '..2' properties. |
| 111 const v8::HeapGraphNode* a2_node = | 111 const v8::HeapGraphNode* a2_node = |
| 112 GetProperty(global_env2, v8::HeapGraphEdge::kShortcut, "a2"); | 112 GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "a2"); |
| 113 CHECK_NE(NULL, a2_node); | 113 CHECK_NE(NULL, a2_node); |
| 114 CHECK_NE( | 114 CHECK_NE( |
| 115 NULL, GetProperty(global_env2, v8::HeapGraphEdge::kShortcut, "b2_1")); | 115 NULL, GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "b2_1")); |
| 116 CHECK_NE( | 116 CHECK_NE( |
| 117 NULL, GetProperty(global_env2, v8::HeapGraphEdge::kShortcut, "b2_2")); | 117 NULL, GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "b2_2")); |
| 118 CHECK_NE(NULL, GetProperty(global_env2, v8::HeapGraphEdge::kShortcut, "c2")); | 118 CHECK_NE(NULL, GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "c2")); |
| 119 | 119 |
| 120 // Paint all nodes reachable from global object. | 120 // Paint all nodes reachable from global object. |
| 121 NamedEntriesDetector det; | 121 NamedEntriesDetector det; |
| 122 i_snapshot_env2->ClearPaint(); | 122 i_snapshot_env2->ClearPaint(); |
| 123 det.CheckAllReachables(const_cast<i::HeapEntry*>( | 123 det.CheckAllReachables(const_cast<i::HeapEntry*>( |
| 124 reinterpret_cast<const i::HeapEntry*>(global_env2))); | 124 reinterpret_cast<const i::HeapEntry*>(global_env2))); |
| 125 CHECK(det.has_A2); | 125 CHECK(det.has_A2); |
| 126 CHECK(det.has_B2); | 126 CHECK(det.has_B2); |
| 127 CHECK(det.has_C2); | 127 CHECK(det.has_C2); |
| 128 } | 128 } |
| 129 | 129 |
| 130 | 130 |
| 131 TEST(HeapSnapshotObjectSizes) { | 131 TEST(HeapSnapshotObjectSizes) { |
| 132 v8::HandleScope scope; | 132 v8::HandleScope scope; |
| 133 LocalContext env; | 133 LocalContext env; |
| 134 | 134 |
| 135 // -a-> X1 --a | 135 // -a-> X1 --a |
| 136 // x -b-> X2 <-| | 136 // x -b-> X2 <-| |
| 137 CompileRun( | 137 CompileRun( |
| 138 "function X(a, b) { this.a = a; this.b = b; }\n" | 138 "function X(a, b) { this.a = a; this.b = b; }\n" |
| 139 "x = new X(new X(), new X());\n" | 139 "x = new X(new X(), new X());\n" |
| 140 "(function() { x.a.a = x.b; })();"); | 140 "(function() { x.a.a = x.b; })();"); |
| 141 const v8::HeapSnapshot* snapshot = | 141 const v8::HeapSnapshot* snapshot = |
| 142 v8::HeapProfiler::TakeSnapshot(v8_str("sizes")); | 142 v8::HeapProfiler::TakeSnapshot(v8_str("sizes")); |
| 143 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); | 143 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 144 const v8::HeapGraphNode* x = | 144 const v8::HeapGraphNode* x = |
| 145 GetProperty(global, v8::HeapGraphEdge::kShortcut, "x"); | 145 GetProperty(global, v8::HeapGraphEdge::kProperty, "x"); |
| 146 CHECK_NE(NULL, x); | 146 CHECK_NE(NULL, x); |
| 147 const v8::HeapGraphNode* x1 = | 147 const v8::HeapGraphNode* x1 = |
| 148 GetProperty(x, v8::HeapGraphEdge::kProperty, "a"); | 148 GetProperty(x, v8::HeapGraphEdge::kProperty, "a"); |
| 149 CHECK_NE(NULL, x1); | 149 CHECK_NE(NULL, x1); |
| 150 const v8::HeapGraphNode* x2 = | 150 const v8::HeapGraphNode* x2 = |
| 151 GetProperty(x, v8::HeapGraphEdge::kProperty, "b"); | 151 GetProperty(x, v8::HeapGraphEdge::kProperty, "b"); |
| 152 CHECK_NE(NULL, x2); | 152 CHECK_NE(NULL, x2); |
| 153 | 153 |
| 154 // Test sizes. | 154 // Test sizes. |
| 155 CHECK_EQ(x->GetSelfSize() * 3, x->GetRetainedSize()); | 155 CHECK_EQ(x->GetSelfSize() * 3, x->GetRetainedSize()); |
| 156 CHECK_EQ(x1->GetSelfSize(), x1->GetRetainedSize()); | 156 CHECK_EQ(x1->GetSelfSize(), x1->GetRetainedSize()); |
| 157 CHECK_EQ(x2->GetSelfSize(), x2->GetRetainedSize()); | 157 CHECK_EQ(x2->GetSelfSize(), x2->GetRetainedSize()); |
| 158 } | 158 } |
| 159 | 159 |
| 160 | 160 |
| 161 TEST(BoundFunctionInSnapshot) { | 161 TEST(BoundFunctionInSnapshot) { |
| 162 v8::HandleScope scope; | 162 v8::HandleScope scope; |
| 163 LocalContext env; | 163 LocalContext env; |
| 164 CompileRun( | 164 CompileRun( |
| 165 "function myFunction(a, b) { this.a = a; this.b = b; }\n" | 165 "function myFunction(a, b) { this.a = a; this.b = b; }\n" |
| 166 "function AAAAA() {}\n" | 166 "function AAAAA() {}\n" |
| 167 "boundFunction = myFunction.bind(new AAAAA(), 20, new Number(12)); \n"); | 167 "boundFunction = myFunction.bind(new AAAAA(), 20, new Number(12)); \n"); |
| 168 const v8::HeapSnapshot* snapshot = | 168 const v8::HeapSnapshot* snapshot = |
| 169 v8::HeapProfiler::TakeSnapshot(v8_str("sizes")); | 169 v8::HeapProfiler::TakeSnapshot(v8_str("sizes")); |
| 170 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); | 170 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 171 const v8::HeapGraphNode* f = | 171 const v8::HeapGraphNode* f = |
| 172 GetProperty(global, v8::HeapGraphEdge::kShortcut, "boundFunction"); | 172 GetProperty(global, v8::HeapGraphEdge::kProperty, "boundFunction"); |
| 173 CHECK(f); | 173 CHECK(f); |
| 174 CHECK_EQ(v8::String::New("native_bind"), f->GetName()); | 174 CHECK_EQ(v8::String::New("native_bind"), f->GetName()); |
| 175 const v8::HeapGraphNode* bindings = | 175 const v8::HeapGraphNode* bindings = |
| 176 GetProperty(f, v8::HeapGraphEdge::kInternal, "bindings"); | 176 GetProperty(f, v8::HeapGraphEdge::kInternal, "bindings"); |
| 177 CHECK_NE(NULL, bindings); | 177 CHECK_NE(NULL, bindings); |
| 178 CHECK_EQ(v8::HeapGraphNode::kArray, bindings->GetType()); | 178 CHECK_EQ(v8::HeapGraphNode::kArray, bindings->GetType()); |
| 179 CHECK_EQ(4, bindings->GetChildrenCount()); | 179 CHECK_EQ(4, bindings->GetChildrenCount()); |
| 180 | 180 |
| 181 const v8::HeapGraphNode* bound_this = GetProperty( | 181 const v8::HeapGraphNode* bound_this = GetProperty( |
| 182 f, v8::HeapGraphEdge::kShortcut, "bound_this"); | 182 f, v8::HeapGraphEdge::kShortcut, "bound_this"); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 226 CompileRun( | 226 CompileRun( |
| 227 "function lazy(x) { return x - 1; }\n" | 227 "function lazy(x) { return x - 1; }\n" |
| 228 "function compiled(x) { return x + 1; }\n" | 228 "function compiled(x) { return x + 1; }\n" |
| 229 "var anonymous = (function() { return function() { return 0; } })();\n" | 229 "var anonymous = (function() { return function() { return 0; } })();\n" |
| 230 "compiled(1)"); | 230 "compiled(1)"); |
| 231 const v8::HeapSnapshot* snapshot = | 231 const v8::HeapSnapshot* snapshot = |
| 232 v8::HeapProfiler::TakeSnapshot(v8_str("code")); | 232 v8::HeapProfiler::TakeSnapshot(v8_str("code")); |
| 233 | 233 |
| 234 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); | 234 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 235 const v8::HeapGraphNode* compiled = | 235 const v8::HeapGraphNode* compiled = |
| 236 GetProperty(global, v8::HeapGraphEdge::kShortcut, "compiled"); | 236 GetProperty(global, v8::HeapGraphEdge::kProperty, "compiled"); |
| 237 CHECK_NE(NULL, compiled); | 237 CHECK_NE(NULL, compiled); |
| 238 CHECK_EQ(v8::HeapGraphNode::kClosure, compiled->GetType()); | 238 CHECK_EQ(v8::HeapGraphNode::kClosure, compiled->GetType()); |
| 239 const v8::HeapGraphNode* lazy = | 239 const v8::HeapGraphNode* lazy = |
| 240 GetProperty(global, v8::HeapGraphEdge::kShortcut, "lazy"); | 240 GetProperty(global, v8::HeapGraphEdge::kProperty, "lazy"); |
| 241 CHECK_NE(NULL, lazy); | 241 CHECK_NE(NULL, lazy); |
| 242 CHECK_EQ(v8::HeapGraphNode::kClosure, lazy->GetType()); | 242 CHECK_EQ(v8::HeapGraphNode::kClosure, lazy->GetType()); |
| 243 const v8::HeapGraphNode* anonymous = | 243 const v8::HeapGraphNode* anonymous = |
| 244 GetProperty(global, v8::HeapGraphEdge::kShortcut, "anonymous"); | 244 GetProperty(global, v8::HeapGraphEdge::kProperty, "anonymous"); |
| 245 CHECK_NE(NULL, anonymous); | 245 CHECK_NE(NULL, anonymous); |
| 246 CHECK_EQ(v8::HeapGraphNode::kClosure, anonymous->GetType()); | 246 CHECK_EQ(v8::HeapGraphNode::kClosure, anonymous->GetType()); |
| 247 v8::String::AsciiValue anonymous_name(anonymous->GetName()); | 247 v8::String::AsciiValue anonymous_name(anonymous->GetName()); |
| 248 CHECK_EQ("", *anonymous_name); | 248 CHECK_EQ("", *anonymous_name); |
| 249 | 249 |
| 250 // Find references to code. | 250 // Find references to code. |
| 251 const v8::HeapGraphNode* compiled_code = | 251 const v8::HeapGraphNode* compiled_code = |
| 252 GetProperty(compiled, v8::HeapGraphEdge::kInternal, "shared"); | 252 GetProperty(compiled, v8::HeapGraphEdge::kInternal, "shared"); |
| 253 CHECK_NE(NULL, compiled_code); | 253 CHECK_NE(NULL, compiled_code); |
| 254 const v8::HeapGraphNode* lazy_code = | 254 const v8::HeapGraphNode* lazy_code = |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 286 | 286 |
| 287 TEST(HeapSnapshotHeapNumbers) { | 287 TEST(HeapSnapshotHeapNumbers) { |
| 288 v8::HandleScope scope; | 288 v8::HandleScope scope; |
| 289 LocalContext env; | 289 LocalContext env; |
| 290 CompileRun( | 290 CompileRun( |
| 291 "a = 1; // a is Smi\n" | 291 "a = 1; // a is Smi\n" |
| 292 "b = 2.5; // b is HeapNumber"); | 292 "b = 2.5; // b is HeapNumber"); |
| 293 const v8::HeapSnapshot* snapshot = | 293 const v8::HeapSnapshot* snapshot = |
| 294 v8::HeapProfiler::TakeSnapshot(v8_str("numbers")); | 294 v8::HeapProfiler::TakeSnapshot(v8_str("numbers")); |
| 295 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); | 295 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 296 CHECK_EQ(NULL, GetProperty(global, v8::HeapGraphEdge::kShortcut, "a")); | 296 CHECK_EQ(NULL, GetProperty(global, v8::HeapGraphEdge::kProperty, "a")); |
| 297 const v8::HeapGraphNode* b = | 297 const v8::HeapGraphNode* b = |
| 298 GetProperty(global, v8::HeapGraphEdge::kShortcut, "b"); | 298 GetProperty(global, v8::HeapGraphEdge::kProperty, "b"); |
| 299 CHECK_NE(NULL, b); | 299 CHECK_NE(NULL, b); |
| 300 CHECK_EQ(v8::HeapGraphNode::kHeapNumber, b->GetType()); | 300 CHECK_EQ(v8::HeapGraphNode::kHeapNumber, b->GetType()); |
| 301 } | 301 } |
| 302 | 302 |
| 303 TEST(HeapSnapshotSlicedString) { | 303 TEST(HeapSnapshotSlicedString) { |
| 304 v8::HandleScope scope; | 304 v8::HandleScope scope; |
| 305 LocalContext env; | 305 LocalContext env; |
| 306 CompileRun( | 306 CompileRun( |
| 307 "parent_string = \"123456789.123456789.123456789.123456789.123456789." | 307 "parent_string = \"123456789.123456789.123456789.123456789.123456789." |
| 308 "123456789.123456789.123456789.123456789.123456789." | 308 "123456789.123456789.123456789.123456789.123456789." |
| 309 "123456789.123456789.123456789.123456789.123456789." | 309 "123456789.123456789.123456789.123456789.123456789." |
| 310 "123456789.123456789.123456789.123456789.123456789.\";" | 310 "123456789.123456789.123456789.123456789.123456789.\";" |
| 311 "child_string = parent_string.slice(100);"); | 311 "child_string = parent_string.slice(100);"); |
| 312 const v8::HeapSnapshot* snapshot = | 312 const v8::HeapSnapshot* snapshot = |
| 313 v8::HeapProfiler::TakeSnapshot(v8_str("strings")); | 313 v8::HeapProfiler::TakeSnapshot(v8_str("strings")); |
| 314 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); | 314 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 315 const v8::HeapGraphNode* parent_string = | 315 const v8::HeapGraphNode* parent_string = |
| 316 GetProperty(global, v8::HeapGraphEdge::kShortcut, "parent_string"); | 316 GetProperty(global, v8::HeapGraphEdge::kProperty, "parent_string"); |
| 317 CHECK_NE(NULL, parent_string); | 317 CHECK_NE(NULL, parent_string); |
| 318 const v8::HeapGraphNode* child_string = | 318 const v8::HeapGraphNode* child_string = |
| 319 GetProperty(global, v8::HeapGraphEdge::kShortcut, "child_string"); | 319 GetProperty(global, v8::HeapGraphEdge::kProperty, "child_string"); |
| 320 CHECK_NE(NULL, child_string); | 320 CHECK_NE(NULL, child_string); |
| 321 const v8::HeapGraphNode* parent = | 321 const v8::HeapGraphNode* parent = |
| 322 GetProperty(child_string, v8::HeapGraphEdge::kInternal, "parent"); | 322 GetProperty(child_string, v8::HeapGraphEdge::kInternal, "parent"); |
| 323 CHECK_EQ(parent_string, parent); | 323 CHECK_EQ(parent_string, parent); |
| 324 } | 324 } |
| 325 | 325 |
| 326 TEST(HeapSnapshotInternalReferences) { | 326 TEST(HeapSnapshotInternalReferences) { |
| 327 v8::HandleScope scope; | 327 v8::HandleScope scope; |
| 328 v8::Local<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); | 328 v8::Local<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); |
| 329 global_template->SetInternalFieldCount(2); | 329 global_template->SetInternalFieldCount(2); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 377 v8::HeapProfiler::TakeSnapshot(v8_str("s2")); | 377 v8::HeapProfiler::TakeSnapshot(v8_str("s2")); |
| 378 | 378 |
| 379 const v8::HeapGraphNode* global1 = GetGlobalObject(snapshot1); | 379 const v8::HeapGraphNode* global1 = GetGlobalObject(snapshot1); |
| 380 const v8::HeapGraphNode* global2 = GetGlobalObject(snapshot2); | 380 const v8::HeapGraphNode* global2 = GetGlobalObject(snapshot2); |
| 381 CHECK_NE_SNAPSHOT_OBJECT_ID(0, global1->GetId()); | 381 CHECK_NE_SNAPSHOT_OBJECT_ID(0, global1->GetId()); |
| 382 CHECK_EQ_SNAPSHOT_OBJECT_ID(global1->GetId(), global2->GetId()); | 382 CHECK_EQ_SNAPSHOT_OBJECT_ID(global1->GetId(), global2->GetId()); |
| 383 | 383 |
| 384 const v8::HeapGraphNode* a1 = | 384 const v8::HeapGraphNode* a1 = |
| 385 GetProperty(global1, v8::HeapGraphEdge::kProperty, "a"); | 385 GetProperty(global1, v8::HeapGraphEdge::kProperty, "a"); |
| 386 CHECK_NE(NULL, a1); | 386 CHECK_NE(NULL, a1); |
| 387 const v8::HeapGraphNode* e1 = | |
| 388 GetProperty(a1, v8::HeapGraphEdge::kHidden, "1"); | |
| 389 CHECK_NE(NULL, e1); | |
| 390 const v8::HeapGraphNode* k1 = | 387 const v8::HeapGraphNode* k1 = |
| 391 GetProperty(e1, v8::HeapGraphEdge::kInternal, "elements"); | 388 GetProperty(a1, v8::HeapGraphEdge::kInternal, "elements"); |
| 392 CHECK_NE(NULL, k1); | 389 CHECK_NE(NULL, k1); |
| 393 const v8::HeapGraphNode* a2 = | 390 const v8::HeapGraphNode* a2 = |
| 394 GetProperty(global2, v8::HeapGraphEdge::kProperty, "a"); | 391 GetProperty(global2, v8::HeapGraphEdge::kProperty, "a"); |
| 395 CHECK_NE(NULL, a2); | 392 CHECK_NE(NULL, a2); |
| 396 const v8::HeapGraphNode* e2 = | |
| 397 GetProperty(a2, v8::HeapGraphEdge::kHidden, "1"); | |
| 398 CHECK_NE(NULL, e2); | |
| 399 const v8::HeapGraphNode* k2 = | 393 const v8::HeapGraphNode* k2 = |
| 400 GetProperty(e2, v8::HeapGraphEdge::kInternal, "elements"); | 394 GetProperty(a2, v8::HeapGraphEdge::kInternal, "elements"); |
| 401 CHECK_NE(NULL, k2); | 395 CHECK_NE(NULL, k2); |
| 402 | 396 |
| 403 CHECK_EQ_SNAPSHOT_OBJECT_ID(a1->GetId(), a2->GetId()); | 397 CHECK_EQ_SNAPSHOT_OBJECT_ID(a1->GetId(), a2->GetId()); |
| 404 CHECK_EQ_SNAPSHOT_OBJECT_ID(e1->GetId(), e2->GetId()); | |
| 405 CHECK_EQ_SNAPSHOT_OBJECT_ID(k1->GetId(), k2->GetId()); | 398 CHECK_EQ_SNAPSHOT_OBJECT_ID(k1->GetId(), k2->GetId()); |
| 406 } | 399 } |
| 407 | 400 |
| 408 TEST(HeapEntryIdsAndGC) { | 401 TEST(HeapEntryIdsAndGC) { |
| 409 v8::HandleScope scope; | 402 v8::HandleScope scope; |
| 410 LocalContext env; | 403 LocalContext env; |
| 411 | 404 |
| 412 CompileRun( | 405 CompileRun( |
| 413 "function A() {}\n" | 406 "function A() {}\n" |
| 414 "function B(x) { this.x = x; }\n" | 407 "function B(x) { this.x = x; }\n" |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 507 "node6.b.a.b = node6.b.b; // node2 -> node3\n" | 500 "node6.b.a.b = node6.b.b; // node2 -> node3\n" |
| 508 "node6.b.b.a = node6.b.a; // node3 -> node2\n" | 501 "node6.b.b.a = node6.b.a; // node3 -> node2\n" |
| 509 "})();"); | 502 "})();"); |
| 510 | 503 |
| 511 const v8::HeapSnapshot* snapshot = | 504 const v8::HeapSnapshot* snapshot = |
| 512 v8::HeapProfiler::TakeSnapshot(v8_str("dominators")); | 505 v8::HeapProfiler::TakeSnapshot(v8_str("dominators")); |
| 513 | 506 |
| 514 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); | 507 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 515 CHECK_NE(NULL, global); | 508 CHECK_NE(NULL, global); |
| 516 const v8::HeapGraphNode* node6 = | 509 const v8::HeapGraphNode* node6 = |
| 517 GetProperty(global, v8::HeapGraphEdge::kShortcut, "node6"); | 510 GetProperty(global, v8::HeapGraphEdge::kProperty, "node6"); |
| 518 CHECK_NE(NULL, node6); | 511 CHECK_NE(NULL, node6); |
| 519 const v8::HeapGraphNode* node5 = | 512 const v8::HeapGraphNode* node5 = |
| 520 GetProperty(node6, v8::HeapGraphEdge::kProperty, "a"); | 513 GetProperty(node6, v8::HeapGraphEdge::kProperty, "a"); |
| 521 CHECK_NE(NULL, node5); | 514 CHECK_NE(NULL, node5); |
| 522 const v8::HeapGraphNode* node4 = | 515 const v8::HeapGraphNode* node4 = |
| 523 GetProperty(node6, v8::HeapGraphEdge::kProperty, "b"); | 516 GetProperty(node6, v8::HeapGraphEdge::kProperty, "b"); |
| 524 CHECK_NE(NULL, node4); | 517 CHECK_NE(NULL, node4); |
| 525 const v8::HeapGraphNode* node3 = | 518 const v8::HeapGraphNode* node3 = |
| 526 GetProperty(node4, v8::HeapGraphEdge::kProperty, "b"); | 519 GetProperty(node4, v8::HeapGraphEdge::kProperty, "b"); |
| 527 CHECK_NE(NULL, node3); | 520 CHECK_NE(NULL, node3); |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 651 " return nodes[child_pos + child_to_node_offset];\n" | 644 " return nodes[child_pos + child_to_node_offset];\n" |
| 652 " }\n" | 645 " }\n" |
| 653 " return null;\n" | 646 " return null;\n" |
| 654 "}\n"); | 647 "}\n"); |
| 655 // Get the string index using the path: <root> -> <global>.b.x.s | 648 // Get the string index using the path: <root> -> <global>.b.x.s |
| 656 v8::Local<v8::Value> string_obj_pos_val = CompileRun( | 649 v8::Local<v8::Value> string_obj_pos_val = CompileRun( |
| 657 "GetChildPosByProperty(\n" | 650 "GetChildPosByProperty(\n" |
| 658 " GetChildPosByProperty(\n" | 651 " GetChildPosByProperty(\n" |
| 659 " GetChildPosByProperty(" | 652 " GetChildPosByProperty(" |
| 660 " parsed.nodes[1 + children_offset + child_to_node_offset]," | 653 " parsed.nodes[1 + children_offset + child_to_node_offset]," |
| 661 " \"b\",shortcut_type),\n" | 654 " \"b\", property_type),\n" |
| 662 " \"x\", property_type)," | 655 " \"x\", property_type)," |
| 663 " \"s\", property_type)"); | 656 " \"s\", property_type)"); |
| 664 CHECK(!string_obj_pos_val.IsEmpty()); | 657 CHECK(!string_obj_pos_val.IsEmpty()); |
| 665 int string_obj_pos = | 658 int string_obj_pos = |
| 666 static_cast<int>(string_obj_pos_val->ToNumber()->Value()); | 659 static_cast<int>(string_obj_pos_val->ToNumber()->Value()); |
| 667 v8::Local<v8::Object> nodes_array = | 660 v8::Local<v8::Object> nodes_array = |
| 668 parsed_snapshot->Get(v8_str("nodes"))->ToObject(); | 661 parsed_snapshot->Get(v8_str("nodes"))->ToObject(); |
| 669 int string_index = static_cast<int>( | 662 int string_index = static_cast<int>( |
| 670 nodes_array->Get(string_obj_pos + 1)->ToNumber()->Value()); | 663 nodes_array->Get(string_obj_pos + 1)->ToNumber()->Value()); |
| 671 CHECK_GT(string_index, 0); | 664 CHECK_GT(string_index, 0); |
| (...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 952 v8::HandleScope scope; | 945 v8::HandleScope scope; |
| 953 LocalContext env; | 946 LocalContext env; |
| 954 | 947 |
| 955 GraphWithImplicitRefs graph(&env); | 948 GraphWithImplicitRefs graph(&env); |
| 956 v8::V8::SetGlobalGCPrologueCallback(&GraphWithImplicitRefs::gcPrologue); | 949 v8::V8::SetGlobalGCPrologueCallback(&GraphWithImplicitRefs::gcPrologue); |
| 957 | 950 |
| 958 const v8::HeapSnapshot* snapshot = | 951 const v8::HeapSnapshot* snapshot = |
| 959 v8::HeapProfiler::TakeSnapshot(v8_str("implicit_refs")); | 952 v8::HeapProfiler::TakeSnapshot(v8_str("implicit_refs")); |
| 960 | 953 |
| 961 const v8::HeapGraphNode* global_object = GetGlobalObject(snapshot); | 954 const v8::HeapGraphNode* global_object = GetGlobalObject(snapshot); |
| 962 // Use kShortcut type to skip intermediate JSGlobalPropertyCell | |
| 963 const v8::HeapGraphNode* obj0 = GetProperty( | 955 const v8::HeapGraphNode* obj0 = GetProperty( |
| 964 global_object, v8::HeapGraphEdge::kShortcut, "root_object"); | 956 global_object, v8::HeapGraphEdge::kProperty, "root_object"); |
| 965 CHECK(obj0); | 957 CHECK(obj0); |
| 966 CHECK_EQ(v8::HeapGraphNode::kObject, obj0->GetType()); | 958 CHECK_EQ(v8::HeapGraphNode::kObject, obj0->GetType()); |
| 967 const v8::HeapGraphNode* obj1 = GetProperty( | 959 const v8::HeapGraphNode* obj1 = GetProperty( |
| 968 obj0, v8::HeapGraphEdge::kInternal, "native"); | 960 obj0, v8::HeapGraphEdge::kInternal, "native"); |
| 969 CHECK(obj1); | 961 CHECK(obj1); |
| 970 int implicit_targets_count = 0; | 962 int implicit_targets_count = 0; |
| 971 for (int i = 0, count = obj1->GetChildrenCount(); i < count; ++i) { | 963 for (int i = 0, count = obj1->GetChildrenCount(); i < count; ++i) { |
| 972 const v8::HeapGraphEdge* prop = obj1->GetChild(i); | 964 const v8::HeapGraphEdge* prop = obj1->GetChild(i); |
| 973 v8::String::AsciiValue prop_name(prop->GetName()); | 965 v8::String::AsciiValue prop_name(prop->GetName()); |
| 974 if (prop->GetType() == v8::HeapGraphEdge::kInternal && | 966 if (prop->GetType() == v8::HeapGraphEdge::kInternal && |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1127 | 1119 |
| 1128 CompileRun("a = { s_prop: \'value\', n_prop: 0.1 };"); | 1120 CompileRun("a = { s_prop: \'value\', n_prop: 0.1 };"); |
| 1129 const v8::HeapSnapshot* snapshot = | 1121 const v8::HeapSnapshot* snapshot = |
| 1130 v8::HeapProfiler::TakeSnapshot(v8_str("value")); | 1122 v8::HeapProfiler::TakeSnapshot(v8_str("value")); |
| 1131 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); | 1123 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 1132 CHECK(global->GetHeapValue()->IsObject()); | 1124 CHECK(global->GetHeapValue()->IsObject()); |
| 1133 v8::Local<v8::Object> js_global = | 1125 v8::Local<v8::Object> js_global = |
| 1134 env->Global()->GetPrototype().As<v8::Object>(); | 1126 env->Global()->GetPrototype().As<v8::Object>(); |
| 1135 CHECK(js_global == global->GetHeapValue()); | 1127 CHECK(js_global == global->GetHeapValue()); |
| 1136 const v8::HeapGraphNode* obj = GetProperty( | 1128 const v8::HeapGraphNode* obj = GetProperty( |
| 1137 global, v8::HeapGraphEdge::kShortcut, "a"); | 1129 global, v8::HeapGraphEdge::kProperty, "a"); |
| 1138 CHECK(obj->GetHeapValue()->IsObject()); | 1130 CHECK(obj->GetHeapValue()->IsObject()); |
| 1139 v8::Local<v8::Object> js_obj = js_global->Get(v8_str("a")).As<v8::Object>(); | 1131 v8::Local<v8::Object> js_obj = js_global->Get(v8_str("a")).As<v8::Object>(); |
| 1140 CHECK(js_obj == obj->GetHeapValue()); | 1132 CHECK(js_obj == obj->GetHeapValue()); |
| 1141 const v8::HeapGraphNode* s_prop = | 1133 const v8::HeapGraphNode* s_prop = |
| 1142 GetProperty(obj, v8::HeapGraphEdge::kProperty, "s_prop"); | 1134 GetProperty(obj, v8::HeapGraphEdge::kProperty, "s_prop"); |
| 1143 v8::Local<v8::String> js_s_prop = | 1135 v8::Local<v8::String> js_s_prop = |
| 1144 js_obj->Get(v8_str("s_prop")).As<v8::String>(); | 1136 js_obj->Get(v8_str("s_prop")).As<v8::String>(); |
| 1145 CHECK(js_s_prop == s_prop->GetHeapValue()); | 1137 CHECK(js_s_prop == s_prop->GetHeapValue()); |
| 1146 const v8::HeapGraphNode* n_prop = | 1138 const v8::HeapGraphNode* n_prop = |
| 1147 GetProperty(obj, v8::HeapGraphEdge::kProperty, "n_prop"); | 1139 GetProperty(obj, v8::HeapGraphEdge::kProperty, "n_prop"); |
| 1148 v8::Local<v8::Number> js_n_prop = | 1140 v8::Local<v8::Number> js_n_prop = |
| 1149 js_obj->Get(v8_str("n_prop")).As<v8::Number>(); | 1141 js_obj->Get(v8_str("n_prop")).As<v8::Number>(); |
| 1150 CHECK(js_n_prop == n_prop->GetHeapValue()); | 1142 CHECK(js_n_prop == n_prop->GetHeapValue()); |
| 1151 } | 1143 } |
| 1152 | 1144 |
| 1153 | 1145 |
| 1154 TEST(GetHeapValueForDeletedObject) { | 1146 TEST(GetHeapValueForDeletedObject) { |
| 1155 v8::HandleScope scope; | 1147 v8::HandleScope scope; |
| 1156 LocalContext env; | 1148 LocalContext env; |
| 1157 | 1149 |
| 1158 // It is impossible to delete a global property, so we are about to delete a | 1150 // It is impossible to delete a global property, so we are about to delete a |
| 1159 // property of the "a" object. Also, the "p" object can't be an empty one | 1151 // property of the "a" object. Also, the "p" object can't be an empty one |
| 1160 // because the empty object is static and isn't actually deleted. | 1152 // because the empty object is static and isn't actually deleted. |
| 1161 CompileRun("a = { p: { r: {} } };"); | 1153 CompileRun("a = { p: { r: {} } };"); |
| 1162 const v8::HeapSnapshot* snapshot = | 1154 const v8::HeapSnapshot* snapshot = |
| 1163 v8::HeapProfiler::TakeSnapshot(v8_str("snapshot")); | 1155 v8::HeapProfiler::TakeSnapshot(v8_str("snapshot")); |
| 1164 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); | 1156 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 1165 const v8::HeapGraphNode* obj = GetProperty( | 1157 const v8::HeapGraphNode* obj = GetProperty( |
| 1166 global, v8::HeapGraphEdge::kShortcut, "a"); | 1158 global, v8::HeapGraphEdge::kProperty, "a"); |
| 1167 const v8::HeapGraphNode* prop = GetProperty( | 1159 const v8::HeapGraphNode* prop = GetProperty( |
| 1168 obj, v8::HeapGraphEdge::kProperty, "p"); | 1160 obj, v8::HeapGraphEdge::kProperty, "p"); |
| 1169 { | 1161 { |
| 1170 // Perform the check inside a nested local scope to avoid creating a | 1162 // Perform the check inside a nested local scope to avoid creating a |
| 1171 // reference to the object we are deleting. | 1163 // reference to the object we are deleting. |
| 1172 v8::HandleScope scope; | 1164 v8::HandleScope scope; |
| 1173 CHECK(prop->GetHeapValue()->IsObject()); | 1165 CHECK(prop->GetHeapValue()->IsObject()); |
| 1174 } | 1166 } |
| 1175 CompileRun("delete a.p;"); | 1167 CompileRun("delete a.p;"); |
| 1176 CHECK(prop->GetHeapValue()->IsUndefined()); | 1168 CHECK(prop->GetHeapValue()->IsUndefined()); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1243 "});\n" | 1235 "});\n" |
| 1244 "obj1.__defineSetter__('propWithSetter', function Z(value) {\n" | 1236 "obj1.__defineSetter__('propWithSetter', function Z(value) {\n" |
| 1245 " return this.value_ = value;\n" | 1237 " return this.value_ = value;\n" |
| 1246 "});\n"); | 1238 "});\n"); |
| 1247 const v8::HeapSnapshot* snapshot = | 1239 const v8::HeapSnapshot* snapshot = |
| 1248 v8::HeapProfiler::TakeSnapshot(v8_str("fastCaseGetter")); | 1240 v8::HeapProfiler::TakeSnapshot(v8_str("fastCaseGetter")); |
| 1249 | 1241 |
| 1250 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); | 1242 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 1251 CHECK_NE(NULL, global); | 1243 CHECK_NE(NULL, global); |
| 1252 const v8::HeapGraphNode* obj1 = | 1244 const v8::HeapGraphNode* obj1 = |
| 1253 GetProperty(global, v8::HeapGraphEdge::kShortcut, "obj1"); | 1245 GetProperty(global, v8::HeapGraphEdge::kProperty, "obj1"); |
| 1254 CHECK_NE(NULL, obj1); | 1246 CHECK_NE(NULL, obj1); |
| 1255 const v8::HeapGraphNode* getterFunction = | 1247 const v8::HeapGraphNode* getterFunction = |
| 1256 GetProperty(obj1, v8::HeapGraphEdge::kProperty, "get-propWithGetter"); | 1248 GetProperty(obj1, v8::HeapGraphEdge::kProperty, "get-propWithGetter"); |
| 1257 CHECK_NE(NULL, getterFunction); | 1249 CHECK_NE(NULL, getterFunction); |
| 1258 const v8::HeapGraphNode* setterFunction = | 1250 const v8::HeapGraphNode* setterFunction = |
| 1259 GetProperty(obj1, v8::HeapGraphEdge::kProperty, "set-propWithSetter"); | 1251 GetProperty(obj1, v8::HeapGraphEdge::kProperty, "set-propWithSetter"); |
| 1260 CHECK_NE(NULL, setterFunction); | 1252 CHECK_NE(NULL, setterFunction); |
| 1261 } | 1253 } |
| 1262 | 1254 |
| 1263 | 1255 |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1325 v8::HandleScope scope; | 1317 v8::HandleScope scope; |
| 1326 LocalContext env; | 1318 LocalContext env; |
| 1327 | 1319 |
| 1328 CompileRun( | 1320 CompileRun( |
| 1329 "fun = (function (x) { return function () { return x + 1; } })(1);"); | 1321 "fun = (function (x) { return function () { return x + 1; } })(1);"); |
| 1330 const v8::HeapSnapshot* snapshot = | 1322 const v8::HeapSnapshot* snapshot = |
| 1331 v8::HeapProfiler::TakeSnapshot(v8_str("fun")); | 1323 v8::HeapProfiler::TakeSnapshot(v8_str("fun")); |
| 1332 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); | 1324 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 1333 CHECK_NE(NULL, global); | 1325 CHECK_NE(NULL, global); |
| 1334 const v8::HeapGraphNode* fun = | 1326 const v8::HeapGraphNode* fun = |
| 1335 GetProperty(global, v8::HeapGraphEdge::kShortcut, "fun"); | 1327 GetProperty(global, v8::HeapGraphEdge::kProperty, "fun"); |
| 1336 CHECK(HasWeakEdge(fun)); | 1328 CHECK(HasWeakEdge(fun)); |
| 1337 const v8::HeapGraphNode* shared = | 1329 const v8::HeapGraphNode* shared = |
| 1338 GetProperty(fun, v8::HeapGraphEdge::kInternal, "shared"); | 1330 GetProperty(fun, v8::HeapGraphEdge::kInternal, "shared"); |
| 1339 CHECK(HasWeakEdge(shared)); | 1331 CHECK(HasWeakEdge(shared)); |
| 1340 } | 1332 } |
| 1341 | 1333 |
| 1342 | 1334 |
| 1343 TEST(PersistentHandleCount) { | 1335 TEST(PersistentHandleCount) { |
| 1344 v8::HandleScope scope; | 1336 v8::HandleScope scope; |
| 1345 LocalContext env; | 1337 LocalContext env; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1365 // Dipose the persistent handles in a different order. | 1357 // Dipose the persistent handles in a different order. |
| 1366 p_AAA.Dispose(); | 1358 p_AAA.Dispose(); |
| 1367 CHECK_EQ(global_handle_count + 2, | 1359 CHECK_EQ(global_handle_count + 2, |
| 1368 v8::HeapProfiler::GetPersistentHandleCount()); | 1360 v8::HeapProfiler::GetPersistentHandleCount()); |
| 1369 p_CCC.Dispose(); | 1361 p_CCC.Dispose(); |
| 1370 CHECK_EQ(global_handle_count + 1, | 1362 CHECK_EQ(global_handle_count + 1, |
| 1371 v8::HeapProfiler::GetPersistentHandleCount()); | 1363 v8::HeapProfiler::GetPersistentHandleCount()); |
| 1372 p_BBB.Dispose(); | 1364 p_BBB.Dispose(); |
| 1373 CHECK_EQ(global_handle_count, v8::HeapProfiler::GetPersistentHandleCount()); | 1365 CHECK_EQ(global_handle_count, v8::HeapProfiler::GetPersistentHandleCount()); |
| 1374 } | 1366 } |
| OLD | NEW |