Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(66)

Side by Side Diff: test/cctest/test-heap-profiler.cc

Issue 2822009: Heap profiler: publish API and add test. (Closed)
Patch Set: comments addressed Created 10 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/v8.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 the V8 project authors. All rights reserved.
2 // 2 //
3 // Tests for heap profiler 3 // Tests for heap profiler
4 4
5 #ifdef ENABLE_LOGGING_AND_PROFILING 5 #ifdef ENABLE_LOGGING_AND_PROFILING
6 6
7 #include "v8.h" 7 #include "v8.h"
8 #include "heap-profiler.h" 8 #include "heap-profiler.h"
9 #include "string-stream.h" 9 #include "string-stream.h"
10 #include "cctest.h" 10 #include "cctest.h"
11 #include "zone-inl.h" 11 #include "zone-inl.h"
12 #include "../include/v8-profiler.h"
12 13
13 namespace i = v8::internal; 14 namespace i = v8::internal;
14 using i::ClustersCoarser; 15 using i::ClustersCoarser;
15 using i::JSObjectsCluster; 16 using i::JSObjectsCluster;
16 using i::JSObjectsRetainerTree; 17 using i::JSObjectsRetainerTree;
17 using i::JSObjectsClusterTree; 18 using i::JSObjectsClusterTree;
18 using i::RetainerHeapProfile; 19 using i::RetainerHeapProfile;
19 20
20 21
21 static void CompileAndRunScript(const char *src) { 22 static void CompileAndRunScript(const char *src) {
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 // verify each retainer separately. 384 // verify each retainer separately.
384 CHECK_EQ(i::StrLength("(global property);1,B;2,C;2"), 385 CHECK_EQ(i::StrLength("(global property);1,B;2,C;2"),
385 i::StrLength(retainers_of_a)); 386 i::StrLength(retainers_of_a));
386 CHECK(strstr(retainers_of_a, "(global property);1") != NULL); 387 CHECK(strstr(retainers_of_a, "(global property);1") != NULL);
387 CHECK(strstr(retainers_of_a, "B;2") != NULL); 388 CHECK(strstr(retainers_of_a, "B;2") != NULL);
388 CHECK(strstr(retainers_of_a, "C;2") != NULL); 389 CHECK(strstr(retainers_of_a, "C;2") != NULL);
389 CHECK_EQ("(global property);2", printer.GetRetainers("B")); 390 CHECK_EQ("(global property);2", printer.GetRetainers("B"));
390 CHECK_EQ("(global property);1", printer.GetRetainers("C")); 391 CHECK_EQ("(global property);1", printer.GetRetainers("C"));
391 } 392 }
392 393
394
395 namespace {
396
397 class NamedEntriesDetector {
398 public:
399 NamedEntriesDetector()
400 : has_A1(false), has_B1(false), has_C1(false),
401 has_A2(false), has_B2(false), has_C2(false) {
402 }
403
404 void Apply(i::HeapEntry* entry) {
405 const char* node_name = entry->name();
406 if (strcmp("A1", node_name) == 0
407 && entry->GetRetainingPaths()->length() > 0) has_A1 = true;
408 if (strcmp("B1", node_name) == 0
409 && entry->GetRetainingPaths()->length() > 0) has_B1 = true;
410 if (strcmp("C1", node_name) == 0
411 && entry->GetRetainingPaths()->length() > 0) has_C1 = true;
412 if (strcmp("A2", node_name) == 0
413 && entry->GetRetainingPaths()->length() > 0) has_A2 = true;
414 if (strcmp("B2", node_name) == 0
415 && entry->GetRetainingPaths()->length() > 0) has_B2 = true;
416 if (strcmp("C2", node_name) == 0
417 && entry->GetRetainingPaths()->length() > 0) has_C2 = true;
418 }
419
420 bool has_A1;
421 bool has_B1;
422 bool has_C1;
423 bool has_A2;
424 bool has_B2;
425 bool has_C2;
426 };
427
428 } // namespace
429
430 TEST(HeapSnapshot) {
431 v8::HandleScope scope;
432
433 v8::Handle<v8::String> token1 = v8::String::New("token1");
434 v8::Handle<v8::Context> env1 = v8::Context::New();
435 env1->SetSecurityToken(token1);
436 env1->Enter();
437
438 CompileAndRunScript(
439 "function A1() {}\n"
440 "function B1(x) { this.x = x; }\n"
441 "function C1(x) { this.x1 = x; this.x2 = x; }\n"
442 "var a1 = new A1();\n"
443 "var b1_1 = new B1(a1), b1_2 = new B1(a1);\n"
444 "var c1 = new C1(a1);");
445
446 v8::Handle<v8::String> token2 = v8::String::New("token2");
447 v8::Handle<v8::Context> env2 = v8::Context::New();
448 env2->SetSecurityToken(token2);
449 env2->Enter();
450
451 CompileAndRunScript(
452 "function A2() {}\n"
453 "function B2(x) { return function() { return typeof x; }; }\n"
454 "function C2(x) { this.x1 = x; this.x2 = x; this[1] = x; }\n"
455 "var a2 = new A2();\n"
456 "var b2_1 = new B2(a2), b2_2 = new B2(a2);\n"
457 "var c2 = new C2(a2);");
458 const v8::HeapSnapshot* snapshot_env2 =
459 v8::HeapProfiler::TakeSnapshot(v8::String::New("env2"));
460 CHECK_EQ(1, snapshot_env2->GetHead()->GetChildrenCount());
461 const v8::HeapGraphNode* global_env2 =
462 snapshot_env2->GetHead()->GetChild(0)->GetToNode();
463
464 // Verify, that JS global object of env2 doesn't have '..1'
465 // properties, but has '..2' properties.
466 bool has_a1 = false, has_b1_1 = false, has_b1_2 = false, has_c1 = false;
467 bool has_a2 = false, has_b2_1 = false, has_b2_2 = false, has_c2 = false;
468 // This will be needed further.
469 const v8::HeapGraphNode* a2_node = NULL;
470 for (int i = 0, count = global_env2->GetChildrenCount(); i < count; ++i) {
471 const v8::HeapGraphEdge* prop = global_env2->GetChild(i);
472 v8::String::AsciiValue prop_name(prop->GetName());
473 if (strcmp("a1", *prop_name) == 0) has_a1 = true;
474 if (strcmp("b1_1", *prop_name) == 0) has_b1_1 = true;
475 if (strcmp("b1_2", *prop_name) == 0) has_b1_2 = true;
476 if (strcmp("c1", *prop_name) == 0) has_c1 = true;
477 if (strcmp("a2", *prop_name) == 0) {
478 has_a2 = true;
479 a2_node = prop->GetToNode();
480 }
481 if (strcmp("b2_1", *prop_name) == 0) has_b2_1 = true;
482 if (strcmp("b2_2", *prop_name) == 0) has_b2_2 = true;
483 if (strcmp("c2", *prop_name) == 0) has_c2 = true;
484 }
485 CHECK(!has_a1);
486 CHECK(!has_b1_1);
487 CHECK(!has_b1_2);
488 CHECK(!has_c1);
489 CHECK(has_a2);
490 CHECK(has_b2_1);
491 CHECK(has_b2_2);
492 CHECK(has_c2);
493
494 // Verify that anything related to '[ABC]1' is not reachable.
495 NamedEntriesDetector det;
496 i::HeapSnapshot* i_snapshot_env2 =
497 const_cast<i::HeapSnapshot*>(
498 reinterpret_cast<const i::HeapSnapshot*>(snapshot_env2));
499 i_snapshot_env2->IterateEntries(&det);
500 CHECK(!det.has_A1);
501 CHECK(!det.has_B1);
502 CHECK(!det.has_C1);
503 CHECK(det.has_A2);
504 CHECK(det.has_B2);
505 CHECK(det.has_C2);
506
507 // Verify 'a2' object retainers. They are:
508 // - (global object).a2
509 // - c2.x1, c2.x2, c2[1]
510 // - b2_1 and b2_2 closures: via 'x' variable
511 CHECK_EQ(6, a2_node->GetRetainingPathsCount());
512 bool has_global_obj_a2_ref = false;
513 bool has_c2_x1_ref = false, has_c2_x2_ref = false, has_c2_1_ref = false;
514 bool has_b2_1_x_ref = false, has_b2_2_x_ref = false;
515 for (int i = 0; i < a2_node->GetRetainingPathsCount(); ++i) {
516 const v8::HeapGraphPath* path = a2_node->GetRetainingPath(i);
517 const int edges_count = path->GetEdgesCount();
518 CHECK_GT(edges_count, 0);
519 const v8::HeapGraphEdge* last_edge = path->GetEdge(edges_count - 1);
520 v8::String::AsciiValue last_edge_name(last_edge->GetName());
521 if (strcmp("a2", *last_edge_name) == 0
522 && last_edge->GetType() == v8::HeapGraphEdge::PROPERTY) {
523 has_global_obj_a2_ref = true;
524 continue;
525 }
526 CHECK_GT(edges_count, 1);
527 const v8::HeapGraphEdge* prev_edge = path->GetEdge(edges_count - 2);
528 v8::String::AsciiValue prev_edge_name(prev_edge->GetName());
529 if (strcmp("x1", *last_edge_name) == 0
530 && last_edge->GetType() == v8::HeapGraphEdge::PROPERTY
531 && strcmp("c2", *prev_edge_name) == 0) has_c2_x1_ref = true;
532 if (strcmp("x2", *last_edge_name) == 0
533 && last_edge->GetType() == v8::HeapGraphEdge::PROPERTY
534 && strcmp("c2", *prev_edge_name) == 0) has_c2_x2_ref = true;
535 if (strcmp("1", *last_edge_name) == 0
536 && last_edge->GetType() == v8::HeapGraphEdge::ELEMENT
537 && strcmp("c2", *prev_edge_name) == 0) has_c2_1_ref = true;
538 if (strcmp("x", *last_edge_name) == 0
539 && last_edge->GetType() == v8::HeapGraphEdge::CONTEXT_VARIABLE
540 && strcmp("b2_1", *prev_edge_name) == 0) has_b2_1_x_ref = true;
541 if (strcmp("x", *last_edge_name) == 0
542 && last_edge->GetType() == v8::HeapGraphEdge::CONTEXT_VARIABLE
543 && strcmp("b2_2", *prev_edge_name) == 0) has_b2_2_x_ref = true;
544 }
545 CHECK(has_global_obj_a2_ref);
546 CHECK(has_c2_x1_ref);
547 CHECK(has_c2_x2_ref);
548 CHECK(has_c2_1_ref);
549 CHECK(has_b2_1_x_ref);
550 CHECK(has_b2_2_x_ref);
551 }
552
393 #endif // ENABLE_LOGGING_AND_PROFILING 553 #endif // ENABLE_LOGGING_AND_PROFILING
OLDNEW
« no previous file with comments | « src/v8.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698