16ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// Copyright 2010 the V8 project authors. All rights reserved.
26ded16be15dd865a9b21ea304d5273c8be299c87Steve Block//
36ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// Tests of profiles generator and utilities.
46ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
56ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#include "v8.h"
66ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#include "profile-generator-inl.h"
76ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#include "cctest.h"
87f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#include "../include/v8-profiler.h"
96ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
106ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockusing i::CodeEntry;
116ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockusing i::CodeMap;
126ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockusing i::CpuProfile;
137f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochusing i::CpuProfiler;
146ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockusing i::CpuProfilesCollection;
156ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockusing i::ProfileNode;
166ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockusing i::ProfileTree;
176ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockusing i::ProfileGenerator;
186ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockusing i::SampleRateCalculator;
196ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockusing i::TickSample;
20f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkeusing i::TokenEnumerator;
216ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockusing i::Vector;
226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
24f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkenamespace v8 {
25f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkenamespace internal {
26f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
27f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkeclass TokenEnumeratorTester {
28f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke public:
29f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  static i::List<bool>* token_removed(TokenEnumerator* te) {
30f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    return &te->token_removed_;
31f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  }
32f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke};
33f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
34f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke} }  // namespace v8::internal
35f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
36f7060e27768c550ace7ec48ad8c093466db52dfaLeon ClarkeTEST(TokenEnumerator) {
37f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  TokenEnumerator te;
387f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  CHECK_EQ(TokenEnumerator::kNoSecurityToken, te.GetTokenId(NULL));
39f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  v8::HandleScope hs;
40589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  v8::Local<v8::String> token1(v8::String::New("1x"));
41f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  CHECK_EQ(0, te.GetTokenId(*v8::Utils::OpenHandle(*token1)));
42f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  CHECK_EQ(0, te.GetTokenId(*v8::Utils::OpenHandle(*token1)));
43589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  v8::Local<v8::String> token2(v8::String::New("2x"));
44f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  CHECK_EQ(1, te.GetTokenId(*v8::Utils::OpenHandle(*token2)));
45f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  CHECK_EQ(1, te.GetTokenId(*v8::Utils::OpenHandle(*token2)));
46f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  CHECK_EQ(0, te.GetTokenId(*v8::Utils::OpenHandle(*token1)));
47f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  {
48f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    v8::HandleScope hs;
49589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    v8::Local<v8::String> token3(v8::String::New("3x"));
50f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    CHECK_EQ(2, te.GetTokenId(*v8::Utils::OpenHandle(*token3)));
51f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    CHECK_EQ(1, te.GetTokenId(*v8::Utils::OpenHandle(*token2)));
52f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    CHECK_EQ(0, te.GetTokenId(*v8::Utils::OpenHandle(*token1)));
53f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  }
54f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  CHECK(!i::TokenEnumeratorTester::token_removed(&te)->at(2));
553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
56f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  CHECK(i::TokenEnumeratorTester::token_removed(&te)->at(2));
57f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  CHECK_EQ(1, te.GetTokenId(*v8::Utils::OpenHandle(*token2)));
58f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  CHECK_EQ(0, te.GetTokenId(*v8::Utils::OpenHandle(*token1)));
59f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke}
60f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
61f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
626ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockTEST(ProfileNodeFindOrAddChild) {
636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ProfileNode node(NULL, NULL);
647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa", "", 0,
657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch                   TokenEnumerator::kNoSecurityToken);
666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ProfileNode* childNode1 = node.FindOrAddChild(&entry1);
676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_NE(NULL, childNode1);
686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(childNode1, node.FindOrAddChild(&entry1));
697f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb", "", 0,
707f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch                   TokenEnumerator::kNoSecurityToken);
716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ProfileNode* childNode2 = node.FindOrAddChild(&entry2);
726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_NE(NULL, childNode2);
736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_NE(childNode1, childNode2);
746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(childNode1, node.FindOrAddChild(&entry1));
756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(childNode2, node.FindOrAddChild(&entry2));
767f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc", "", 0,
777f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch                   TokenEnumerator::kNoSecurityToken);
786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ProfileNode* childNode3 = node.FindOrAddChild(&entry3);
796ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_NE(NULL, childNode3);
806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_NE(childNode1, childNode3);
816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_NE(childNode2, childNode3);
826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(childNode1, node.FindOrAddChild(&entry1));
836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(childNode2, node.FindOrAddChild(&entry2));
846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(childNode3, node.FindOrAddChild(&entry3));
856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
880d5e116f6aee03185f237311a943491bb079a768Kristian MonsenTEST(ProfileNodeFindOrAddChildForSameFunction) {
890d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  const char* empty = "";
900d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  const char* aaa = "aaa";
910d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  ProfileNode node(NULL, NULL);
920d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  CodeEntry entry1(i::Logger::FUNCTION_TAG, empty, aaa, empty, 0,
930d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                     TokenEnumerator::kNoSecurityToken);
940d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  ProfileNode* childNode1 = node.FindOrAddChild(&entry1);
950d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  CHECK_NE(NULL, childNode1);
960d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  CHECK_EQ(childNode1, node.FindOrAddChild(&entry1));
970d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // The same function again.
980d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  CodeEntry entry2(i::Logger::FUNCTION_TAG, empty, aaa, empty, 0,
990d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                   TokenEnumerator::kNoSecurityToken);
1000d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  CHECK_EQ(childNode1, node.FindOrAddChild(&entry2));
1010d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // Now with a different security token.
1020d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  CodeEntry entry3(i::Logger::FUNCTION_TAG, empty, aaa, empty, 0,
1030d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                   TokenEnumerator::kNoSecurityToken + 1);
1040d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  CHECK_EQ(childNode1, node.FindOrAddChild(&entry3));
1050d5e116f6aee03185f237311a943491bb079a768Kristian Monsen}
1060d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
1070d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
1086ded16be15dd865a9b21ea304d5273c8be299c87Steve Blocknamespace {
1096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1106ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass ProfileTreeTestHelper {
1116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public:
1126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  explicit ProfileTreeTestHelper(const ProfileTree* tree)
1136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      : tree_(tree) { }
1146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ProfileNode* Walk(CodeEntry* entry1,
1166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                    CodeEntry* entry2 = NULL,
1176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                    CodeEntry* entry3 = NULL) {
1186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    ProfileNode* node = tree_->root();
1196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    node = node->FindChild(entry1);
1206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    if (node == NULL) return NULL;
1216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    if (entry2 != NULL) {
1226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      node = node->FindChild(entry2);
1236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      if (node == NULL) return NULL;
1246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    }
1256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    if (entry3 != NULL) {
1266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      node = node->FindChild(entry3);
1276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    }
1286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return node;
1296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
1306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private:
1326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  const ProfileTree* tree_;
1336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block};
1346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1356ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}  // namespace
1366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1376ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockTEST(ProfileTreeAddPathFromStart) {
1387f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa", "", 0,
1397f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch                   TokenEnumerator::kNoSecurityToken);
1407f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb", "", 0,
1417f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch                   TokenEnumerator::kNoSecurityToken);
1427f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc", "", 0,
1437f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch                   TokenEnumerator::kNoSecurityToken);
1446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ProfileTree tree;
1456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ProfileTreeTestHelper helper(&tree);
1466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(NULL, helper.Walk(&entry1));
1476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(NULL, helper.Walk(&entry2));
1486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(NULL, helper.Walk(&entry3));
1496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CodeEntry* path[] = {NULL, &entry1, NULL, &entry2, NULL, NULL, &entry3, NULL};
1516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Vector<CodeEntry*> path_vec(path, sizeof(path) / sizeof(path[0]));
1526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  tree.AddPathFromStart(path_vec);
1536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(NULL, helper.Walk(&entry2));
1546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(NULL, helper.Walk(&entry3));
1556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ProfileNode* node1 = helper.Walk(&entry1);
1566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_NE(NULL, node1);
1576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(0, node1->total_ticks());
1586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(0, node1->self_ticks());
1596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(NULL, helper.Walk(&entry1, &entry1));
1606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(NULL, helper.Walk(&entry1, &entry3));
1616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ProfileNode* node2 = helper.Walk(&entry1, &entry2);
1626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_NE(NULL, node2);
1636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_NE(node1, node2);
1646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(0, node2->total_ticks());
1656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(0, node2->self_ticks());
1666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(NULL, helper.Walk(&entry1, &entry2, &entry1));
1676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(NULL, helper.Walk(&entry1, &entry2, &entry2));
1686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ProfileNode* node3 = helper.Walk(&entry1, &entry2, &entry3);
1696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_NE(NULL, node3);
1706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_NE(node1, node3);
1716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_NE(node2, node3);
1726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(0, node3->total_ticks());
1736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(1, node3->self_ticks());
1746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  tree.AddPathFromStart(path_vec);
1766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(node1, helper.Walk(&entry1));
1776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(node2, helper.Walk(&entry1, &entry2));
1786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(node3, helper.Walk(&entry1, &entry2, &entry3));
1796ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(0, node1->total_ticks());
1806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(0, node1->self_ticks());
1816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(0, node2->total_ticks());
1826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(0, node2->self_ticks());
1836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(0, node3->total_ticks());
1846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(2, node3->self_ticks());
1856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CodeEntry* path2[] = {&entry1, &entry2, &entry2};
1876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Vector<CodeEntry*> path2_vec(path2, sizeof(path2) / sizeof(path2[0]));
1886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  tree.AddPathFromStart(path2_vec);
1896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(NULL, helper.Walk(&entry2));
1906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(NULL, helper.Walk(&entry3));
1916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(node1, helper.Walk(&entry1));
1926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(NULL, helper.Walk(&entry1, &entry1));
1936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(NULL, helper.Walk(&entry1, &entry3));
1946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(node2, helper.Walk(&entry1, &entry2));
1956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(NULL, helper.Walk(&entry1, &entry2, &entry1));
1966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(node3, helper.Walk(&entry1, &entry2, &entry3));
1976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(0, node3->total_ticks());
1986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(2, node3->self_ticks());
1996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ProfileNode* node4 = helper.Walk(&entry1, &entry2, &entry2);
2006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_NE(NULL, node4);
2016ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_NE(node3, node4);
2026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(0, node4->total_ticks());
2036ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(1, node4->self_ticks());
2046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
2056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
2066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
2076ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockTEST(ProfileTreeAddPathFromEnd) {
2087f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa", "", 0,
2097f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch                   TokenEnumerator::kNoSecurityToken);
2107f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb", "", 0,
2117f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch                   TokenEnumerator::kNoSecurityToken);
2127f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc", "", 0,
2137f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch                   TokenEnumerator::kNoSecurityToken);
2146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ProfileTree tree;
2156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ProfileTreeTestHelper helper(&tree);
2166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(NULL, helper.Walk(&entry1));
2176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(NULL, helper.Walk(&entry2));
2186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(NULL, helper.Walk(&entry3));
2196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
2206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CodeEntry* path[] = {NULL, &entry3, NULL, &entry2, NULL, NULL, &entry1, NULL};
2216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Vector<CodeEntry*> path_vec(path, sizeof(path) / sizeof(path[0]));
2226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  tree.AddPathFromEnd(path_vec);
2236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(NULL, helper.Walk(&entry2));
2246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(NULL, helper.Walk(&entry3));
2256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ProfileNode* node1 = helper.Walk(&entry1);
2266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_NE(NULL, node1);
2276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(0, node1->total_ticks());
2286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(0, node1->self_ticks());
2296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(NULL, helper.Walk(&entry1, &entry1));
2306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(NULL, helper.Walk(&entry1, &entry3));
2316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ProfileNode* node2 = helper.Walk(&entry1, &entry2);
2326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_NE(NULL, node2);
2336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_NE(node1, node2);
2346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(0, node2->total_ticks());
2356ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(0, node2->self_ticks());
2366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(NULL, helper.Walk(&entry1, &entry2, &entry1));
2376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(NULL, helper.Walk(&entry1, &entry2, &entry2));
2386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ProfileNode* node3 = helper.Walk(&entry1, &entry2, &entry3);
2396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_NE(NULL, node3);
2406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_NE(node1, node3);
2416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_NE(node2, node3);
2426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(0, node3->total_ticks());
2436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(1, node3->self_ticks());
2446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
2456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  tree.AddPathFromEnd(path_vec);
2466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(node1, helper.Walk(&entry1));
2476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(node2, helper.Walk(&entry1, &entry2));
2486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(node3, helper.Walk(&entry1, &entry2, &entry3));
2496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(0, node1->total_ticks());
2506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(0, node1->self_ticks());
2516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(0, node2->total_ticks());
2526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(0, node2->self_ticks());
2536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(0, node3->total_ticks());
2546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(2, node3->self_ticks());
2556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
2566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CodeEntry* path2[] = {&entry2, &entry2, &entry1};
2576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Vector<CodeEntry*> path2_vec(path2, sizeof(path2) / sizeof(path2[0]));
2586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  tree.AddPathFromEnd(path2_vec);
2596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(NULL, helper.Walk(&entry2));
2606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(NULL, helper.Walk(&entry3));
2616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(node1, helper.Walk(&entry1));
2626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(NULL, helper.Walk(&entry1, &entry1));
2636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(NULL, helper.Walk(&entry1, &entry3));
2646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(node2, helper.Walk(&entry1, &entry2));
2656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(NULL, helper.Walk(&entry1, &entry2, &entry1));
2666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(node3, helper.Walk(&entry1, &entry2, &entry3));
2676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(0, node3->total_ticks());
2686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(2, node3->self_ticks());
2696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ProfileNode* node4 = helper.Walk(&entry1, &entry2, &entry2);
2706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_NE(NULL, node4);
2716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_NE(node3, node4);
2726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(0, node4->total_ticks());
2736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(1, node4->self_ticks());
2746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
2756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
2766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
2776ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockTEST(ProfileTreeCalculateTotalTicks) {
2786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ProfileTree empty_tree;
2796ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(0, empty_tree.root()->total_ticks());
2806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(0, empty_tree.root()->self_ticks());
2816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  empty_tree.CalculateTotalTicks();
2826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(0, empty_tree.root()->total_ticks());
2836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(0, empty_tree.root()->self_ticks());
2846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  empty_tree.root()->IncrementSelfTicks();
2856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(0, empty_tree.root()->total_ticks());
2866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(1, empty_tree.root()->self_ticks());
2876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  empty_tree.CalculateTotalTicks();
2886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(1, empty_tree.root()->total_ticks());
2896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(1, empty_tree.root()->self_ticks());
2906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
2917f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa", "", 0,
2927f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch                   TokenEnumerator::kNoSecurityToken);
2936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CodeEntry* e1_path[] = {&entry1};
2946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Vector<CodeEntry*> e1_path_vec(
2956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      e1_path, sizeof(e1_path) / sizeof(e1_path[0]));
296f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
297f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  ProfileTree single_child_tree;
298f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  single_child_tree.AddPathFromStart(e1_path_vec);
299f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  single_child_tree.root()->IncrementSelfTicks();
300f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  CHECK_EQ(0, single_child_tree.root()->total_ticks());
301f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  CHECK_EQ(1, single_child_tree.root()->self_ticks());
302f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  ProfileTreeTestHelper single_child_helper(&single_child_tree);
303f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  ProfileNode* node1 = single_child_helper.Walk(&entry1);
304f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  CHECK_NE(NULL, node1);
305f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  CHECK_EQ(0, node1->total_ticks());
306f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  CHECK_EQ(1, node1->self_ticks());
307f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  single_child_tree.CalculateTotalTicks();
308f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  CHECK_EQ(2, single_child_tree.root()->total_ticks());
309f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  CHECK_EQ(1, single_child_tree.root()->self_ticks());
310f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  CHECK_EQ(1, node1->total_ticks());
311f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  CHECK_EQ(1, node1->self_ticks());
312f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
3137f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb", "", 0,
3147f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch                   TokenEnumerator::kNoSecurityToken);
3156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CodeEntry* e1_e2_path[] = {&entry1, &entry2};
3166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Vector<CodeEntry*> e1_e2_path_vec(
3176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      e1_e2_path, sizeof(e1_e2_path) / sizeof(e1_e2_path[0]));
3186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
3196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ProfileTree flat_tree;
3206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ProfileTreeTestHelper flat_helper(&flat_tree);
3216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  flat_tree.AddPathFromStart(e1_path_vec);
3226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  flat_tree.AddPathFromStart(e1_path_vec);
3236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  flat_tree.AddPathFromStart(e1_e2_path_vec);
3246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  flat_tree.AddPathFromStart(e1_e2_path_vec);
3256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  flat_tree.AddPathFromStart(e1_e2_path_vec);
3266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Results in {root,0,0} -> {entry1,0,2} -> {entry2,0,3}
3276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(0, flat_tree.root()->total_ticks());
3286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(0, flat_tree.root()->self_ticks());
329f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  node1 = flat_helper.Walk(&entry1);
3306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_NE(NULL, node1);
3316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(0, node1->total_ticks());
3326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(2, node1->self_ticks());
3336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ProfileNode* node2 = flat_helper.Walk(&entry1, &entry2);
3346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_NE(NULL, node2);
3356ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(0, node2->total_ticks());
3366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(3, node2->self_ticks());
3376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  flat_tree.CalculateTotalTicks();
3386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Must calculate {root,5,0} -> {entry1,5,2} -> {entry2,3,3}
3396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(5, flat_tree.root()->total_ticks());
3406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(0, flat_tree.root()->self_ticks());
3416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(5, node1->total_ticks());
3426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(2, node1->self_ticks());
3436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(3, node2->total_ticks());
3446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(3, node2->self_ticks());
3456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
3466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CodeEntry* e2_path[] = {&entry2};
3476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Vector<CodeEntry*> e2_path_vec(
3486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      e2_path, sizeof(e2_path) / sizeof(e2_path[0]));
3497f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc", "", 0,
3507f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch                   TokenEnumerator::kNoSecurityToken);
3516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CodeEntry* e3_path[] = {&entry3};
3526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Vector<CodeEntry*> e3_path_vec(
3536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      e3_path, sizeof(e3_path) / sizeof(e3_path[0]));
3546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
3556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ProfileTree wide_tree;
3566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ProfileTreeTestHelper wide_helper(&wide_tree);
3576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  wide_tree.AddPathFromStart(e1_path_vec);
3586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  wide_tree.AddPathFromStart(e1_path_vec);
3596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  wide_tree.AddPathFromStart(e1_e2_path_vec);
3606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  wide_tree.AddPathFromStart(e2_path_vec);
3616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  wide_tree.AddPathFromStart(e2_path_vec);
3626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  wide_tree.AddPathFromStart(e2_path_vec);
3636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  wide_tree.AddPathFromStart(e3_path_vec);
3646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  wide_tree.AddPathFromStart(e3_path_vec);
3656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  wide_tree.AddPathFromStart(e3_path_vec);
3666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  wide_tree.AddPathFromStart(e3_path_vec);
3676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Results in            -> {entry1,0,2} -> {entry2,0,1}
3686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  //            {root,0,0} -> {entry2,0,3}
3696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  //                       -> {entry3,0,4}
3706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(0, wide_tree.root()->total_ticks());
3716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(0, wide_tree.root()->self_ticks());
3726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  node1 = wide_helper.Walk(&entry1);
3736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_NE(NULL, node1);
3746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(0, node1->total_ticks());
3756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(2, node1->self_ticks());
3766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ProfileNode* node1_2 = wide_helper.Walk(&entry1, &entry2);
3776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_NE(NULL, node1_2);
3786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(0, node1_2->total_ticks());
3796ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(1, node1_2->self_ticks());
3806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  node2 = wide_helper.Walk(&entry2);
3816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_NE(NULL, node2);
3826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(0, node2->total_ticks());
3836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(3, node2->self_ticks());
3846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ProfileNode* node3 = wide_helper.Walk(&entry3);
3856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_NE(NULL, node3);
3866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(0, node3->total_ticks());
3876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(4, node3->self_ticks());
3886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  wide_tree.CalculateTotalTicks();
3896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Calculates             -> {entry1,3,2} -> {entry2,1,1}
3906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  //            {root,10,0} -> {entry2,3,3}
3916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  //                        -> {entry3,4,4}
3926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(10, wide_tree.root()->total_ticks());
3936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(0, wide_tree.root()->self_ticks());
3946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(3, node1->total_ticks());
3956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(2, node1->self_ticks());
3966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(1, node1_2->total_ticks());
3976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(1, node1_2->self_ticks());
3986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(3, node2->total_ticks());
3996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(3, node2->self_ticks());
4006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(4, node3->total_ticks());
4016ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(4, node3->self_ticks());
4026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
4036ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
4046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
405f7060e27768c550ace7ec48ad8c093466db52dfaLeon ClarkeTEST(ProfileTreeFilteredClone) {
406f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  ProfileTree source_tree;
407f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  const int token0 = 0, token1 = 1, token2 = 2;
408f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa", "", 0, token0);
409f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb", "", 0, token1);
410f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc", "", 0, token0);
411f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  CodeEntry entry4(
412f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke      i::Logger::FUNCTION_TAG, "", "ddd", "", 0,
4137f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      TokenEnumerator::kInheritsSecurityToken);
414f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
415f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  {
416f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    CodeEntry* e1_e2_path[] = {&entry1, &entry2};
417f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    Vector<CodeEntry*> e1_e2_path_vec(
418f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke        e1_e2_path, sizeof(e1_e2_path) / sizeof(e1_e2_path[0]));
419f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    source_tree.AddPathFromStart(e1_e2_path_vec);
420f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    CodeEntry* e2_e4_path[] = {&entry2, &entry4};
421f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    Vector<CodeEntry*> e2_e4_path_vec(
422f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke        e2_e4_path, sizeof(e2_e4_path) / sizeof(e2_e4_path[0]));
423f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    source_tree.AddPathFromStart(e2_e4_path_vec);
424f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    CodeEntry* e3_e1_path[] = {&entry3, &entry1};
425f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    Vector<CodeEntry*> e3_e1_path_vec(
426f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke        e3_e1_path, sizeof(e3_e1_path) / sizeof(e3_e1_path[0]));
427f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    source_tree.AddPathFromStart(e3_e1_path_vec);
428f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    CodeEntry* e3_e2_path[] = {&entry3, &entry2};
429f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    Vector<CodeEntry*> e3_e2_path_vec(
430f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke        e3_e2_path, sizeof(e3_e2_path) / sizeof(e3_e2_path[0]));
431f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    source_tree.AddPathFromStart(e3_e2_path_vec);
432f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    source_tree.CalculateTotalTicks();
433f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    // Results in               -> {entry1,0,1,0} -> {entry2,1,1,1}
434f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    //            {root,0,4,-1} -> {entry2,0,1,1} -> {entry4,1,1,inherits}
435f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    //                          -> {entry3,0,2,0} -> {entry1,1,1,0}
436f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    //                                            -> {entry2,1,1,1}
437f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    CHECK_EQ(4, source_tree.root()->total_ticks());
438f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    CHECK_EQ(0, source_tree.root()->self_ticks());
439f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  }
440f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
441f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  {
442f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    ProfileTree token0_tree;
443f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    token0_tree.FilteredClone(&source_tree, token0);
444f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    // Should be                -> {entry1,1,1,0}
445f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    //            {root,1,4,-1} -> {entry3,1,2,0} -> {entry1,1,1,0}
446f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    // [self ticks from filtered nodes are attributed to their parents]
447f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    CHECK_EQ(4, token0_tree.root()->total_ticks());
448f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    CHECK_EQ(1, token0_tree.root()->self_ticks());
449f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    ProfileTreeTestHelper token0_helper(&token0_tree);
450f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    ProfileNode* node1 = token0_helper.Walk(&entry1);
451f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    CHECK_NE(NULL, node1);
452f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    CHECK_EQ(1, node1->total_ticks());
453f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    CHECK_EQ(1, node1->self_ticks());
454f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    CHECK_EQ(NULL, token0_helper.Walk(&entry2));
455f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    ProfileNode* node3 = token0_helper.Walk(&entry3);
456f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    CHECK_NE(NULL, node3);
457f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    CHECK_EQ(2, node3->total_ticks());
458f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    CHECK_EQ(1, node3->self_ticks());
459f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    ProfileNode* node3_1 = token0_helper.Walk(&entry3, &entry1);
460f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    CHECK_NE(NULL, node3_1);
461f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    CHECK_EQ(1, node3_1->total_ticks());
462f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    CHECK_EQ(1, node3_1->self_ticks());
463f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    CHECK_EQ(NULL, token0_helper.Walk(&entry3, &entry2));
464f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  }
465f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
466f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  {
467f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    ProfileTree token1_tree;
468f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    token1_tree.FilteredClone(&source_tree, token1);
469f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    // Should be
470f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    //            {root,1,4,-1} -> {entry2,2,3,1} -> {entry4,1,1,inherits}
471f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    // [child nodes referring to the same entry get merged and
472f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    //  their self times summed up]
473f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    CHECK_EQ(4, token1_tree.root()->total_ticks());
474f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    CHECK_EQ(1, token1_tree.root()->self_ticks());
475f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    ProfileTreeTestHelper token1_helper(&token1_tree);
476f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    CHECK_EQ(NULL, token1_helper.Walk(&entry1));
477f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    CHECK_EQ(NULL, token1_helper.Walk(&entry3));
478f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    ProfileNode* node2 = token1_helper.Walk(&entry2);
479f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    CHECK_NE(NULL, node2);
480f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    CHECK_EQ(3, node2->total_ticks());
481f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    CHECK_EQ(2, node2->self_ticks());
482f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    ProfileNode* node2_4 = token1_helper.Walk(&entry2, &entry4);
483f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    CHECK_NE(NULL, node2_4);
484f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    CHECK_EQ(1, node2_4->total_ticks());
485f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    CHECK_EQ(1, node2_4->self_ticks());
486f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  }
487f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
488f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  {
489f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    ProfileTree token2_tree;
490f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    token2_tree.FilteredClone(&source_tree, token2);
491f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    // Should be
492f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    //            {root,4,4,-1}
493f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    // [no nodes, all ticks get migrated into root node]
494f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    CHECK_EQ(4, token2_tree.root()->total_ticks());
495f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    CHECK_EQ(4, token2_tree.root()->self_ticks());
496f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    ProfileTreeTestHelper token2_helper(&token2_tree);
497f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    CHECK_EQ(NULL, token2_helper.Walk(&entry1));
498f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    CHECK_EQ(NULL, token2_helper.Walk(&entry2));
499f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    CHECK_EQ(NULL, token2_helper.Walk(&entry3));
500f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  }
501f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke}
502f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
503f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
5046ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockstatic inline i::Address ToAddress(int n) {
5056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  return reinterpret_cast<i::Address>(n);
5066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
5076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
5086ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockTEST(CodeMapAddCode) {
5096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CodeMap code_map;
5107f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa", "", 0,
5117f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch                   TokenEnumerator::kNoSecurityToken);
5127f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb", "", 0,
5137f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch                   TokenEnumerator::kNoSecurityToken);
5147f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc", "", 0,
5157f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch                   TokenEnumerator::kNoSecurityToken);
5167f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  CodeEntry entry4(i::Logger::FUNCTION_TAG, "", "ddd", "", 0,
5177f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch                   TokenEnumerator::kNoSecurityToken);
5186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  code_map.AddCode(ToAddress(0x1500), &entry1, 0x200);
5196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  code_map.AddCode(ToAddress(0x1700), &entry2, 0x100);
5206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  code_map.AddCode(ToAddress(0x1900), &entry3, 0x50);
5216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  code_map.AddCode(ToAddress(0x1950), &entry4, 0x10);
5226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(NULL, code_map.FindEntry(0));
5236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1500 - 1)));
5246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1500)));
5256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1500 + 0x100)));
5266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1500 + 0x200 - 1)));
5276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(&entry2, code_map.FindEntry(ToAddress(0x1700)));
5286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(&entry2, code_map.FindEntry(ToAddress(0x1700 + 0x50)));
5296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(&entry2, code_map.FindEntry(ToAddress(0x1700 + 0x100 - 1)));
5306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1700 + 0x100)));
5316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1900 - 1)));
5326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(&entry3, code_map.FindEntry(ToAddress(0x1900)));
5336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(&entry3, code_map.FindEntry(ToAddress(0x1900 + 0x28)));
5346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(&entry4, code_map.FindEntry(ToAddress(0x1950)));
5356ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(&entry4, code_map.FindEntry(ToAddress(0x1950 + 0x7)));
5366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(&entry4, code_map.FindEntry(ToAddress(0x1950 + 0x10 - 1)));
5376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1950 + 0x10)));
5386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0xFFFFFFFF)));
5396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
5406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
5416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
5426ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockTEST(CodeMapMoveAndDeleteCode) {
5436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CodeMap code_map;
5447f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa", "", 0,
5457f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch                   TokenEnumerator::kNoSecurityToken);
5467f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb", "", 0,
5477f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch                   TokenEnumerator::kNoSecurityToken);
5486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  code_map.AddCode(ToAddress(0x1500), &entry1, 0x200);
5496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  code_map.AddCode(ToAddress(0x1700), &entry2, 0x100);
5506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1500)));
5516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(&entry2, code_map.FindEntry(ToAddress(0x1700)));
552589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  code_map.MoveCode(ToAddress(0x1500), ToAddress(0x1700));  // Deprecate bbb.
5536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1500)));
554589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1700)));
555589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc", "", 0,
556589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                   TokenEnumerator::kNoSecurityToken);
557589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  code_map.AddCode(ToAddress(0x1750), &entry3, 0x100);
5586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1700)));
559589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  CHECK_EQ(&entry3, code_map.FindEntry(ToAddress(0x1750)));
5606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
5616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
5626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
5636ded16be15dd865a9b21ea304d5273c8be299c87Steve Blocknamespace {
5646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
5656ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass TestSetup {
5666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public:
5676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  TestSetup()
5686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      : old_flag_prof_browser_mode_(i::FLAG_prof_browser_mode) {
5696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    i::FLAG_prof_browser_mode = false;
5706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
5716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
5726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ~TestSetup() {
5736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    i::FLAG_prof_browser_mode = old_flag_prof_browser_mode_;
5746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
5756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
5766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private:
5776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  bool old_flag_prof_browser_mode_;
5786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block};
5796ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
5806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}  // namespace
5816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
5826ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockTEST(RecordTickSample) {
5836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  TestSetup test_setup;
5846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CpuProfilesCollection profiles;
5856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  profiles.StartProfiling("", 1);
5866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ProfileGenerator generator(&profiles);
5876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CodeEntry* entry1 = generator.NewCodeEntry(i::Logger::FUNCTION_TAG, "aaa");
5886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CodeEntry* entry2 = generator.NewCodeEntry(i::Logger::FUNCTION_TAG, "bbb");
5896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CodeEntry* entry3 = generator.NewCodeEntry(i::Logger::FUNCTION_TAG, "ccc");
5906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  generator.code_map()->AddCode(ToAddress(0x1500), entry1, 0x200);
5916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  generator.code_map()->AddCode(ToAddress(0x1700), entry2, 0x100);
5926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  generator.code_map()->AddCode(ToAddress(0x1900), entry3, 0x50);
5936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
5946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // We are building the following calls tree:
5956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  //      -> aaa         - sample1
5966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  //  aaa -> bbb -> ccc  - sample2
5976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  //      -> ccc -> aaa  - sample3
5986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  TickSample sample1;
5996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  sample1.pc = ToAddress(0x1600);
600e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  sample1.tos = ToAddress(0x1500);
6016ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  sample1.stack[0] = ToAddress(0x1510);
6026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  sample1.frames_count = 1;
6036ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  generator.RecordTickSample(sample1);
6046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  TickSample sample2;
6056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  sample2.pc = ToAddress(0x1925);
606e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  sample2.tos = ToAddress(0x1900);
6076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  sample2.stack[0] = ToAddress(0x1780);
6086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  sample2.stack[1] = ToAddress(0x10000);  // non-existent.
6096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  sample2.stack[2] = ToAddress(0x1620);
6106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  sample2.frames_count = 3;
6116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  generator.RecordTickSample(sample2);
6126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  TickSample sample3;
6136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  sample3.pc = ToAddress(0x1510);
614e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  sample3.tos = ToAddress(0x1500);
6156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  sample3.stack[0] = ToAddress(0x1910);
6166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  sample3.stack[1] = ToAddress(0x1610);
6176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  sample3.frames_count = 2;
6186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  generator.RecordTickSample(sample3);
6196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
620f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  CpuProfile* profile =
6217f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      profiles.StopProfiling(TokenEnumerator::kNoSecurityToken, "", 1);
6226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_NE(NULL, profile);
6236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ProfileTreeTestHelper top_down_test_helper(profile->top_down());
6246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(NULL, top_down_test_helper.Walk(entry2));
6256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(NULL, top_down_test_helper.Walk(entry3));
6266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ProfileNode* node1 = top_down_test_helper.Walk(entry1);
6276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_NE(NULL, node1);
6286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(entry1, node1->entry());
6296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ProfileNode* node2 = top_down_test_helper.Walk(entry1, entry1);
6306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_NE(NULL, node2);
6316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(entry1, node2->entry());
6326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ProfileNode* node3 = top_down_test_helper.Walk(entry1, entry2, entry3);
6336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_NE(NULL, node3);
6346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(entry3, node3->entry());
6356ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ProfileNode* node4 = top_down_test_helper.Walk(entry1, entry3, entry1);
6366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_NE(NULL, node4);
6376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(entry1, node4->entry());
6386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
6396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
6406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
6416ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockTEST(SampleRateCalculator) {
6426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  const double kSamplingIntervalMs = i::Logger::kSamplingIntervalMs;
6436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
6446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Verify that ticking exactly in query intervals results in the
6456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // initial sampling interval.
6466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  double time = 0.0;
6476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  SampleRateCalculator calc1;
6486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(kSamplingIntervalMs, calc1.ticks_per_ms());
6496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  calc1.UpdateMeasurements(time);
6506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(kSamplingIntervalMs, calc1.ticks_per_ms());
6516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  time += SampleRateCalculator::kWallTimeQueryIntervalMs;
6526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  calc1.UpdateMeasurements(time);
6536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(kSamplingIntervalMs, calc1.ticks_per_ms());
6546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  time += SampleRateCalculator::kWallTimeQueryIntervalMs;
6556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  calc1.UpdateMeasurements(time);
6566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(kSamplingIntervalMs, calc1.ticks_per_ms());
6576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  time += SampleRateCalculator::kWallTimeQueryIntervalMs;
6586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  calc1.UpdateMeasurements(time);
6596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(kSamplingIntervalMs, calc1.ticks_per_ms());
6606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
6616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  SampleRateCalculator calc2;
6626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  time = 0.0;
6636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(kSamplingIntervalMs, calc2.ticks_per_ms());
6646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  calc2.UpdateMeasurements(time);
6656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(kSamplingIntervalMs, calc2.ticks_per_ms());
6666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  time += SampleRateCalculator::kWallTimeQueryIntervalMs * 0.5;
6676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  calc2.UpdateMeasurements(time);
6686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // (1.0 + 2.0) / 2
6696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(kSamplingIntervalMs * 1.5, calc2.ticks_per_ms());
6706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  time += SampleRateCalculator::kWallTimeQueryIntervalMs * 0.75;
6716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  calc2.UpdateMeasurements(time);
6726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // (1.0 + 2.0 + 2.0) / 3
6738defd9ff6930b4e24729971a61cf7469daf119beSteve Block  CHECK_EQ(kSamplingIntervalMs * 5.0, floor(calc2.ticks_per_ms() * 3.0 + 0.5));
6746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
6756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  SampleRateCalculator calc3;
6766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  time = 0.0;
6776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(kSamplingIntervalMs, calc3.ticks_per_ms());
6786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  calc3.UpdateMeasurements(time);
6796ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(kSamplingIntervalMs, calc3.ticks_per_ms());
6806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  time += SampleRateCalculator::kWallTimeQueryIntervalMs * 2;
6816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  calc3.UpdateMeasurements(time);
6826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // (1.0 + 0.5) / 2
6836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CHECK_EQ(kSamplingIntervalMs * 0.75, calc3.ticks_per_ms());
6846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  time += SampleRateCalculator::kWallTimeQueryIntervalMs * 1.5;
6856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  calc3.UpdateMeasurements(time);
6866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // (1.0 + 0.5 + 0.5) / 3
6878defd9ff6930b4e24729971a61cf7469daf119beSteve Block  CHECK_EQ(kSamplingIntervalMs * 2.0, floor(calc3.ticks_per_ms() * 3.0 + 0.5));
6886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
6896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
6907f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
6917f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch// --- P r o f i l e r   E x t e n s i o n ---
6927f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
6937f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochclass ProfilerExtension : public v8::Extension {
6947f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch public:
6957f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  ProfilerExtension() : v8::Extension("v8/profiler", kSource) { }
6967f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
6977f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      v8::Handle<v8::String> name);
6987f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  static v8::Handle<v8::Value> StartProfiling(const v8::Arguments& args);
6997f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  static v8::Handle<v8::Value> StopProfiling(const v8::Arguments& args);
7007f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch private:
7017f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  static const char* kSource;
7027f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch};
7037f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
7047f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
7057f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochconst char* ProfilerExtension::kSource =
7067f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    "native function startProfiling();"
7077f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    "native function stopProfiling();";
7087f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
7097f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochv8::Handle<v8::FunctionTemplate> ProfilerExtension::GetNativeFunction(
7107f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    v8::Handle<v8::String> name) {
7117f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  if (name->Equals(v8::String::New("startProfiling"))) {
7127f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    return v8::FunctionTemplate::New(ProfilerExtension::StartProfiling);
7137f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } else if (name->Equals(v8::String::New("stopProfiling"))) {
7147f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    return v8::FunctionTemplate::New(ProfilerExtension::StopProfiling);
7157f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } else {
7167f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    CHECK(false);
7177f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    return v8::Handle<v8::FunctionTemplate>();
7187f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  }
7197f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
7207f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
7217f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
7227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochv8::Handle<v8::Value> ProfilerExtension::StartProfiling(
7237f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    const v8::Arguments& args) {
7247f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  if (args.Length() > 0)
7257f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    v8::CpuProfiler::StartProfiling(args[0].As<v8::String>());
7267f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  else
7277f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    v8::CpuProfiler::StartProfiling(v8::String::New(""));
7287f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  return v8::Undefined();
7297f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
7307f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
7317f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
7327f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochv8::Handle<v8::Value> ProfilerExtension::StopProfiling(
7337f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    const v8::Arguments& args) {
7347f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  if (args.Length() > 0)
7357f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    v8::CpuProfiler::StopProfiling(args[0].As<v8::String>());
7367f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  else
7377f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    v8::CpuProfiler::StopProfiling(v8::String::New(""));
7387f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  return v8::Undefined();
7397f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
7407f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
7417f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
7427f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochstatic ProfilerExtension kProfilerExtension;
7437f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochv8::DeclareExtension kProfilerExtensionDeclaration(&kProfilerExtension);
7447f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochstatic v8::Persistent<v8::Context> env;
7457f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
7467f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochstatic const ProfileNode* PickChild(const ProfileNode* parent,
7477f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch                                    const char* name) {
7487f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  for (int i = 0; i < parent->children()->length(); ++i) {
7497f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    const ProfileNode* child = parent->children()->at(i);
7507f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    if (strcmp(child->entry()->name(), name) == 0) return child;
7517f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  }
7527f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  return NULL;
7537f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
7547f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
7557f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
7567f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochTEST(RecordStackTraceAtStartProfiling) {
757b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // This test does not pass with inlining enabled since inlined functions
758b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // don't appear in the stack trace.
759b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  i::FLAG_use_inlining = false;
760b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
7617f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  if (env.IsEmpty()) {
7627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    v8::HandleScope scope;
7637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    const char* extensions[] = { "v8/profiler" };
7647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    v8::ExtensionConfiguration config(1, extensions);
7657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    env = v8::Context::New(&config);
7667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  }
7677f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  v8::HandleScope scope;
7687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  env->Enter();
7697f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
7707f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  CHECK_EQ(0, CpuProfiler::GetProfilesCount());
7717f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  CompileRun(
7727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      "function c() { startProfiling(); }\n"
7737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      "function b() { c(); }\n"
7747f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      "function a() { b(); }\n"
7757f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      "a();\n"
7767f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      "stopProfiling();");
7777f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  CHECK_EQ(1, CpuProfiler::GetProfilesCount());
7787f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  CpuProfile* profile =
7797f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      CpuProfiler::GetProfile(NULL, 0);
7807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  const ProfileTree* topDown = profile->top_down();
7817f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  const ProfileNode* current = topDown->root();
782b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  const_cast<ProfileNode*>(current)->Print(0);
7837f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // The tree should look like this:
7847f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  //  (root)
7857f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  //   (anonymous function)
7867f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  //     a
7877f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  //       b
7887f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  //         c
789b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // There can also be:
790b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  //           startProfiling
791b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // if the sampler managed to get a tick.
7927f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  current = PickChild(current, "(anonymous function)");
7937f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  CHECK_NE(NULL, const_cast<ProfileNode*>(current));
7947f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  current = PickChild(current, "a");
7957f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  CHECK_NE(NULL, const_cast<ProfileNode*>(current));
7967f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  current = PickChild(current, "b");
7977f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  CHECK_NE(NULL, const_cast<ProfileNode*>(current));
7987f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  current = PickChild(current, "c");
7997f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  CHECK_NE(NULL, const_cast<ProfileNode*>(current));
800b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  CHECK(current->children()->length() == 0 ||
801b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        current->children()->length() == 1);
802b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  if (current->children()->length() == 1) {
803b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    current = PickChild(current, "startProfiling");
804b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    CHECK_EQ(0, current->children()->length());
805b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
8067f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
8077f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
80880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
80980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian MonsenTEST(Issue51919) {
81080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  CpuProfilesCollection collection;
81180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  i::EmbeddedVector<char*,
81280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen      CpuProfilesCollection::kMaxSimultaneousProfiles> titles;
81380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  for (int i = 0; i < CpuProfilesCollection::kMaxSimultaneousProfiles; ++i) {
81480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    i::Vector<char> title = i::Vector<char>::New(16);
81580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    i::OS::SNPrintF(title, "%d", i);
81680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    CHECK(collection.StartProfiling(title.start(), i + 1));  // UID must be > 0.
81780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    titles[i] = title.start();
81880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  }
81980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  CHECK(!collection.StartProfiling(
82080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen      "maximum", CpuProfilesCollection::kMaxSimultaneousProfiles + 1));
82180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  for (int i = 0; i < CpuProfilesCollection::kMaxSimultaneousProfiles; ++i)
82280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    i::DeleteArray(titles[i]);
82380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}
824