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

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

Issue 2846012: Heap profiler: add a missing link between a function closure and shared function info. (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/profile-generator.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 "snapshot.h" 9 #include "snapshot.h"
10 #include "string-stream.h" 10 #include "string-stream.h"
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 bool has_A1; 421 bool has_A1;
422 bool has_B1; 422 bool has_B1;
423 bool has_C1; 423 bool has_C1;
424 bool has_A2; 424 bool has_A2;
425 bool has_B2; 425 bool has_B2;
426 bool has_C2; 426 bool has_C2;
427 }; 427 };
428 428
429 } // namespace 429 } // namespace
430 430
431
432 static const v8::HeapGraphNode* GetGlobalObject(
433 const v8::HeapSnapshot* snapshot) {
434 if (i::Snapshot::IsEnabled()) {
435 // In case if snapshots are enabled, there will present a
436 // vanilla deserealized global object, without properties
437 // added by the test code.
438 CHECK_EQ(2, snapshot->GetHead()->GetChildrenCount());
439 // Choose the global object of a bigger size.
440 const v8::HeapGraphNode* node0 =
441 snapshot->GetHead()->GetChild(0)->GetToNode();
442 const v8::HeapGraphNode* node1 =
443 snapshot->GetHead()->GetChild(1)->GetToNode();
444 return node0->GetTotalSize() > node1->GetTotalSize() ? node0 : node1;
445 } else {
446 CHECK_EQ(1, snapshot->GetHead()->GetChildrenCount());
447 return snapshot->GetHead()->GetChild(0)->GetToNode();
448 }
449 }
450
451
452 static const v8::HeapGraphNode* GetProperty(const v8::HeapGraphNode* node,
453 v8::HeapGraphEdge::Type type,
454 const char* name) {
455 for (int i = 0, count = node->GetChildrenCount(); i < count; ++i) {
456 const v8::HeapGraphEdge* prop = node->GetChild(i);
457 v8::String::AsciiValue prop_name(prop->GetName());
458 if (prop->GetType() == type && strcmp(name, *prop_name) == 0)
459 return prop->GetToNode();
460 }
461 return NULL;
462 }
463
464
465 static bool HasString(const v8::HeapGraphNode* node, const char* contents) {
466 for (int i = 0, count = node->GetChildrenCount(); i < count; ++i) {
467 const v8::HeapGraphEdge* prop = node->GetChild(i);
468 const v8::HeapGraphNode* node = prop->GetToNode();
469 if (node->GetType() == v8::HeapGraphNode::STRING) {
470 v8::String::AsciiValue node_name(node->GetName());
471 if (strcmp(contents, *node_name) == 0) return true;
472 }
473 }
474 return false;
475 }
476
477
431 TEST(HeapSnapshot) { 478 TEST(HeapSnapshot) {
432 v8::HandleScope scope; 479 v8::HandleScope scope;
433 480
434 v8::Handle<v8::String> token1 = v8::String::New("token1"); 481 v8::Handle<v8::String> token1 = v8::String::New("token1");
435 v8::Handle<v8::Context> env1 = v8::Context::New(); 482 v8::Handle<v8::Context> env1 = v8::Context::New();
436 env1->SetSecurityToken(token1); 483 env1->SetSecurityToken(token1);
437 env1->Enter(); 484 env1->Enter();
438 485
439 CompileAndRunScript( 486 CompileAndRunScript(
440 "function A1() {}\n" 487 "function A1() {}\n"
(...skipping 10 matching lines...) Expand all
451 498
452 CompileAndRunScript( 499 CompileAndRunScript(
453 "function A2() {}\n" 500 "function A2() {}\n"
454 "function B2(x) { return function() { return typeof x; }; }\n" 501 "function B2(x) { return function() { return typeof x; }; }\n"
455 "function C2(x) { this.x1 = x; this.x2 = x; this[1] = x; }\n" 502 "function C2(x) { this.x1 = x; this.x2 = x; this[1] = x; }\n"
456 "var a2 = new A2();\n" 503 "var a2 = new A2();\n"
457 "var b2_1 = new B2(a2), b2_2 = new B2(a2);\n" 504 "var b2_1 = new B2(a2), b2_2 = new B2(a2);\n"
458 "var c2 = new C2(a2);"); 505 "var c2 = new C2(a2);");
459 const v8::HeapSnapshot* snapshot_env2 = 506 const v8::HeapSnapshot* snapshot_env2 =
460 v8::HeapProfiler::TakeSnapshot(v8::String::New("env2")); 507 v8::HeapProfiler::TakeSnapshot(v8::String::New("env2"));
461 const v8::HeapGraphNode* global_env2; 508 const v8::HeapGraphNode* global_env2 = GetGlobalObject(snapshot_env2);
462 if (i::Snapshot::IsEnabled()) {
463 // In case if snapshots are enabled, there will present a
464 // vanilla deserealized global object, without properties
465 // added by the test code.
466 CHECK_EQ(2, snapshot_env2->GetHead()->GetChildrenCount());
467 // Choose the global object of a bigger size.
468 const v8::HeapGraphNode* node0 =
469 snapshot_env2->GetHead()->GetChild(0)->GetToNode();
470 const v8::HeapGraphNode* node1 =
471 snapshot_env2->GetHead()->GetChild(1)->GetToNode();
472 global_env2 = node0->GetTotalSize() > node1->GetTotalSize() ?
473 node0 : node1;
474 } else {
475 CHECK_EQ(1, snapshot_env2->GetHead()->GetChildrenCount());
476 global_env2 = snapshot_env2->GetHead()->GetChild(0)->GetToNode();
477 }
478 509
479 // Verify, that JS global object of env2 doesn't have '..1' 510 // Verify, that JS global object of env2 doesn't have '..1'
480 // properties, but has '..2' properties. 511 // properties, but has '..2' properties.
481 bool has_a1 = false, has_b1_1 = false, has_b1_2 = false, has_c1 = false; 512 CHECK_EQ(NULL, GetProperty(global_env2, v8::HeapGraphEdge::PROPERTY, "a1"));
482 bool has_a2 = false, has_b2_1 = false, has_b2_2 = false, has_c2 = false; 513 CHECK_EQ(NULL, GetProperty(global_env2, v8::HeapGraphEdge::PROPERTY, "b1_1"));
483 // This will be needed further. 514 CHECK_EQ(NULL, GetProperty(global_env2, v8::HeapGraphEdge::PROPERTY, "b1_2"));
484 const v8::HeapGraphNode* a2_node = NULL; 515 CHECK_EQ(NULL, GetProperty(global_env2, v8::HeapGraphEdge::PROPERTY, "c1"));
485 for (int i = 0, count = global_env2->GetChildrenCount(); i < count; ++i) { 516 const v8::HeapGraphNode* a2_node =
486 const v8::HeapGraphEdge* prop = global_env2->GetChild(i); 517 GetProperty(global_env2, v8::HeapGraphEdge::PROPERTY, "a2");
487 v8::String::AsciiValue prop_name(prop->GetName()); 518 CHECK_NE(NULL, a2_node);
488 if (strcmp("a1", *prop_name) == 0) has_a1 = true; 519 CHECK_NE(NULL, GetProperty(global_env2, v8::HeapGraphEdge::PROPERTY, "b2_1"));
489 if (strcmp("b1_1", *prop_name) == 0) has_b1_1 = true; 520 CHECK_NE(NULL, GetProperty(global_env2, v8::HeapGraphEdge::PROPERTY, "b2_2"));
490 if (strcmp("b1_2", *prop_name) == 0) has_b1_2 = true; 521 CHECK_NE(NULL, GetProperty(global_env2, v8::HeapGraphEdge::PROPERTY, "c2"));
491 if (strcmp("c1", *prop_name) == 0) has_c1 = true;
492 if (strcmp("a2", *prop_name) == 0) {
493 has_a2 = true;
494 a2_node = prop->GetToNode();
495 }
496 if (strcmp("b2_1", *prop_name) == 0) has_b2_1 = true;
497 if (strcmp("b2_2", *prop_name) == 0) has_b2_2 = true;
498 if (strcmp("c2", *prop_name) == 0) has_c2 = true;
499 }
500 CHECK(!has_a1);
501 CHECK(!has_b1_1);
502 CHECK(!has_b1_2);
503 CHECK(!has_c1);
504 CHECK(has_a2);
505 CHECK(has_b2_1);
506 CHECK(has_b2_2);
507 CHECK(has_c2);
508 522
509 // Verify that anything related to '[ABC]1' is not reachable. 523 // Verify that anything related to '[ABC]1' is not reachable.
510 NamedEntriesDetector det; 524 NamedEntriesDetector det;
511 i::HeapSnapshot* i_snapshot_env2 = 525 i::HeapSnapshot* i_snapshot_env2 =
512 const_cast<i::HeapSnapshot*>( 526 const_cast<i::HeapSnapshot*>(
513 reinterpret_cast<const i::HeapSnapshot*>(snapshot_env2)); 527 reinterpret_cast<const i::HeapSnapshot*>(snapshot_env2));
514 i_snapshot_env2->IterateEntries(&det); 528 i_snapshot_env2->IterateEntries(&det);
515 CHECK(!det.has_A1); 529 CHECK(!det.has_A1);
516 CHECK(!det.has_B1); 530 CHECK(!det.has_B1);
517 CHECK(!det.has_C1); 531 CHECK(!det.has_C1);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
558 && strcmp("b2_2", *prev_edge_name) == 0) has_b2_2_x_ref = true; 572 && strcmp("b2_2", *prev_edge_name) == 0) has_b2_2_x_ref = true;
559 } 573 }
560 CHECK(has_global_obj_a2_ref); 574 CHECK(has_global_obj_a2_ref);
561 CHECK(has_c2_x1_ref); 575 CHECK(has_c2_x1_ref);
562 CHECK(has_c2_x2_ref); 576 CHECK(has_c2_x2_ref);
563 CHECK(has_c2_1_ref); 577 CHECK(has_c2_1_ref);
564 CHECK(has_b2_1_x_ref); 578 CHECK(has_b2_1_x_ref);
565 CHECK(has_b2_2_x_ref); 579 CHECK(has_b2_2_x_ref);
566 } 580 }
567 581
582
583 TEST(HeapSnapshotCodeObjects) {
584 v8::HandleScope scope;
585 v8::Handle<v8::Context> env = v8::Context::New();
586 env->Enter();
587
588 CompileAndRunScript(
589 "function lazy(x) { return x - 1; }\n"
590 "function compiled(x) { return x + 1; }\n"
591 "compiled(1)");
592 const v8::HeapSnapshot* snapshot =
593 v8::HeapProfiler::TakeSnapshot(v8::String::New("code"));
594
595 const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
596 const v8::HeapGraphNode* compiled =
597 GetProperty(global, v8::HeapGraphEdge::PROPERTY, "compiled");
598 CHECK_NE(NULL, compiled);
599 CHECK_EQ(v8::HeapGraphNode::CLOSURE, compiled->GetType());
600 const v8::HeapGraphNode* lazy =
601 GetProperty(global, v8::HeapGraphEdge::PROPERTY, "lazy");
602 CHECK_NE(NULL, lazy);
603 CHECK_EQ(v8::HeapGraphNode::CLOSURE, lazy->GetType());
604
605 // Find references to code.
606 const v8::HeapGraphNode* compiled_code =
607 GetProperty(compiled, v8::HeapGraphEdge::INTERNAL, "code");
608 CHECK_NE(NULL, compiled_code);
609 const v8::HeapGraphNode* lazy_code =
610 GetProperty(lazy, v8::HeapGraphEdge::INTERNAL, "code");
611 CHECK_NE(NULL, lazy_code);
612
613 // Verify that non-compiled code doesn't contain references to "x"
614 // literal, while compiled code does.
615 bool compiled_references_x = false, lazy_references_x = false;
616 for (int i = 0, count = compiled_code->GetChildrenCount(); i < count; ++i) {
617 const v8::HeapGraphEdge* prop = compiled_code->GetChild(i);
618 const v8::HeapGraphNode* node = prop->GetToNode();
619 if (node->GetType() == v8::HeapGraphNode::CODE) {
620 if (HasString(node, "x")) {
621 compiled_references_x = true;
622 break;
623 }
624 }
625 }
626 for (int i = 0, count = lazy_code->GetChildrenCount(); i < count; ++i) {
627 const v8::HeapGraphEdge* prop = lazy_code->GetChild(i);
628 const v8::HeapGraphNode* node = prop->GetToNode();
629 if (node->GetType() == v8::HeapGraphNode::CODE) {
630 if (HasString(node, "x")) {
631 lazy_references_x = true;
632 break;
633 }
634 }
635 }
636 CHECK(compiled_references_x);
637 CHECK(!lazy_references_x);
638 }
639
568 #endif // ENABLE_LOGGING_AND_PROFILING 640 #endif // ENABLE_LOGGING_AND_PROFILING
OLDNEW
« no previous file with comments | « src/profile-generator.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698