| 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 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 LocalContext env2; | 78 LocalContext env2; |
| 79 | 79 |
| 80 CompileRun( | 80 CompileRun( |
| 81 "function A2() {}\n" | 81 "function A2() {}\n" |
| 82 "function B2(x) { return function() { return typeof x; }; }\n" | 82 "function B2(x) { return function() { return typeof x; }; }\n" |
| 83 "function C2(x) { this.x1 = x; this.x2 = x; this[1] = x; }\n" | 83 "function C2(x) { this.x1 = x; this.x2 = x; this[1] = x; }\n" |
| 84 "var a2 = new A2();\n" | 84 "var a2 = new A2();\n" |
| 85 "var b2_1 = new B2(a2), b2_2 = new B2(a2);\n" | 85 "var b2_1 = new B2(a2), b2_2 = new B2(a2);\n" |
| 86 "var c2 = new C2(a2);"); | 86 "var c2 = new C2(a2);"); |
| 87 const v8::HeapSnapshot* snapshot_env2 = | 87 const v8::HeapSnapshot* snapshot_env2 = |
| 88 v8::HeapProfiler::TakeSnapshot(v8::String::New("env2")); | 88 v8::HeapProfiler::TakeSnapshot(v8_str("env2")); |
| 89 i::HeapSnapshot* i_snapshot_env2 = | 89 i::HeapSnapshot* i_snapshot_env2 = |
| 90 const_cast<i::HeapSnapshot*>( | 90 const_cast<i::HeapSnapshot*>( |
| 91 reinterpret_cast<const i::HeapSnapshot*>(snapshot_env2)); | 91 reinterpret_cast<const i::HeapSnapshot*>(snapshot_env2)); |
| 92 const v8::HeapGraphNode* global_env2 = GetGlobalObject(snapshot_env2); | 92 const v8::HeapGraphNode* global_env2 = GetGlobalObject(snapshot_env2); |
| 93 // Paint all nodes reachable from global object. | 93 // Paint all nodes reachable from global object. |
| 94 i_snapshot_env2->ClearPaint(); | 94 i_snapshot_env2->ClearPaint(); |
| 95 const_cast<i::HeapEntry*>( | 95 const_cast<i::HeapEntry*>( |
| 96 reinterpret_cast<const i::HeapEntry*>(global_env2))->PaintAllReachable(); | 96 reinterpret_cast<const i::HeapEntry*>(global_env2))->PaintAllReachable(); |
| 97 | 97 |
| 98 // Verify, that JS global object of env2 has '..2' properties. | 98 // Verify, that JS global object of env2 has '..2' properties. |
| (...skipping 18 matching lines...) Expand all Loading... |
| 117 v8::HandleScope scope; | 117 v8::HandleScope scope; |
| 118 LocalContext env; | 118 LocalContext env; |
| 119 | 119 |
| 120 // -a-> X1 --a | 120 // -a-> X1 --a |
| 121 // x -b-> X2 <-| | 121 // x -b-> X2 <-| |
| 122 CompileRun( | 122 CompileRun( |
| 123 "function X(a, b) { this.a = a; this.b = b; }\n" | 123 "function X(a, b) { this.a = a; this.b = b; }\n" |
| 124 "x = new X(new X(), new X());\n" | 124 "x = new X(new X(), new X());\n" |
| 125 "(function() { x.a.a = x.b; })();"); | 125 "(function() { x.a.a = x.b; })();"); |
| 126 const v8::HeapSnapshot* snapshot = | 126 const v8::HeapSnapshot* snapshot = |
| 127 v8::HeapProfiler::TakeSnapshot(v8::String::New("sizes")); | 127 v8::HeapProfiler::TakeSnapshot(v8_str("sizes")); |
| 128 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); | 128 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 129 const v8::HeapGraphNode* x = | 129 const v8::HeapGraphNode* x = |
| 130 GetProperty(global, v8::HeapGraphEdge::kShortcut, "x"); | 130 GetProperty(global, v8::HeapGraphEdge::kShortcut, "x"); |
| 131 CHECK_NE(NULL, x); | 131 CHECK_NE(NULL, x); |
| 132 const v8::HeapGraphNode* x1 = | 132 const v8::HeapGraphNode* x1 = |
| 133 GetProperty(x, v8::HeapGraphEdge::kProperty, "a"); | 133 GetProperty(x, v8::HeapGraphEdge::kProperty, "a"); |
| 134 CHECK_NE(NULL, x1); | 134 CHECK_NE(NULL, x1); |
| 135 const v8::HeapGraphNode* x2 = | 135 const v8::HeapGraphNode* x2 = |
| 136 GetProperty(x, v8::HeapGraphEdge::kProperty, "b"); | 136 GetProperty(x, v8::HeapGraphEdge::kProperty, "b"); |
| 137 CHECK_NE(NULL, x2); | 137 CHECK_NE(NULL, x2); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 148 | 148 |
| 149 | 149 |
| 150 TEST(HeapSnapshotEntryChildren) { | 150 TEST(HeapSnapshotEntryChildren) { |
| 151 v8::HandleScope scope; | 151 v8::HandleScope scope; |
| 152 LocalContext env; | 152 LocalContext env; |
| 153 | 153 |
| 154 CompileRun( | 154 CompileRun( |
| 155 "function A() { }\n" | 155 "function A() { }\n" |
| 156 "a = new A;"); | 156 "a = new A;"); |
| 157 const v8::HeapSnapshot* snapshot = | 157 const v8::HeapSnapshot* snapshot = |
| 158 v8::HeapProfiler::TakeSnapshot(v8::String::New("children")); | 158 v8::HeapProfiler::TakeSnapshot(v8_str("children")); |
| 159 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); | 159 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 160 for (int i = 0, count = global->GetChildrenCount(); i < count; ++i) { | 160 for (int i = 0, count = global->GetChildrenCount(); i < count; ++i) { |
| 161 const v8::HeapGraphEdge* prop = global->GetChild(i); | 161 const v8::HeapGraphEdge* prop = global->GetChild(i); |
| 162 CHECK_EQ(global, prop->GetFromNode()); | 162 CHECK_EQ(global, prop->GetFromNode()); |
| 163 } | 163 } |
| 164 const v8::HeapGraphNode* a = | 164 const v8::HeapGraphNode* a = |
| 165 GetProperty(global, v8::HeapGraphEdge::kProperty, "a"); | 165 GetProperty(global, v8::HeapGraphEdge::kProperty, "a"); |
| 166 CHECK_NE(NULL, a); | 166 CHECK_NE(NULL, a); |
| 167 for (int i = 0, count = a->GetChildrenCount(); i < count; ++i) { | 167 for (int i = 0, count = a->GetChildrenCount(); i < count; ++i) { |
| 168 const v8::HeapGraphEdge* prop = a->GetChild(i); | 168 const v8::HeapGraphEdge* prop = a->GetChild(i); |
| 169 CHECK_EQ(a, prop->GetFromNode()); | 169 CHECK_EQ(a, prop->GetFromNode()); |
| 170 } | 170 } |
| 171 } | 171 } |
| 172 | 172 |
| 173 | 173 |
| 174 TEST(HeapSnapshotCodeObjects) { | 174 TEST(HeapSnapshotCodeObjects) { |
| 175 v8::HandleScope scope; | 175 v8::HandleScope scope; |
| 176 LocalContext env; | 176 LocalContext env; |
| 177 | 177 |
| 178 CompileRun( | 178 CompileRun( |
| 179 "function lazy(x) { return x - 1; }\n" | 179 "function lazy(x) { return x - 1; }\n" |
| 180 "function compiled(x) { return x + 1; }\n" | 180 "function compiled(x) { return x + 1; }\n" |
| 181 "var anonymous = (function() { return function() { return 0; } })();\n" | 181 "var anonymous = (function() { return function() { return 0; } })();\n" |
| 182 "compiled(1)"); | 182 "compiled(1)"); |
| 183 const v8::HeapSnapshot* snapshot = | 183 const v8::HeapSnapshot* snapshot = |
| 184 v8::HeapProfiler::TakeSnapshot(v8::String::New("code")); | 184 v8::HeapProfiler::TakeSnapshot(v8_str("code")); |
| 185 | 185 |
| 186 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); | 186 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 187 const v8::HeapGraphNode* compiled = | 187 const v8::HeapGraphNode* compiled = |
| 188 GetProperty(global, v8::HeapGraphEdge::kShortcut, "compiled"); | 188 GetProperty(global, v8::HeapGraphEdge::kShortcut, "compiled"); |
| 189 CHECK_NE(NULL, compiled); | 189 CHECK_NE(NULL, compiled); |
| 190 CHECK_EQ(v8::HeapGraphNode::kClosure, compiled->GetType()); | 190 CHECK_EQ(v8::HeapGraphNode::kClosure, compiled->GetType()); |
| 191 const v8::HeapGraphNode* lazy = | 191 const v8::HeapGraphNode* lazy = |
| 192 GetProperty(global, v8::HeapGraphEdge::kShortcut, "lazy"); | 192 GetProperty(global, v8::HeapGraphEdge::kShortcut, "lazy"); |
| 193 CHECK_NE(NULL, lazy); | 193 CHECK_NE(NULL, lazy); |
| 194 CHECK_EQ(v8::HeapGraphNode::kClosure, lazy->GetType()); | 194 CHECK_EQ(v8::HeapGraphNode::kClosure, lazy->GetType()); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 236 } | 236 } |
| 237 | 237 |
| 238 | 238 |
| 239 TEST(HeapSnapshotHeapNumbers) { | 239 TEST(HeapSnapshotHeapNumbers) { |
| 240 v8::HandleScope scope; | 240 v8::HandleScope scope; |
| 241 LocalContext env; | 241 LocalContext env; |
| 242 CompileRun( | 242 CompileRun( |
| 243 "a = 1; // a is Smi\n" | 243 "a = 1; // a is Smi\n" |
| 244 "b = 2.5; // b is HeapNumber"); | 244 "b = 2.5; // b is HeapNumber"); |
| 245 const v8::HeapSnapshot* snapshot = | 245 const v8::HeapSnapshot* snapshot = |
| 246 v8::HeapProfiler::TakeSnapshot(v8::String::New("numbers")); | 246 v8::HeapProfiler::TakeSnapshot(v8_str("numbers")); |
| 247 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); | 247 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 248 CHECK_EQ(NULL, GetProperty(global, v8::HeapGraphEdge::kShortcut, "a")); | 248 CHECK_EQ(NULL, GetProperty(global, v8::HeapGraphEdge::kShortcut, "a")); |
| 249 const v8::HeapGraphNode* b = | 249 const v8::HeapGraphNode* b = |
| 250 GetProperty(global, v8::HeapGraphEdge::kShortcut, "b"); | 250 GetProperty(global, v8::HeapGraphEdge::kShortcut, "b"); |
| 251 CHECK_NE(NULL, b); | 251 CHECK_NE(NULL, b); |
| 252 CHECK_EQ(v8::HeapGraphNode::kHeapNumber, b->GetType()); | 252 CHECK_EQ(v8::HeapGraphNode::kHeapNumber, b->GetType()); |
| 253 } | 253 } |
| 254 | 254 |
| 255 | 255 |
| 256 TEST(HeapSnapshotInternalReferences) { | 256 TEST(HeapSnapshotInternalReferences) { |
| 257 v8::HandleScope scope; | 257 v8::HandleScope scope; |
| 258 v8::Local<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); | 258 v8::Local<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); |
| 259 global_template->SetInternalFieldCount(2); | 259 global_template->SetInternalFieldCount(2); |
| 260 LocalContext env(NULL, global_template); | 260 LocalContext env(NULL, global_template); |
| 261 v8::Handle<v8::Object> global_proxy = env->Global(); | 261 v8::Handle<v8::Object> global_proxy = env->Global(); |
| 262 v8::Handle<v8::Object> global = global_proxy->GetPrototype().As<v8::Object>(); | 262 v8::Handle<v8::Object> global = global_proxy->GetPrototype().As<v8::Object>(); |
| 263 CHECK_EQ(2, global->InternalFieldCount()); | 263 CHECK_EQ(2, global->InternalFieldCount()); |
| 264 v8::Local<v8::Object> obj = v8::Object::New(); | 264 v8::Local<v8::Object> obj = v8::Object::New(); |
| 265 global->SetInternalField(0, v8_num(17)); | 265 global->SetInternalField(0, v8_num(17)); |
| 266 global->SetInternalField(1, obj); | 266 global->SetInternalField(1, obj); |
| 267 const v8::HeapSnapshot* snapshot = | 267 const v8::HeapSnapshot* snapshot = |
| 268 v8::HeapProfiler::TakeSnapshot(v8::String::New("internals")); | 268 v8::HeapProfiler::TakeSnapshot(v8_str("internals")); |
| 269 const v8::HeapGraphNode* global_node = GetGlobalObject(snapshot); | 269 const v8::HeapGraphNode* global_node = GetGlobalObject(snapshot); |
| 270 // The first reference will not present, because it's a Smi. | 270 // The first reference will not present, because it's a Smi. |
| 271 CHECK_EQ(NULL, GetProperty(global_node, v8::HeapGraphEdge::kInternal, "0")); | 271 CHECK_EQ(NULL, GetProperty(global_node, v8::HeapGraphEdge::kInternal, "0")); |
| 272 // The second reference is to an object. | 272 // The second reference is to an object. |
| 273 CHECK_NE(NULL, GetProperty(global_node, v8::HeapGraphEdge::kInternal, "1")); | 273 CHECK_NE(NULL, GetProperty(global_node, v8::HeapGraphEdge::kInternal, "1")); |
| 274 } | 274 } |
| 275 | 275 |
| 276 | 276 |
| 277 // Trying to introduce a check helper for uint64_t causes many | 277 // Trying to introduce a check helper for uint64_t causes many |
| 278 // overloading ambiguities, so it seems easier just to cast | 278 // overloading ambiguities, so it seems easier just to cast |
| 279 // them to a signed type. | 279 // them to a signed type. |
| 280 #define CHECK_EQ_UINT64_T(a, b) \ | 280 #define CHECK_EQ_UINT64_T(a, b) \ |
| 281 CHECK_EQ(static_cast<int64_t>(a), static_cast<int64_t>(b)) | 281 CHECK_EQ(static_cast<int64_t>(a), static_cast<int64_t>(b)) |
| 282 #define CHECK_NE_UINT64_T(a, b) \ | 282 #define CHECK_NE_UINT64_T(a, b) \ |
| 283 CHECK((a) != (b)) // NOLINT | 283 CHECK((a) != (b)) // NOLINT |
| 284 | 284 |
| 285 TEST(HeapEntryIdsAndGC) { | 285 TEST(HeapEntryIdsAndGC) { |
| 286 v8::HandleScope scope; | 286 v8::HandleScope scope; |
| 287 LocalContext env; | 287 LocalContext env; |
| 288 | 288 |
| 289 CompileRun( | 289 CompileRun( |
| 290 "function A() {}\n" | 290 "function A() {}\n" |
| 291 "function B(x) { this.x = x; }\n" | 291 "function B(x) { this.x = x; }\n" |
| 292 "var a = new A();\n" | 292 "var a = new A();\n" |
| 293 "var b = new B(a);"); | 293 "var b = new B(a);"); |
| 294 const v8::HeapSnapshot* snapshot1 = | 294 const v8::HeapSnapshot* snapshot1 = |
| 295 v8::HeapProfiler::TakeSnapshot(v8::String::New("s1")); | 295 v8::HeapProfiler::TakeSnapshot(v8_str("s1")); |
| 296 | 296 |
| 297 HEAP->CollectAllGarbage(true); // Enforce compaction. | 297 HEAP->CollectAllGarbage(true); // Enforce compaction. |
| 298 | 298 |
| 299 const v8::HeapSnapshot* snapshot2 = | 299 const v8::HeapSnapshot* snapshot2 = |
| 300 v8::HeapProfiler::TakeSnapshot(v8::String::New("s2")); | 300 v8::HeapProfiler::TakeSnapshot(v8_str("s2")); |
| 301 | 301 |
| 302 const v8::HeapGraphNode* global1 = GetGlobalObject(snapshot1); | 302 const v8::HeapGraphNode* global1 = GetGlobalObject(snapshot1); |
| 303 const v8::HeapGraphNode* global2 = GetGlobalObject(snapshot2); | 303 const v8::HeapGraphNode* global2 = GetGlobalObject(snapshot2); |
| 304 CHECK_NE_UINT64_T(0, global1->GetId()); | 304 CHECK_NE_UINT64_T(0, global1->GetId()); |
| 305 CHECK_EQ_UINT64_T(global1->GetId(), global2->GetId()); | 305 CHECK_EQ_UINT64_T(global1->GetId(), global2->GetId()); |
| 306 const v8::HeapGraphNode* A1 = | 306 const v8::HeapGraphNode* A1 = |
| 307 GetProperty(global1, v8::HeapGraphEdge::kProperty, "A"); | 307 GetProperty(global1, v8::HeapGraphEdge::kProperty, "A"); |
| 308 CHECK_NE(NULL, A1); | 308 CHECK_NE(NULL, A1); |
| 309 const v8::HeapGraphNode* A2 = | 309 const v8::HeapGraphNode* A2 = |
| 310 GetProperty(global2, v8::HeapGraphEdge::kProperty, "A"); | 310 GetProperty(global2, v8::HeapGraphEdge::kProperty, "A"); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 335 CHECK_NE(NULL, b2); | 335 CHECK_NE(NULL, b2); |
| 336 CHECK_NE_UINT64_T(0, b1->GetId()); | 336 CHECK_NE_UINT64_T(0, b1->GetId()); |
| 337 CHECK_EQ_UINT64_T(b1->GetId(), b2->GetId()); | 337 CHECK_EQ_UINT64_T(b1->GetId(), b2->GetId()); |
| 338 } | 338 } |
| 339 | 339 |
| 340 | 340 |
| 341 TEST(HeapSnapshotRootPreservedAfterSorting) { | 341 TEST(HeapSnapshotRootPreservedAfterSorting) { |
| 342 v8::HandleScope scope; | 342 v8::HandleScope scope; |
| 343 LocalContext env; | 343 LocalContext env; |
| 344 const v8::HeapSnapshot* snapshot = | 344 const v8::HeapSnapshot* snapshot = |
| 345 v8::HeapProfiler::TakeSnapshot(v8::String::New("s")); | 345 v8::HeapProfiler::TakeSnapshot(v8_str("s")); |
| 346 const v8::HeapGraphNode* root1 = snapshot->GetRoot(); | 346 const v8::HeapGraphNode* root1 = snapshot->GetRoot(); |
| 347 const_cast<i::HeapSnapshot*>(reinterpret_cast<const i::HeapSnapshot*>( | 347 const_cast<i::HeapSnapshot*>(reinterpret_cast<const i::HeapSnapshot*>( |
| 348 snapshot))->GetSortedEntriesList(); | 348 snapshot))->GetSortedEntriesList(); |
| 349 const v8::HeapGraphNode* root2 = snapshot->GetRoot(); | 349 const v8::HeapGraphNode* root2 = snapshot->GetRoot(); |
| 350 CHECK_EQ(root1, root2); | 350 CHECK_EQ(root1, root2); |
| 351 } | 351 } |
| 352 | 352 |
| 353 | 353 |
| 354 TEST(HeapEntryDominator) { | 354 TEST(HeapEntryDominator) { |
| 355 // The graph looks like this: | 355 // The graph looks like this: |
| (...skipping 17 matching lines...) Expand all Loading... |
| 373 "function X(a, b) { this.a = a; this.b = b; }\n" | 373 "function X(a, b) { this.a = a; this.b = b; }\n" |
| 374 "node6 = new X(new X(new X()), new X(new X(),new X()));\n" | 374 "node6 = new X(new X(new X()), new X(new X(),new X()));\n" |
| 375 "(function(){\n" | 375 "(function(){\n" |
| 376 "node6.a.a.b = node6.b.a; // node1 -> node2\n" | 376 "node6.a.a.b = node6.b.a; // node1 -> node2\n" |
| 377 "node6.b.a.a = node6.a.a; // node2 -> node1\n" | 377 "node6.b.a.a = node6.a.a; // node2 -> node1\n" |
| 378 "node6.b.a.b = node6.b.b; // node2 -> node3\n" | 378 "node6.b.a.b = node6.b.b; // node2 -> node3\n" |
| 379 "node6.b.b.a = node6.b.a; // node3 -> node2\n" | 379 "node6.b.b.a = node6.b.a; // node3 -> node2\n" |
| 380 "})();"); | 380 "})();"); |
| 381 | 381 |
| 382 const v8::HeapSnapshot* snapshot = | 382 const v8::HeapSnapshot* snapshot = |
| 383 v8::HeapProfiler::TakeSnapshot(v8::String::New("dominators")); | 383 v8::HeapProfiler::TakeSnapshot(v8_str("dominators")); |
| 384 | 384 |
| 385 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); | 385 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 386 CHECK_NE(NULL, global); | 386 CHECK_NE(NULL, global); |
| 387 const v8::HeapGraphNode* node6 = | 387 const v8::HeapGraphNode* node6 = |
| 388 GetProperty(global, v8::HeapGraphEdge::kShortcut, "node6"); | 388 GetProperty(global, v8::HeapGraphEdge::kShortcut, "node6"); |
| 389 CHECK_NE(NULL, node6); | 389 CHECK_NE(NULL, node6); |
| 390 const v8::HeapGraphNode* node5 = | 390 const v8::HeapGraphNode* node5 = |
| 391 GetProperty(node6, v8::HeapGraphEdge::kProperty, "a"); | 391 GetProperty(node6, v8::HeapGraphEdge::kProperty, "a"); |
| 392 CHECK_NE(NULL, node5); | 392 CHECK_NE(NULL, node5); |
| 393 const v8::HeapGraphNode* node4 = | 393 const v8::HeapGraphNode* node4 = |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 456 LocalContext env; | 456 LocalContext env; |
| 457 | 457 |
| 458 #define STRING_LITERAL_FOR_TEST \ | 458 #define STRING_LITERAL_FOR_TEST \ |
| 459 "\"String \\n\\r\\u0008\\u0081\\u0101\\u0801\\u8001\"" | 459 "\"String \\n\\r\\u0008\\u0081\\u0101\\u0801\\u8001\"" |
| 460 CompileRun( | 460 CompileRun( |
| 461 "function A(s) { this.s = s; }\n" | 461 "function A(s) { this.s = s; }\n" |
| 462 "function B(x) { this.x = x; }\n" | 462 "function B(x) { this.x = x; }\n" |
| 463 "var a = new A(" STRING_LITERAL_FOR_TEST ");\n" | 463 "var a = new A(" STRING_LITERAL_FOR_TEST ");\n" |
| 464 "var b = new B(a);"); | 464 "var b = new B(a);"); |
| 465 const v8::HeapSnapshot* snapshot = | 465 const v8::HeapSnapshot* snapshot = |
| 466 v8::HeapProfiler::TakeSnapshot(v8::String::New("json")); | 466 v8::HeapProfiler::TakeSnapshot(v8_str("json")); |
| 467 TestJSONStream stream; | 467 TestJSONStream stream; |
| 468 snapshot->Serialize(&stream, v8::HeapSnapshot::kJSON); | 468 snapshot->Serialize(&stream, v8::HeapSnapshot::kJSON); |
| 469 CHECK_GT(stream.size(), 0); | 469 CHECK_GT(stream.size(), 0); |
| 470 CHECK_EQ(1, stream.eos_signaled()); | 470 CHECK_EQ(1, stream.eos_signaled()); |
| 471 i::ScopedVector<char> json(stream.size()); | 471 i::ScopedVector<char> json(stream.size()); |
| 472 stream.WriteTo(json); | 472 stream.WriteTo(json); |
| 473 | 473 |
| 474 // Verify that snapshot string is valid JSON. | 474 // Verify that snapshot string is valid JSON. |
| 475 AsciiResource json_res(json); | 475 AsciiResource json_res(json); |
| 476 v8::Local<v8::String> json_string = v8::String::NewExternal(&json_res); | 476 v8::Local<v8::String> json_string = v8::String::NewExternal(&json_res); |
| 477 env->Global()->Set(v8::String::New("json_snapshot"), json_string); | 477 env->Global()->Set(v8_str("json_snapshot"), json_string); |
| 478 v8::Local<v8::Value> snapshot_parse_result = CompileRun( | 478 v8::Local<v8::Value> snapshot_parse_result = CompileRun( |
| 479 "var parsed = JSON.parse(json_snapshot); true;"); | 479 "var parsed = JSON.parse(json_snapshot); true;"); |
| 480 CHECK(!snapshot_parse_result.IsEmpty()); | 480 CHECK(!snapshot_parse_result.IsEmpty()); |
| 481 | 481 |
| 482 // Verify that snapshot object has required fields. | 482 // Verify that snapshot object has required fields. |
| 483 v8::Local<v8::Object> parsed_snapshot = | 483 v8::Local<v8::Object> parsed_snapshot = |
| 484 env->Global()->Get(v8::String::New("parsed"))->ToObject(); | 484 env->Global()->Get(v8_str("parsed"))->ToObject(); |
| 485 CHECK(parsed_snapshot->Has(v8::String::New("snapshot"))); | 485 CHECK(parsed_snapshot->Has(v8_str("snapshot"))); |
| 486 CHECK(parsed_snapshot->Has(v8::String::New("nodes"))); | 486 CHECK(parsed_snapshot->Has(v8_str("nodes"))); |
| 487 CHECK(parsed_snapshot->Has(v8::String::New("strings"))); | 487 CHECK(parsed_snapshot->Has(v8_str("strings"))); |
| 488 | 488 |
| 489 // Get node and edge "member" offsets. | 489 // Get node and edge "member" offsets. |
| 490 v8::Local<v8::Value> meta_analysis_result = CompileRun( | 490 v8::Local<v8::Value> meta_analysis_result = CompileRun( |
| 491 "var parsed_meta = parsed.nodes[0];\n" | 491 "var parsed_meta = parsed.nodes[0];\n" |
| 492 "var children_count_offset =" | 492 "var children_count_offset =" |
| 493 " parsed_meta.fields.indexOf('children_count');\n" | 493 " parsed_meta.fields.indexOf('children_count');\n" |
| 494 "var children_offset =" | 494 "var children_offset =" |
| 495 " parsed_meta.fields.indexOf('children');\n" | 495 " parsed_meta.fields.indexOf('children');\n" |
| 496 "var children_meta =" | 496 "var children_meta =" |
| 497 " parsed_meta.types[children_offset];\n" | 497 " parsed_meta.types[children_offset];\n" |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 529 " GetChildPosByProperty(\n" | 529 " GetChildPosByProperty(\n" |
| 530 " GetChildPosByProperty(" | 530 " GetChildPosByProperty(" |
| 531 " parsed.nodes[1 + children_offset + child_to_node_offset]," | 531 " parsed.nodes[1 + children_offset + child_to_node_offset]," |
| 532 " \"b\",shortcut_type),\n" | 532 " \"b\",shortcut_type),\n" |
| 533 " \"x\", property_type)," | 533 " \"x\", property_type)," |
| 534 " \"s\", property_type)"); | 534 " \"s\", property_type)"); |
| 535 CHECK(!string_obj_pos_val.IsEmpty()); | 535 CHECK(!string_obj_pos_val.IsEmpty()); |
| 536 int string_obj_pos = | 536 int string_obj_pos = |
| 537 static_cast<int>(string_obj_pos_val->ToNumber()->Value()); | 537 static_cast<int>(string_obj_pos_val->ToNumber()->Value()); |
| 538 v8::Local<v8::Object> nodes_array = | 538 v8::Local<v8::Object> nodes_array = |
| 539 parsed_snapshot->Get(v8::String::New("nodes"))->ToObject(); | 539 parsed_snapshot->Get(v8_str("nodes"))->ToObject(); |
| 540 int string_index = static_cast<int>( | 540 int string_index = static_cast<int>( |
| 541 nodes_array->Get(string_obj_pos + 1)->ToNumber()->Value()); | 541 nodes_array->Get(string_obj_pos + 1)->ToNumber()->Value()); |
| 542 CHECK_GT(string_index, 0); | 542 CHECK_GT(string_index, 0); |
| 543 v8::Local<v8::Object> strings_array = | 543 v8::Local<v8::Object> strings_array = |
| 544 parsed_snapshot->Get(v8::String::New("strings"))->ToObject(); | 544 parsed_snapshot->Get(v8_str("strings"))->ToObject(); |
| 545 v8::Local<v8::String> string = strings_array->Get(string_index)->ToString(); | 545 v8::Local<v8::String> string = strings_array->Get(string_index)->ToString(); |
| 546 v8::Local<v8::String> ref_string = | 546 v8::Local<v8::String> ref_string = |
| 547 CompileRun(STRING_LITERAL_FOR_TEST)->ToString(); | 547 CompileRun(STRING_LITERAL_FOR_TEST)->ToString(); |
| 548 #undef STRING_LITERAL_FOR_TEST | 548 #undef STRING_LITERAL_FOR_TEST |
| 549 CHECK_EQ(*v8::String::Utf8Value(ref_string), | 549 CHECK_EQ(*v8::String::Utf8Value(ref_string), |
| 550 *v8::String::Utf8Value(string)); | 550 *v8::String::Utf8Value(string)); |
| 551 } | 551 } |
| 552 | 552 |
| 553 | 553 |
| 554 TEST(HeapSnapshotJSONSerializationAborting) { | 554 TEST(HeapSnapshotJSONSerializationAborting) { |
| 555 v8::HandleScope scope; | 555 v8::HandleScope scope; |
| 556 LocalContext env; | 556 LocalContext env; |
| 557 const v8::HeapSnapshot* snapshot = | 557 const v8::HeapSnapshot* snapshot = |
| 558 v8::HeapProfiler::TakeSnapshot(v8::String::New("abort")); | 558 v8::HeapProfiler::TakeSnapshot(v8_str("abort")); |
| 559 TestJSONStream stream(5); | 559 TestJSONStream stream(5); |
| 560 snapshot->Serialize(&stream, v8::HeapSnapshot::kJSON); | 560 snapshot->Serialize(&stream, v8::HeapSnapshot::kJSON); |
| 561 CHECK_GT(stream.size(), 0); | 561 CHECK_GT(stream.size(), 0); |
| 562 CHECK_EQ(0, stream.eos_signaled()); | 562 CHECK_EQ(0, stream.eos_signaled()); |
| 563 } | 563 } |
| 564 | 564 |
| 565 | 565 |
| 566 TEST(HeapSnapshotGetNodeById) { | 566 TEST(HeapSnapshotGetNodeById) { |
| 567 v8::HandleScope scope; | 567 v8::HandleScope scope; |
| 568 LocalContext env; | 568 LocalContext env; |
| 569 | 569 |
| 570 const v8::HeapSnapshot* snapshot = | 570 const v8::HeapSnapshot* snapshot = |
| 571 v8::HeapProfiler::TakeSnapshot(v8::String::New("id")); | 571 v8::HeapProfiler::TakeSnapshot(v8_str("id")); |
| 572 const v8::HeapGraphNode* root = snapshot->GetRoot(); | 572 const v8::HeapGraphNode* root = snapshot->GetRoot(); |
| 573 CHECK_EQ(root, snapshot->GetNodeById(root->GetId())); | 573 CHECK_EQ(root, snapshot->GetNodeById(root->GetId())); |
| 574 for (int i = 0, count = root->GetChildrenCount(); i < count; ++i) { | 574 for (int i = 0, count = root->GetChildrenCount(); i < count; ++i) { |
| 575 const v8::HeapGraphEdge* prop = root->GetChild(i); | 575 const v8::HeapGraphEdge* prop = root->GetChild(i); |
| 576 CHECK_EQ( | 576 CHECK_EQ( |
| 577 prop->GetToNode(), snapshot->GetNodeById(prop->GetToNode()->GetId())); | 577 prop->GetToNode(), snapshot->GetNodeById(prop->GetToNode()->GetId())); |
| 578 } | 578 } |
| 579 // Check a big id, which should not exist yet. | 579 // Check a big id, which should not exist yet. |
| 580 CHECK_EQ(NULL, snapshot->GetNodeById(0x1000000UL)); | 580 CHECK_EQ(NULL, snapshot->GetNodeById(0x1000000UL)); |
| 581 } | 581 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 602 }; | 602 }; |
| 603 } | 603 } |
| 604 | 604 |
| 605 TEST(TakeHeapSnapshotAborting) { | 605 TEST(TakeHeapSnapshotAborting) { |
| 606 v8::HandleScope scope; | 606 v8::HandleScope scope; |
| 607 LocalContext env; | 607 LocalContext env; |
| 608 | 608 |
| 609 const int snapshots_count = v8::HeapProfiler::GetSnapshotsCount(); | 609 const int snapshots_count = v8::HeapProfiler::GetSnapshotsCount(); |
| 610 TestActivityControl aborting_control(3); | 610 TestActivityControl aborting_control(3); |
| 611 const v8::HeapSnapshot* no_snapshot = | 611 const v8::HeapSnapshot* no_snapshot = |
| 612 v8::HeapProfiler::TakeSnapshot(v8::String::New("abort"), | 612 v8::HeapProfiler::TakeSnapshot(v8_str("abort"), |
| 613 v8::HeapSnapshot::kFull, | 613 v8::HeapSnapshot::kFull, |
| 614 &aborting_control); | 614 &aborting_control); |
| 615 CHECK_EQ(NULL, no_snapshot); | 615 CHECK_EQ(NULL, no_snapshot); |
| 616 CHECK_EQ(snapshots_count, v8::HeapProfiler::GetSnapshotsCount()); | 616 CHECK_EQ(snapshots_count, v8::HeapProfiler::GetSnapshotsCount()); |
| 617 CHECK_GT(aborting_control.total(), aborting_control.done()); | 617 CHECK_GT(aborting_control.total(), aborting_control.done()); |
| 618 | 618 |
| 619 TestActivityControl control(-1); // Don't abort. | 619 TestActivityControl control(-1); // Don't abort. |
| 620 const v8::HeapSnapshot* snapshot = | 620 const v8::HeapSnapshot* snapshot = |
| 621 v8::HeapProfiler::TakeSnapshot(v8::String::New("full"), | 621 v8::HeapProfiler::TakeSnapshot(v8_str("full"), |
| 622 v8::HeapSnapshot::kFull, | 622 v8::HeapSnapshot::kFull, |
| 623 &control); | 623 &control); |
| 624 CHECK_NE(NULL, snapshot); | 624 CHECK_NE(NULL, snapshot); |
| 625 CHECK_EQ(snapshots_count + 1, v8::HeapProfiler::GetSnapshotsCount()); | 625 CHECK_EQ(snapshots_count + 1, v8::HeapProfiler::GetSnapshotsCount()); |
| 626 CHECK_EQ(control.total(), control.done()); | 626 CHECK_EQ(control.total(), control.done()); |
| 627 CHECK_GT(control.total(), 0); | 627 CHECK_GT(control.total(), 0); |
| 628 } | 628 } |
| 629 | 629 |
| 630 | 630 |
| 631 namespace { | 631 namespace { |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 721 v8::Persistent<v8::String>::New(v8_str("AAA")); | 721 v8::Persistent<v8::String>::New(v8_str("AAA")); |
| 722 p_AAA.SetWrapperClassId(1); | 722 p_AAA.SetWrapperClassId(1); |
| 723 v8::Persistent<v8::String> p_BBB = | 723 v8::Persistent<v8::String> p_BBB = |
| 724 v8::Persistent<v8::String>::New(v8_str("BBB")); | 724 v8::Persistent<v8::String>::New(v8_str("BBB")); |
| 725 p_BBB.SetWrapperClassId(1); | 725 p_BBB.SetWrapperClassId(1); |
| 726 v8::Persistent<v8::String> p_CCC = | 726 v8::Persistent<v8::String> p_CCC = |
| 727 v8::Persistent<v8::String>::New(v8_str("CCC")); | 727 v8::Persistent<v8::String>::New(v8_str("CCC")); |
| 728 p_CCC.SetWrapperClassId(2); | 728 p_CCC.SetWrapperClassId(2); |
| 729 CHECK_EQ(0, TestRetainedObjectInfo::instances.length()); | 729 CHECK_EQ(0, TestRetainedObjectInfo::instances.length()); |
| 730 const v8::HeapSnapshot* snapshot = | 730 const v8::HeapSnapshot* snapshot = |
| 731 v8::HeapProfiler::TakeSnapshot(v8::String::New("retained")); | 731 v8::HeapProfiler::TakeSnapshot(v8_str("retained")); |
| 732 | 732 |
| 733 CHECK_EQ(3, TestRetainedObjectInfo::instances.length()); | 733 CHECK_EQ(3, TestRetainedObjectInfo::instances.length()); |
| 734 for (int i = 0; i < TestRetainedObjectInfo::instances.length(); ++i) { | 734 for (int i = 0; i < TestRetainedObjectInfo::instances.length(); ++i) { |
| 735 CHECK(TestRetainedObjectInfo::instances[i]->disposed()); | 735 CHECK(TestRetainedObjectInfo::instances[i]->disposed()); |
| 736 delete TestRetainedObjectInfo::instances[i]; | 736 delete TestRetainedObjectInfo::instances[i]; |
| 737 } | 737 } |
| 738 | 738 |
| 739 const v8::HeapGraphNode* natives = GetNode( | 739 const v8::HeapGraphNode* natives = GetNode( |
| 740 snapshot->GetRoot(), v8::HeapGraphNode::kObject, "(Native objects)"); | 740 snapshot->GetRoot(), v8::HeapGraphNode::kObject, "(Native objects)"); |
| 741 CHECK_NE(NULL, natives); | 741 CHECK_NE(NULL, natives); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 765 } | 765 } |
| 766 | 766 |
| 767 | 767 |
| 768 TEST(DeleteAllHeapSnapshots) { | 768 TEST(DeleteAllHeapSnapshots) { |
| 769 v8::HandleScope scope; | 769 v8::HandleScope scope; |
| 770 LocalContext env; | 770 LocalContext env; |
| 771 | 771 |
| 772 CHECK_EQ(0, v8::HeapProfiler::GetSnapshotsCount()); | 772 CHECK_EQ(0, v8::HeapProfiler::GetSnapshotsCount()); |
| 773 v8::HeapProfiler::DeleteAllSnapshots(); | 773 v8::HeapProfiler::DeleteAllSnapshots(); |
| 774 CHECK_EQ(0, v8::HeapProfiler::GetSnapshotsCount()); | 774 CHECK_EQ(0, v8::HeapProfiler::GetSnapshotsCount()); |
| 775 CHECK_NE(NULL, v8::HeapProfiler::TakeSnapshot(v8::String::New("1"))); | 775 CHECK_NE(NULL, v8::HeapProfiler::TakeSnapshot(v8_str("1"))); |
| 776 CHECK_EQ(1, v8::HeapProfiler::GetSnapshotsCount()); | 776 CHECK_EQ(1, v8::HeapProfiler::GetSnapshotsCount()); |
| 777 v8::HeapProfiler::DeleteAllSnapshots(); | 777 v8::HeapProfiler::DeleteAllSnapshots(); |
| 778 CHECK_EQ(0, v8::HeapProfiler::GetSnapshotsCount()); | 778 CHECK_EQ(0, v8::HeapProfiler::GetSnapshotsCount()); |
| 779 CHECK_NE(NULL, v8::HeapProfiler::TakeSnapshot(v8::String::New("1"))); | 779 CHECK_NE(NULL, v8::HeapProfiler::TakeSnapshot(v8_str("1"))); |
| 780 CHECK_NE(NULL, v8::HeapProfiler::TakeSnapshot(v8::String::New("2"))); | 780 CHECK_NE(NULL, v8::HeapProfiler::TakeSnapshot(v8_str("2"))); |
| 781 CHECK_EQ(2, v8::HeapProfiler::GetSnapshotsCount()); | 781 CHECK_EQ(2, v8::HeapProfiler::GetSnapshotsCount()); |
| 782 v8::HeapProfiler::DeleteAllSnapshots(); | 782 v8::HeapProfiler::DeleteAllSnapshots(); |
| 783 CHECK_EQ(0, v8::HeapProfiler::GetSnapshotsCount()); | 783 CHECK_EQ(0, v8::HeapProfiler::GetSnapshotsCount()); |
| 784 } | 784 } |
| 785 | 785 |
| 786 | 786 |
| 787 TEST(DeleteHeapSnapshot) { | 787 TEST(DeleteHeapSnapshot) { |
| 788 v8::HandleScope scope; | 788 v8::HandleScope scope; |
| 789 LocalContext env; | 789 LocalContext env; |
| 790 | 790 |
| 791 CHECK_EQ(0, v8::HeapProfiler::GetSnapshotsCount()); | 791 CHECK_EQ(0, v8::HeapProfiler::GetSnapshotsCount()); |
| 792 const v8::HeapSnapshot* s1 = | 792 const v8::HeapSnapshot* s1 = |
| 793 v8::HeapProfiler::TakeSnapshot(v8::String::New("1")); | 793 v8::HeapProfiler::TakeSnapshot(v8_str("1")); |
| 794 CHECK_NE(NULL, s1); | 794 CHECK_NE(NULL, s1); |
| 795 CHECK_EQ(1, v8::HeapProfiler::GetSnapshotsCount()); | 795 CHECK_EQ(1, v8::HeapProfiler::GetSnapshotsCount()); |
| 796 unsigned uid1 = s1->GetUid(); | 796 unsigned uid1 = s1->GetUid(); |
| 797 CHECK_EQ(s1, v8::HeapProfiler::FindSnapshot(uid1)); | 797 CHECK_EQ(s1, v8::HeapProfiler::FindSnapshot(uid1)); |
| 798 const_cast<v8::HeapSnapshot*>(s1)->Delete(); | 798 const_cast<v8::HeapSnapshot*>(s1)->Delete(); |
| 799 CHECK_EQ(0, v8::HeapProfiler::GetSnapshotsCount()); | 799 CHECK_EQ(0, v8::HeapProfiler::GetSnapshotsCount()); |
| 800 CHECK_EQ(NULL, v8::HeapProfiler::FindSnapshot(uid1)); | 800 CHECK_EQ(NULL, v8::HeapProfiler::FindSnapshot(uid1)); |
| 801 | 801 |
| 802 const v8::HeapSnapshot* s2 = | 802 const v8::HeapSnapshot* s2 = |
| 803 v8::HeapProfiler::TakeSnapshot(v8::String::New("2")); | 803 v8::HeapProfiler::TakeSnapshot(v8_str("2")); |
| 804 CHECK_NE(NULL, s2); | 804 CHECK_NE(NULL, s2); |
| 805 CHECK_EQ(1, v8::HeapProfiler::GetSnapshotsCount()); | 805 CHECK_EQ(1, v8::HeapProfiler::GetSnapshotsCount()); |
| 806 unsigned uid2 = s2->GetUid(); | 806 unsigned uid2 = s2->GetUid(); |
| 807 CHECK_NE(static_cast<int>(uid1), static_cast<int>(uid2)); | 807 CHECK_NE(static_cast<int>(uid1), static_cast<int>(uid2)); |
| 808 CHECK_EQ(s2, v8::HeapProfiler::FindSnapshot(uid2)); | 808 CHECK_EQ(s2, v8::HeapProfiler::FindSnapshot(uid2)); |
| 809 const v8::HeapSnapshot* s3 = | 809 const v8::HeapSnapshot* s3 = |
| 810 v8::HeapProfiler::TakeSnapshot(v8::String::New("3")); | 810 v8::HeapProfiler::TakeSnapshot(v8_str("3")); |
| 811 CHECK_NE(NULL, s3); | 811 CHECK_NE(NULL, s3); |
| 812 CHECK_EQ(2, v8::HeapProfiler::GetSnapshotsCount()); | 812 CHECK_EQ(2, v8::HeapProfiler::GetSnapshotsCount()); |
| 813 unsigned uid3 = s3->GetUid(); | 813 unsigned uid3 = s3->GetUid(); |
| 814 CHECK_NE(static_cast<int>(uid1), static_cast<int>(uid3)); | 814 CHECK_NE(static_cast<int>(uid1), static_cast<int>(uid3)); |
| 815 CHECK_EQ(s3, v8::HeapProfiler::FindSnapshot(uid3)); | 815 CHECK_EQ(s3, v8::HeapProfiler::FindSnapshot(uid3)); |
| 816 const_cast<v8::HeapSnapshot*>(s2)->Delete(); | 816 const_cast<v8::HeapSnapshot*>(s2)->Delete(); |
| 817 CHECK_EQ(1, v8::HeapProfiler::GetSnapshotsCount()); | 817 CHECK_EQ(1, v8::HeapProfiler::GetSnapshotsCount()); |
| 818 CHECK_EQ(NULL, v8::HeapProfiler::FindSnapshot(uid2)); | 818 CHECK_EQ(NULL, v8::HeapProfiler::FindSnapshot(uid2)); |
| 819 CHECK_EQ(s3, v8::HeapProfiler::FindSnapshot(uid3)); | 819 CHECK_EQ(s3, v8::HeapProfiler::FindSnapshot(uid3)); |
| 820 const_cast<v8::HeapSnapshot*>(s3)->Delete(); | 820 const_cast<v8::HeapSnapshot*>(s3)->Delete(); |
| 821 CHECK_EQ(0, v8::HeapProfiler::GetSnapshotsCount()); | 821 CHECK_EQ(0, v8::HeapProfiler::GetSnapshotsCount()); |
| 822 CHECK_EQ(NULL, v8::HeapProfiler::FindSnapshot(uid3)); | 822 CHECK_EQ(NULL, v8::HeapProfiler::FindSnapshot(uid3)); |
| 823 } | 823 } |
| 824 | 824 |
| 825 | 825 |
| 826 TEST(DocumentURL) { | 826 TEST(DocumentURL) { |
| 827 v8::HandleScope scope; | 827 v8::HandleScope scope; |
| 828 LocalContext env; | 828 LocalContext env; |
| 829 | 829 |
| 830 CompileRun("document = { URL:\"abcdefgh\" };"); | 830 CompileRun("document = { URL:\"abcdefgh\" };"); |
| 831 | 831 |
| 832 const v8::HeapSnapshot* snapshot = | 832 const v8::HeapSnapshot* snapshot = |
| 833 v8::HeapProfiler::TakeSnapshot(v8::String::New("document")); | 833 v8::HeapProfiler::TakeSnapshot(v8_str("document")); |
| 834 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); | 834 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 835 CHECK_NE(NULL, global); | 835 CHECK_NE(NULL, global); |
| 836 CHECK_EQ("Object / abcdefgh", | 836 CHECK_EQ("Object / abcdefgh", |
| 837 const_cast<i::HeapEntry*>( | 837 const_cast<i::HeapEntry*>( |
| 838 reinterpret_cast<const i::HeapEntry*>(global))->name()); | 838 reinterpret_cast<const i::HeapEntry*>(global))->name()); |
| 839 } | 839 } |
| 840 | 840 |
| 841 | 841 |
| 842 TEST(DocumentWithException) { | 842 TEST(DocumentWithException) { |
| 843 v8::HandleScope scope; | 843 v8::HandleScope scope; |
| 844 LocalContext env; | 844 LocalContext env; |
| 845 | 845 |
| 846 CompileRun( | 846 CompileRun( |
| 847 "this.__defineGetter__(\"document\", function() { throw new Error(); })"); | 847 "this.__defineGetter__(\"document\", function() { throw new Error(); })"); |
| 848 const v8::HeapSnapshot* snapshot = | 848 const v8::HeapSnapshot* snapshot = |
| 849 v8::HeapProfiler::TakeSnapshot(v8::String::New("document")); | 849 v8::HeapProfiler::TakeSnapshot(v8_str("document")); |
| 850 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); | 850 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 851 CHECK_NE(NULL, global); | 851 CHECK_NE(NULL, global); |
| 852 CHECK_EQ("Object", | 852 CHECK_EQ("Object", |
| 853 const_cast<i::HeapEntry*>( | 853 const_cast<i::HeapEntry*>( |
| 854 reinterpret_cast<const i::HeapEntry*>(global))->name()); | 854 reinterpret_cast<const i::HeapEntry*>(global))->name()); |
| 855 } | 855 } |
| 856 | 856 |
| 857 | 857 |
| 858 TEST(DocumentURLWithException) { | 858 TEST(DocumentURLWithException) { |
| 859 v8::HandleScope scope; | 859 v8::HandleScope scope; |
| 860 LocalContext env; | 860 LocalContext env; |
| 861 | 861 |
| 862 CompileRun( | 862 CompileRun( |
| 863 "function URLWithException() {}\n" | 863 "function URLWithException() {}\n" |
| 864 "URLWithException.prototype = { get URL() { throw new Error(); } };\n" | 864 "URLWithException.prototype = { get URL() { throw new Error(); } };\n" |
| 865 "document = { URL: new URLWithException() };"); | 865 "document = { URL: new URLWithException() };"); |
| 866 const v8::HeapSnapshot* snapshot = | 866 const v8::HeapSnapshot* snapshot = |
| 867 v8::HeapProfiler::TakeSnapshot(v8::String::New("document")); | 867 v8::HeapProfiler::TakeSnapshot(v8_str("document")); |
| 868 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); | 868 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 869 CHECK_NE(NULL, global); | 869 CHECK_NE(NULL, global); |
| 870 CHECK_EQ("Object", | 870 CHECK_EQ("Object", |
| 871 const_cast<i::HeapEntry*>( | 871 const_cast<i::HeapEntry*>( |
| 872 reinterpret_cast<const i::HeapEntry*>(global))->name()); | 872 reinterpret_cast<const i::HeapEntry*>(global))->name()); |
| 873 } | 873 } |
| 874 | 874 |
| 875 | 875 |
| 876 TEST(NodesIteration) { | 876 TEST(NodesIteration) { |
| 877 v8::HandleScope scope; | 877 v8::HandleScope scope; |
| 878 LocalContext env; | 878 LocalContext env; |
| 879 const v8::HeapSnapshot* snapshot = | 879 const v8::HeapSnapshot* snapshot = |
| 880 v8::HeapProfiler::TakeSnapshot(v8::String::New("iteration")); | 880 v8::HeapProfiler::TakeSnapshot(v8_str("iteration")); |
| 881 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); | 881 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 882 CHECK_NE(NULL, global); | 882 CHECK_NE(NULL, global); |
| 883 // Verify that we can find this object by iteration. | 883 // Verify that we can find this object by iteration. |
| 884 const int nodes_count = snapshot->GetNodesCount(); | 884 const int nodes_count = snapshot->GetNodesCount(); |
| 885 int count = 0; | 885 int count = 0; |
| 886 for (int i = 0; i < nodes_count; ++i) { | 886 for (int i = 0; i < nodes_count; ++i) { |
| 887 if (snapshot->GetNode(i) == global) | 887 if (snapshot->GetNode(i) == global) |
| 888 ++count; | 888 ++count; |
| 889 } | 889 } |
| 890 CHECK_EQ(1, count); | 890 CHECK_EQ(1, count); |
| 891 } | 891 } |
| 892 | 892 |
| 893 | 893 |
| 894 TEST(GetHeapValue) { |
| 895 v8::HandleScope scope; |
| 896 LocalContext env; |
| 897 |
| 898 CompileRun("a = { s_prop: \'value\', n_prop: 0.1 };"); |
| 899 const v8::HeapSnapshot* snapshot = |
| 900 v8::HeapProfiler::TakeSnapshot(v8_str("value")); |
| 901 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 902 CHECK(global->GetHeapValue()->IsObject()); |
| 903 v8::Local<v8::Object> js_global = |
| 904 env->Global()->GetPrototype().As<v8::Object>(); |
| 905 CHECK(js_global == global->GetHeapValue()); |
| 906 const v8::HeapGraphNode* obj = GetProperty( |
| 907 global, v8::HeapGraphEdge::kShortcut, "a"); |
| 908 CHECK(obj->GetHeapValue()->IsObject()); |
| 909 v8::Local<v8::Object> js_obj = js_global->Get(v8_str("a")).As<v8::Object>(); |
| 910 CHECK(js_obj == obj->GetHeapValue()); |
| 911 const v8::HeapGraphNode* s_prop = |
| 912 GetProperty(obj, v8::HeapGraphEdge::kProperty, "s_prop"); |
| 913 v8::Local<v8::String> js_s_prop = |
| 914 js_obj->Get(v8_str("s_prop")).As<v8::String>(); |
| 915 CHECK(js_s_prop == s_prop->GetHeapValue()); |
| 916 const v8::HeapGraphNode* n_prop = |
| 917 GetProperty(obj, v8::HeapGraphEdge::kProperty, "n_prop"); |
| 918 v8::Local<v8::Number> js_n_prop = |
| 919 js_obj->Get(v8_str("n_prop")).As<v8::Number>(); |
| 920 CHECK(js_n_prop == n_prop->GetHeapValue()); |
| 921 } |
| 922 |
| 923 |
| 924 TEST(GetHeapValueForDeletedObject) { |
| 925 v8::HandleScope scope; |
| 926 LocalContext env; |
| 927 |
| 928 // It is impossible to delete a global property, so we are about to delete a |
| 929 // property of the "a" object. Also, the "p" object can't be an empty one |
| 930 // because the empty object is static and isn't actually deleted. |
| 931 CompileRun("a = { p: { r: {} } };"); |
| 932 const v8::HeapSnapshot* snapshot = |
| 933 v8::HeapProfiler::TakeSnapshot(v8_str("snapshot")); |
| 934 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 935 const v8::HeapGraphNode* obj = GetProperty( |
| 936 global, v8::HeapGraphEdge::kShortcut, "a"); |
| 937 const v8::HeapGraphNode* prop = GetProperty( |
| 938 obj, v8::HeapGraphEdge::kProperty, "p"); |
| 939 { |
| 940 // Perform the check inside a nested local scope to avoid creating a |
| 941 // reference to the object we are deleting. |
| 942 v8::HandleScope scope; |
| 943 CHECK(prop->GetHeapValue()->IsObject()); |
| 944 } |
| 945 CompileRun("delete a.p;"); |
| 946 CHECK(prop->GetHeapValue()->IsUndefined()); |
| 947 } |
| 948 |
| 949 |
| 894 static int StringCmp(const char* ref, i::String* act) { | 950 static int StringCmp(const char* ref, i::String* act) { |
| 895 i::SmartPointer<char> s_act = act->ToCString(); | 951 i::SmartPointer<char> s_act = act->ToCString(); |
| 896 int result = strcmp(ref, *s_act); | 952 int result = strcmp(ref, *s_act); |
| 897 if (result != 0) | 953 if (result != 0) |
| 898 fprintf(stderr, "Expected: \"%s\", Actual: \"%s\"\n", ref, *s_act); | 954 fprintf(stderr, "Expected: \"%s\", Actual: \"%s\"\n", ref, *s_act); |
| 899 return result; | 955 return result; |
| 900 } | 956 } |
| 901 | 957 |
| 902 | 958 |
| 903 TEST(GetConstructorName) { | 959 TEST(GetConstructorName) { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 938 "Constructor4", i::V8HeapExplorer::GetConstructorName(*js_obj4))); | 994 "Constructor4", i::V8HeapExplorer::GetConstructorName(*js_obj4))); |
| 939 v8::Local<v8::Object> obj5 = js_global->Get(v8_str("obj5")).As<v8::Object>(); | 995 v8::Local<v8::Object> obj5 = js_global->Get(v8_str("obj5")).As<v8::Object>(); |
| 940 i::Handle<i::JSObject> js_obj5 = v8::Utils::OpenHandle(*obj5); | 996 i::Handle<i::JSObject> js_obj5 = v8::Utils::OpenHandle(*obj5); |
| 941 CHECK_EQ(0, StringCmp( | 997 CHECK_EQ(0, StringCmp( |
| 942 "Object", i::V8HeapExplorer::GetConstructorName(*js_obj5))); | 998 "Object", i::V8HeapExplorer::GetConstructorName(*js_obj5))); |
| 943 v8::Local<v8::Object> obj6 = js_global->Get(v8_str("obj6")).As<v8::Object>(); | 999 v8::Local<v8::Object> obj6 = js_global->Get(v8_str("obj6")).As<v8::Object>(); |
| 944 i::Handle<i::JSObject> js_obj6 = v8::Utils::OpenHandle(*obj6); | 1000 i::Handle<i::JSObject> js_obj6 = v8::Utils::OpenHandle(*obj6); |
| 945 CHECK_EQ(0, StringCmp( | 1001 CHECK_EQ(0, StringCmp( |
| 946 "Object", i::V8HeapExplorer::GetConstructorName(*js_obj6))); | 1002 "Object", i::V8HeapExplorer::GetConstructorName(*js_obj6))); |
| 947 } | 1003 } |
| OLD | NEW |