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

Side by Side Diff: test/cctest/test-profile-generator.cc

Issue 148503002: A64: Synchronize with r15545. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 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 | Annotate | Revision Log
« no previous file with comments | « test/cctest/test-platform-tls.cc ('k') | test/cctest/test-regexp.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 12 matching lines...) Expand all
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 // 27 //
28 // Tests of profiles generator and utilities. 28 // Tests of profiles generator and utilities.
29 29
30 #include "v8.h" 30 #include "v8.h"
31 #include "profile-generator-inl.h" 31 #include "profile-generator-inl.h"
32 #include "cctest.h" 32 #include "cctest.h"
33 #include "cpu-profiler.h"
33 #include "../include/v8-profiler.h" 34 #include "../include/v8-profiler.h"
34 35
35 using i::CodeEntry; 36 using i::CodeEntry;
36 using i::CodeMap; 37 using i::CodeMap;
37 using i::CpuProfile; 38 using i::CpuProfile;
38 using i::CpuProfiler; 39 using i::CpuProfiler;
39 using i::CpuProfilesCollection; 40 using i::CpuProfilesCollection;
40 using i::ProfileNode; 41 using i::ProfileNode;
41 using i::ProfileTree; 42 using i::ProfileTree;
42 using i::ProfileGenerator; 43 using i::ProfileGenerator;
43 using i::SampleRateCalculator; 44 using i::SampleRateCalculator;
44 using i::TickSample; 45 using i::TickSample;
45 using i::TokenEnumerator;
46 using i::Vector; 46 using i::Vector;
47 47
48 48
49 namespace v8 {
50 namespace internal {
51
52 class TokenEnumeratorTester {
53 public:
54 static i::List<bool>* token_removed(TokenEnumerator* te) {
55 return &te->token_removed_;
56 }
57 };
58
59 } } // namespace v8::internal
60
61 TEST(TokenEnumerator) {
62 TokenEnumerator te;
63 CHECK_EQ(TokenEnumerator::kNoSecurityToken, te.GetTokenId(NULL));
64 v8::HandleScope hs(v8::Isolate::GetCurrent());
65 v8::Local<v8::String> token1(v8::String::New("1x"));
66 CHECK_EQ(0, te.GetTokenId(*v8::Utils::OpenHandle(*token1)));
67 CHECK_EQ(0, te.GetTokenId(*v8::Utils::OpenHandle(*token1)));
68 v8::Local<v8::String> token2(v8::String::New("2x"));
69 CHECK_EQ(1, te.GetTokenId(*v8::Utils::OpenHandle(*token2)));
70 CHECK_EQ(1, te.GetTokenId(*v8::Utils::OpenHandle(*token2)));
71 CHECK_EQ(0, te.GetTokenId(*v8::Utils::OpenHandle(*token1)));
72 {
73 v8::HandleScope hs(v8::Isolate::GetCurrent());
74 v8::Local<v8::String> token3(v8::String::New("3x"));
75 CHECK_EQ(2, te.GetTokenId(*v8::Utils::OpenHandle(*token3)));
76 CHECK_EQ(1, te.GetTokenId(*v8::Utils::OpenHandle(*token2)));
77 CHECK_EQ(0, te.GetTokenId(*v8::Utils::OpenHandle(*token1)));
78 }
79 CHECK(!i::TokenEnumeratorTester::token_removed(&te)->at(2));
80 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
81 CHECK(i::TokenEnumeratorTester::token_removed(&te)->at(2));
82 CHECK_EQ(1, te.GetTokenId(*v8::Utils::OpenHandle(*token2)));
83 CHECK_EQ(0, te.GetTokenId(*v8::Utils::OpenHandle(*token1)));
84 }
85
86
87 TEST(ProfileNodeFindOrAddChild) { 49 TEST(ProfileNodeFindOrAddChild) {
88 ProfileTree tree; 50 ProfileTree tree;
89 ProfileNode node(&tree, NULL); 51 ProfileNode node(&tree, NULL);
90 CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa"); 52 CodeEntry entry1(i::Logger::FUNCTION_TAG, "aaa");
91 ProfileNode* childNode1 = node.FindOrAddChild(&entry1); 53 ProfileNode* childNode1 = node.FindOrAddChild(&entry1);
92 CHECK_NE(NULL, childNode1); 54 CHECK_NE(NULL, childNode1);
93 CHECK_EQ(childNode1, node.FindOrAddChild(&entry1)); 55 CHECK_EQ(childNode1, node.FindOrAddChild(&entry1));
94 CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb"); 56 CodeEntry entry2(i::Logger::FUNCTION_TAG, "bbb");
95 ProfileNode* childNode2 = node.FindOrAddChild(&entry2); 57 ProfileNode* childNode2 = node.FindOrAddChild(&entry2);
96 CHECK_NE(NULL, childNode2); 58 CHECK_NE(NULL, childNode2);
97 CHECK_NE(childNode1, childNode2); 59 CHECK_NE(childNode1, childNode2);
98 CHECK_EQ(childNode1, node.FindOrAddChild(&entry1)); 60 CHECK_EQ(childNode1, node.FindOrAddChild(&entry1));
99 CHECK_EQ(childNode2, node.FindOrAddChild(&entry2)); 61 CHECK_EQ(childNode2, node.FindOrAddChild(&entry2));
100 CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc"); 62 CodeEntry entry3(i::Logger::FUNCTION_TAG, "ccc");
101 ProfileNode* childNode3 = node.FindOrAddChild(&entry3); 63 ProfileNode* childNode3 = node.FindOrAddChild(&entry3);
102 CHECK_NE(NULL, childNode3); 64 CHECK_NE(NULL, childNode3);
103 CHECK_NE(childNode1, childNode3); 65 CHECK_NE(childNode1, childNode3);
104 CHECK_NE(childNode2, childNode3); 66 CHECK_NE(childNode2, childNode3);
105 CHECK_EQ(childNode1, node.FindOrAddChild(&entry1)); 67 CHECK_EQ(childNode1, node.FindOrAddChild(&entry1));
106 CHECK_EQ(childNode2, node.FindOrAddChild(&entry2)); 68 CHECK_EQ(childNode2, node.FindOrAddChild(&entry2));
107 CHECK_EQ(childNode3, node.FindOrAddChild(&entry3)); 69 CHECK_EQ(childNode3, node.FindOrAddChild(&entry3));
108 } 70 }
109 71
110 72
111 TEST(ProfileNodeFindOrAddChildForSameFunction) { 73 TEST(ProfileNodeFindOrAddChildForSameFunction) {
112 const char* empty = "";
113 const char* aaa = "aaa"; 74 const char* aaa = "aaa";
114 ProfileTree tree; 75 ProfileTree tree;
115 ProfileNode node(&tree, NULL); 76 ProfileNode node(&tree, NULL);
116 CodeEntry entry1(i::Logger::FUNCTION_TAG, empty, aaa); 77 CodeEntry entry1(i::Logger::FUNCTION_TAG, aaa);
117 ProfileNode* childNode1 = node.FindOrAddChild(&entry1); 78 ProfileNode* childNode1 = node.FindOrAddChild(&entry1);
118 CHECK_NE(NULL, childNode1); 79 CHECK_NE(NULL, childNode1);
119 CHECK_EQ(childNode1, node.FindOrAddChild(&entry1)); 80 CHECK_EQ(childNode1, node.FindOrAddChild(&entry1));
120 // The same function again. 81 // The same function again.
121 CodeEntry entry2(i::Logger::FUNCTION_TAG, empty, aaa); 82 CodeEntry entry2(i::Logger::FUNCTION_TAG, aaa);
122 CHECK_EQ(childNode1, node.FindOrAddChild(&entry2)); 83 CHECK_EQ(childNode1, node.FindOrAddChild(&entry2));
123 // Now with a different security token. 84 // Now with a different security token.
124 CodeEntry entry3(i::Logger::FUNCTION_TAG, empty, aaa, 85 CodeEntry entry3(i::Logger::FUNCTION_TAG, aaa);
125 TokenEnumerator::kNoSecurityToken + 1);
126 CHECK_EQ(childNode1, node.FindOrAddChild(&entry3)); 86 CHECK_EQ(childNode1, node.FindOrAddChild(&entry3));
127 } 87 }
128 88
129 89
130 namespace { 90 namespace {
131 91
132 class ProfileTreeTestHelper { 92 class ProfileTreeTestHelper {
133 public: 93 public:
134 explicit ProfileTreeTestHelper(const ProfileTree* tree) 94 explicit ProfileTreeTestHelper(const ProfileTree* tree)
135 : tree_(tree) { } 95 : tree_(tree) { }
(...skipping 14 matching lines...) Expand all
150 return node; 110 return node;
151 } 111 }
152 112
153 private: 113 private:
154 const ProfileTree* tree_; 114 const ProfileTree* tree_;
155 }; 115 };
156 116
157 } // namespace 117 } // namespace
158 118
159 TEST(ProfileTreeAddPathFromStart) { 119 TEST(ProfileTreeAddPathFromStart) {
160 CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa"); 120 CodeEntry entry1(i::Logger::FUNCTION_TAG, "aaa");
161 CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb"); 121 CodeEntry entry2(i::Logger::FUNCTION_TAG, "bbb");
162 CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc"); 122 CodeEntry entry3(i::Logger::FUNCTION_TAG, "ccc");
163 ProfileTree tree; 123 ProfileTree tree;
164 ProfileTreeTestHelper helper(&tree); 124 ProfileTreeTestHelper helper(&tree);
165 CHECK_EQ(NULL, helper.Walk(&entry1)); 125 CHECK_EQ(NULL, helper.Walk(&entry1));
166 CHECK_EQ(NULL, helper.Walk(&entry2)); 126 CHECK_EQ(NULL, helper.Walk(&entry2));
167 CHECK_EQ(NULL, helper.Walk(&entry3)); 127 CHECK_EQ(NULL, helper.Walk(&entry3));
168 128
169 CodeEntry* path[] = {NULL, &entry1, NULL, &entry2, NULL, NULL, &entry3, NULL}; 129 CodeEntry* path[] = {NULL, &entry1, NULL, &entry2, NULL, NULL, &entry3, NULL};
170 Vector<CodeEntry*> path_vec(path, sizeof(path) / sizeof(path[0])); 130 Vector<CodeEntry*> path_vec(path, sizeof(path) / sizeof(path[0]));
171 tree.AddPathFromStart(path_vec); 131 tree.AddPathFromStart(path_vec);
172 CHECK_EQ(NULL, helper.Walk(&entry2)); 132 CHECK_EQ(NULL, helper.Walk(&entry2));
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 CHECK_EQ(2, node3->self_ticks()); 177 CHECK_EQ(2, node3->self_ticks());
218 ProfileNode* node4 = helper.Walk(&entry1, &entry2, &entry2); 178 ProfileNode* node4 = helper.Walk(&entry1, &entry2, &entry2);
219 CHECK_NE(NULL, node4); 179 CHECK_NE(NULL, node4);
220 CHECK_NE(node3, node4); 180 CHECK_NE(node3, node4);
221 CHECK_EQ(0, node4->total_ticks()); 181 CHECK_EQ(0, node4->total_ticks());
222 CHECK_EQ(1, node4->self_ticks()); 182 CHECK_EQ(1, node4->self_ticks());
223 } 183 }
224 184
225 185
226 TEST(ProfileTreeAddPathFromEnd) { 186 TEST(ProfileTreeAddPathFromEnd) {
227 CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa"); 187 CodeEntry entry1(i::Logger::FUNCTION_TAG, "aaa");
228 CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb"); 188 CodeEntry entry2(i::Logger::FUNCTION_TAG, "bbb");
229 CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc"); 189 CodeEntry entry3(i::Logger::FUNCTION_TAG, "ccc");
230 ProfileTree tree; 190 ProfileTree tree;
231 ProfileTreeTestHelper helper(&tree); 191 ProfileTreeTestHelper helper(&tree);
232 CHECK_EQ(NULL, helper.Walk(&entry1)); 192 CHECK_EQ(NULL, helper.Walk(&entry1));
233 CHECK_EQ(NULL, helper.Walk(&entry2)); 193 CHECK_EQ(NULL, helper.Walk(&entry2));
234 CHECK_EQ(NULL, helper.Walk(&entry3)); 194 CHECK_EQ(NULL, helper.Walk(&entry3));
235 195
236 CodeEntry* path[] = {NULL, &entry3, NULL, &entry2, NULL, NULL, &entry1, NULL}; 196 CodeEntry* path[] = {NULL, &entry3, NULL, &entry2, NULL, NULL, &entry1, NULL};
237 Vector<CodeEntry*> path_vec(path, sizeof(path) / sizeof(path[0])); 197 Vector<CodeEntry*> path_vec(path, sizeof(path) / sizeof(path[0]));
238 tree.AddPathFromEnd(path_vec); 198 tree.AddPathFromEnd(path_vec);
239 CHECK_EQ(NULL, helper.Walk(&entry2)); 199 CHECK_EQ(NULL, helper.Walk(&entry2));
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 empty_tree.CalculateTotalTicks(); 257 empty_tree.CalculateTotalTicks();
298 CHECK_EQ(0, empty_tree.root()->total_ticks()); 258 CHECK_EQ(0, empty_tree.root()->total_ticks());
299 CHECK_EQ(0, empty_tree.root()->self_ticks()); 259 CHECK_EQ(0, empty_tree.root()->self_ticks());
300 empty_tree.root()->IncrementSelfTicks(); 260 empty_tree.root()->IncrementSelfTicks();
301 CHECK_EQ(0, empty_tree.root()->total_ticks()); 261 CHECK_EQ(0, empty_tree.root()->total_ticks());
302 CHECK_EQ(1, empty_tree.root()->self_ticks()); 262 CHECK_EQ(1, empty_tree.root()->self_ticks());
303 empty_tree.CalculateTotalTicks(); 263 empty_tree.CalculateTotalTicks();
304 CHECK_EQ(1, empty_tree.root()->total_ticks()); 264 CHECK_EQ(1, empty_tree.root()->total_ticks());
305 CHECK_EQ(1, empty_tree.root()->self_ticks()); 265 CHECK_EQ(1, empty_tree.root()->self_ticks());
306 266
307 CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa"); 267 CodeEntry entry1(i::Logger::FUNCTION_TAG, "aaa");
308 CodeEntry* e1_path[] = {&entry1}; 268 CodeEntry* e1_path[] = {&entry1};
309 Vector<CodeEntry*> e1_path_vec( 269 Vector<CodeEntry*> e1_path_vec(
310 e1_path, sizeof(e1_path) / sizeof(e1_path[0])); 270 e1_path, sizeof(e1_path) / sizeof(e1_path[0]));
311 271
312 ProfileTree single_child_tree; 272 ProfileTree single_child_tree;
313 single_child_tree.AddPathFromStart(e1_path_vec); 273 single_child_tree.AddPathFromStart(e1_path_vec);
314 single_child_tree.root()->IncrementSelfTicks(); 274 single_child_tree.root()->IncrementSelfTicks();
315 CHECK_EQ(0, single_child_tree.root()->total_ticks()); 275 CHECK_EQ(0, single_child_tree.root()->total_ticks());
316 CHECK_EQ(1, single_child_tree.root()->self_ticks()); 276 CHECK_EQ(1, single_child_tree.root()->self_ticks());
317 ProfileTreeTestHelper single_child_helper(&single_child_tree); 277 ProfileTreeTestHelper single_child_helper(&single_child_tree);
318 ProfileNode* node1 = single_child_helper.Walk(&entry1); 278 ProfileNode* node1 = single_child_helper.Walk(&entry1);
319 CHECK_NE(NULL, node1); 279 CHECK_NE(NULL, node1);
320 CHECK_EQ(0, node1->total_ticks()); 280 CHECK_EQ(0, node1->total_ticks());
321 CHECK_EQ(1, node1->self_ticks()); 281 CHECK_EQ(1, node1->self_ticks());
322 single_child_tree.CalculateTotalTicks(); 282 single_child_tree.CalculateTotalTicks();
323 CHECK_EQ(2, single_child_tree.root()->total_ticks()); 283 CHECK_EQ(2, single_child_tree.root()->total_ticks());
324 CHECK_EQ(1, single_child_tree.root()->self_ticks()); 284 CHECK_EQ(1, single_child_tree.root()->self_ticks());
325 CHECK_EQ(1, node1->total_ticks()); 285 CHECK_EQ(1, node1->total_ticks());
326 CHECK_EQ(1, node1->self_ticks()); 286 CHECK_EQ(1, node1->self_ticks());
327 287
328 CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb"); 288 CodeEntry entry2(i::Logger::FUNCTION_TAG, "bbb");
329 CodeEntry* e1_e2_path[] = {&entry1, &entry2}; 289 CodeEntry* e1_e2_path[] = {&entry1, &entry2};
330 Vector<CodeEntry*> e1_e2_path_vec( 290 Vector<CodeEntry*> e1_e2_path_vec(
331 e1_e2_path, sizeof(e1_e2_path) / sizeof(e1_e2_path[0])); 291 e1_e2_path, sizeof(e1_e2_path) / sizeof(e1_e2_path[0]));
332 292
333 ProfileTree flat_tree; 293 ProfileTree flat_tree;
334 ProfileTreeTestHelper flat_helper(&flat_tree); 294 ProfileTreeTestHelper flat_helper(&flat_tree);
335 flat_tree.AddPathFromStart(e1_path_vec); 295 flat_tree.AddPathFromStart(e1_path_vec);
336 flat_tree.AddPathFromStart(e1_path_vec); 296 flat_tree.AddPathFromStart(e1_path_vec);
337 flat_tree.AddPathFromStart(e1_e2_path_vec); 297 flat_tree.AddPathFromStart(e1_e2_path_vec);
338 flat_tree.AddPathFromStart(e1_e2_path_vec); 298 flat_tree.AddPathFromStart(e1_e2_path_vec);
(...skipping 14 matching lines...) Expand all
353 CHECK_EQ(5, flat_tree.root()->total_ticks()); 313 CHECK_EQ(5, flat_tree.root()->total_ticks());
354 CHECK_EQ(0, flat_tree.root()->self_ticks()); 314 CHECK_EQ(0, flat_tree.root()->self_ticks());
355 CHECK_EQ(5, node1->total_ticks()); 315 CHECK_EQ(5, node1->total_ticks());
356 CHECK_EQ(2, node1->self_ticks()); 316 CHECK_EQ(2, node1->self_ticks());
357 CHECK_EQ(3, node2->total_ticks()); 317 CHECK_EQ(3, node2->total_ticks());
358 CHECK_EQ(3, node2->self_ticks()); 318 CHECK_EQ(3, node2->self_ticks());
359 319
360 CodeEntry* e2_path[] = {&entry2}; 320 CodeEntry* e2_path[] = {&entry2};
361 Vector<CodeEntry*> e2_path_vec( 321 Vector<CodeEntry*> e2_path_vec(
362 e2_path, sizeof(e2_path) / sizeof(e2_path[0])); 322 e2_path, sizeof(e2_path) / sizeof(e2_path[0]));
363 CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc"); 323 CodeEntry entry3(i::Logger::FUNCTION_TAG, "ccc");
364 CodeEntry* e3_path[] = {&entry3}; 324 CodeEntry* e3_path[] = {&entry3};
365 Vector<CodeEntry*> e3_path_vec( 325 Vector<CodeEntry*> e3_path_vec(
366 e3_path, sizeof(e3_path) / sizeof(e3_path[0])); 326 e3_path, sizeof(e3_path) / sizeof(e3_path[0]));
367 327
368 ProfileTree wide_tree; 328 ProfileTree wide_tree;
369 ProfileTreeTestHelper wide_helper(&wide_tree); 329 ProfileTreeTestHelper wide_helper(&wide_tree);
370 wide_tree.AddPathFromStart(e1_path_vec); 330 wide_tree.AddPathFromStart(e1_path_vec);
371 wide_tree.AddPathFromStart(e1_path_vec); 331 wide_tree.AddPathFromStart(e1_path_vec);
372 wide_tree.AddPathFromStart(e1_e2_path_vec); 332 wide_tree.AddPathFromStart(e1_e2_path_vec);
373 wide_tree.AddPathFromStart(e2_path_vec); 333 wide_tree.AddPathFromStart(e2_path_vec);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
408 CHECK_EQ(2, node1->self_ticks()); 368 CHECK_EQ(2, node1->self_ticks());
409 CHECK_EQ(1, node1_2->total_ticks()); 369 CHECK_EQ(1, node1_2->total_ticks());
410 CHECK_EQ(1, node1_2->self_ticks()); 370 CHECK_EQ(1, node1_2->self_ticks());
411 CHECK_EQ(3, node2->total_ticks()); 371 CHECK_EQ(3, node2->total_ticks());
412 CHECK_EQ(3, node2->self_ticks()); 372 CHECK_EQ(3, node2->self_ticks());
413 CHECK_EQ(4, node3->total_ticks()); 373 CHECK_EQ(4, node3->total_ticks());
414 CHECK_EQ(4, node3->self_ticks()); 374 CHECK_EQ(4, node3->self_ticks());
415 } 375 }
416 376
417 377
418 TEST(ProfileTreeFilteredClone) {
419 ProfileTree source_tree;
420 const int token0 = 0, token1 = 1, token2 = 2;
421 CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa", token0);
422 CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb", token1);
423 CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc", token0);
424 CodeEntry entry4(i::Logger::FUNCTION_TAG, "", "ddd",
425 TokenEnumerator::kInheritsSecurityToken);
426
427 {
428 CodeEntry* e1_e2_path[] = {&entry1, &entry2};
429 Vector<CodeEntry*> e1_e2_path_vec(
430 e1_e2_path, sizeof(e1_e2_path) / sizeof(e1_e2_path[0]));
431 source_tree.AddPathFromStart(e1_e2_path_vec);
432 CodeEntry* e2_e4_path[] = {&entry2, &entry4};
433 Vector<CodeEntry*> e2_e4_path_vec(
434 e2_e4_path, sizeof(e2_e4_path) / sizeof(e2_e4_path[0]));
435 source_tree.AddPathFromStart(e2_e4_path_vec);
436 CodeEntry* e3_e1_path[] = {&entry3, &entry1};
437 Vector<CodeEntry*> e3_e1_path_vec(
438 e3_e1_path, sizeof(e3_e1_path) / sizeof(e3_e1_path[0]));
439 source_tree.AddPathFromStart(e3_e1_path_vec);
440 CodeEntry* e3_e2_path[] = {&entry3, &entry2};
441 Vector<CodeEntry*> e3_e2_path_vec(
442 e3_e2_path, sizeof(e3_e2_path) / sizeof(e3_e2_path[0]));
443 source_tree.AddPathFromStart(e3_e2_path_vec);
444 source_tree.CalculateTotalTicks();
445 // Results in -> {entry1,0,1,0} -> {entry2,1,1,1}
446 // {root,0,4,-1} -> {entry2,0,1,1} -> {entry4,1,1,inherits}
447 // -> {entry3,0,2,0} -> {entry1,1,1,0}
448 // -> {entry2,1,1,1}
449 CHECK_EQ(4, source_tree.root()->total_ticks());
450 CHECK_EQ(0, source_tree.root()->self_ticks());
451 }
452
453 {
454 ProfileTree token0_tree;
455 token0_tree.FilteredClone(&source_tree, token0);
456 // Should be -> {entry1,1,1,0}
457 // {root,1,4,-1} -> {entry3,1,2,0} -> {entry1,1,1,0}
458 // [self ticks from filtered nodes are attributed to their parents]
459 CHECK_EQ(4, token0_tree.root()->total_ticks());
460 CHECK_EQ(1, token0_tree.root()->self_ticks());
461 ProfileTreeTestHelper token0_helper(&token0_tree);
462 ProfileNode* node1 = token0_helper.Walk(&entry1);
463 CHECK_NE(NULL, node1);
464 CHECK_EQ(1, node1->total_ticks());
465 CHECK_EQ(1, node1->self_ticks());
466 CHECK_EQ(NULL, token0_helper.Walk(&entry2));
467 ProfileNode* node3 = token0_helper.Walk(&entry3);
468 CHECK_NE(NULL, node3);
469 CHECK_EQ(2, node3->total_ticks());
470 CHECK_EQ(1, node3->self_ticks());
471 ProfileNode* node3_1 = token0_helper.Walk(&entry3, &entry1);
472 CHECK_NE(NULL, node3_1);
473 CHECK_EQ(1, node3_1->total_ticks());
474 CHECK_EQ(1, node3_1->self_ticks());
475 CHECK_EQ(NULL, token0_helper.Walk(&entry3, &entry2));
476 }
477
478 {
479 ProfileTree token1_tree;
480 token1_tree.FilteredClone(&source_tree, token1);
481 // Should be
482 // {root,1,4,-1} -> {entry2,2,3,1} -> {entry4,1,1,inherits}
483 // [child nodes referring to the same entry get merged and
484 // their self times summed up]
485 CHECK_EQ(4, token1_tree.root()->total_ticks());
486 CHECK_EQ(1, token1_tree.root()->self_ticks());
487 ProfileTreeTestHelper token1_helper(&token1_tree);
488 CHECK_EQ(NULL, token1_helper.Walk(&entry1));
489 CHECK_EQ(NULL, token1_helper.Walk(&entry3));
490 ProfileNode* node2 = token1_helper.Walk(&entry2);
491 CHECK_NE(NULL, node2);
492 CHECK_EQ(3, node2->total_ticks());
493 CHECK_EQ(2, node2->self_ticks());
494 ProfileNode* node2_4 = token1_helper.Walk(&entry2, &entry4);
495 CHECK_NE(NULL, node2_4);
496 CHECK_EQ(1, node2_4->total_ticks());
497 CHECK_EQ(1, node2_4->self_ticks());
498 }
499
500 {
501 ProfileTree token2_tree;
502 token2_tree.FilteredClone(&source_tree, token2);
503 // Should be
504 // {root,4,4,-1}
505 // [no nodes, all ticks get migrated into root node]
506 CHECK_EQ(4, token2_tree.root()->total_ticks());
507 CHECK_EQ(4, token2_tree.root()->self_ticks());
508 ProfileTreeTestHelper token2_helper(&token2_tree);
509 CHECK_EQ(NULL, token2_helper.Walk(&entry1));
510 CHECK_EQ(NULL, token2_helper.Walk(&entry2));
511 CHECK_EQ(NULL, token2_helper.Walk(&entry3));
512 }
513 }
514
515
516 static inline i::Address ToAddress(int n) { 378 static inline i::Address ToAddress(int n) {
517 return reinterpret_cast<i::Address>(n); 379 return reinterpret_cast<i::Address>(n);
518 } 380 }
519 381
382
520 TEST(CodeMapAddCode) { 383 TEST(CodeMapAddCode) {
521 CodeMap code_map; 384 CodeMap code_map;
522 CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa"); 385 CodeEntry entry1(i::Logger::FUNCTION_TAG, "aaa");
523 CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb"); 386 CodeEntry entry2(i::Logger::FUNCTION_TAG, "bbb");
524 CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc"); 387 CodeEntry entry3(i::Logger::FUNCTION_TAG, "ccc");
525 CodeEntry entry4(i::Logger::FUNCTION_TAG, "", "ddd"); 388 CodeEntry entry4(i::Logger::FUNCTION_TAG, "ddd");
526 code_map.AddCode(ToAddress(0x1500), &entry1, 0x200); 389 code_map.AddCode(ToAddress(0x1500), &entry1, 0x200);
527 code_map.AddCode(ToAddress(0x1700), &entry2, 0x100); 390 code_map.AddCode(ToAddress(0x1700), &entry2, 0x100);
528 code_map.AddCode(ToAddress(0x1900), &entry3, 0x50); 391 code_map.AddCode(ToAddress(0x1900), &entry3, 0x50);
529 code_map.AddCode(ToAddress(0x1950), &entry4, 0x10); 392 code_map.AddCode(ToAddress(0x1950), &entry4, 0x10);
530 CHECK_EQ(NULL, code_map.FindEntry(0)); 393 CHECK_EQ(NULL, code_map.FindEntry(0));
531 CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1500 - 1))); 394 CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1500 - 1)));
532 CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1500))); 395 CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1500)));
533 CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1500 + 0x100))); 396 CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1500 + 0x100)));
534 CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1500 + 0x200 - 1))); 397 CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1500 + 0x200 - 1)));
535 CHECK_EQ(&entry2, code_map.FindEntry(ToAddress(0x1700))); 398 CHECK_EQ(&entry2, code_map.FindEntry(ToAddress(0x1700)));
536 CHECK_EQ(&entry2, code_map.FindEntry(ToAddress(0x1700 + 0x50))); 399 CHECK_EQ(&entry2, code_map.FindEntry(ToAddress(0x1700 + 0x50)));
537 CHECK_EQ(&entry2, code_map.FindEntry(ToAddress(0x1700 + 0x100 - 1))); 400 CHECK_EQ(&entry2, code_map.FindEntry(ToAddress(0x1700 + 0x100 - 1)));
538 CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1700 + 0x100))); 401 CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1700 + 0x100)));
539 CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1900 - 1))); 402 CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1900 - 1)));
540 CHECK_EQ(&entry3, code_map.FindEntry(ToAddress(0x1900))); 403 CHECK_EQ(&entry3, code_map.FindEntry(ToAddress(0x1900)));
541 CHECK_EQ(&entry3, code_map.FindEntry(ToAddress(0x1900 + 0x28))); 404 CHECK_EQ(&entry3, code_map.FindEntry(ToAddress(0x1900 + 0x28)));
542 CHECK_EQ(&entry4, code_map.FindEntry(ToAddress(0x1950))); 405 CHECK_EQ(&entry4, code_map.FindEntry(ToAddress(0x1950)));
543 CHECK_EQ(&entry4, code_map.FindEntry(ToAddress(0x1950 + 0x7))); 406 CHECK_EQ(&entry4, code_map.FindEntry(ToAddress(0x1950 + 0x7)));
544 CHECK_EQ(&entry4, code_map.FindEntry(ToAddress(0x1950 + 0x10 - 1))); 407 CHECK_EQ(&entry4, code_map.FindEntry(ToAddress(0x1950 + 0x10 - 1)));
545 CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1950 + 0x10))); 408 CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1950 + 0x10)));
546 CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0xFFFFFFFF))); 409 CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0xFFFFFFFF)));
547 } 410 }
548 411
549 412
550 TEST(CodeMapMoveAndDeleteCode) { 413 TEST(CodeMapMoveAndDeleteCode) {
551 CodeMap code_map; 414 CodeMap code_map;
552 CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa"); 415 CodeEntry entry1(i::Logger::FUNCTION_TAG, "aaa");
553 CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb"); 416 CodeEntry entry2(i::Logger::FUNCTION_TAG, "bbb");
554 code_map.AddCode(ToAddress(0x1500), &entry1, 0x200); 417 code_map.AddCode(ToAddress(0x1500), &entry1, 0x200);
555 code_map.AddCode(ToAddress(0x1700), &entry2, 0x100); 418 code_map.AddCode(ToAddress(0x1700), &entry2, 0x100);
556 CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1500))); 419 CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1500)));
557 CHECK_EQ(&entry2, code_map.FindEntry(ToAddress(0x1700))); 420 CHECK_EQ(&entry2, code_map.FindEntry(ToAddress(0x1700)));
558 code_map.MoveCode(ToAddress(0x1500), ToAddress(0x1700)); // Deprecate bbb. 421 code_map.MoveCode(ToAddress(0x1500), ToAddress(0x1700)); // Deprecate bbb.
559 CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1500))); 422 CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1500)));
560 CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1700))); 423 CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1700)));
561 CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc"); 424 CodeEntry entry3(i::Logger::FUNCTION_TAG, "ccc");
562 code_map.AddCode(ToAddress(0x1750), &entry3, 0x100); 425 code_map.AddCode(ToAddress(0x1750), &entry3, 0x100);
563 CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1700))); 426 CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1700)));
564 CHECK_EQ(&entry3, code_map.FindEntry(ToAddress(0x1750))); 427 CHECK_EQ(&entry3, code_map.FindEntry(ToAddress(0x1750)));
565 } 428 }
566 429
567 430
568 namespace { 431 namespace {
569 432
570 class TestSetup { 433 class TestSetup {
571 public: 434 public:
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
615 sample2.frames_count = 3; 478 sample2.frames_count = 3;
616 generator.RecordTickSample(sample2); 479 generator.RecordTickSample(sample2);
617 TickSample sample3; 480 TickSample sample3;
618 sample3.pc = ToAddress(0x1510); 481 sample3.pc = ToAddress(0x1510);
619 sample3.tos = ToAddress(0x1500); 482 sample3.tos = ToAddress(0x1500);
620 sample3.stack[0] = ToAddress(0x1910); 483 sample3.stack[0] = ToAddress(0x1910);
621 sample3.stack[1] = ToAddress(0x1610); 484 sample3.stack[1] = ToAddress(0x1610);
622 sample3.frames_count = 2; 485 sample3.frames_count = 2;
623 generator.RecordTickSample(sample3); 486 generator.RecordTickSample(sample3);
624 487
625 CpuProfile* profile = 488 CpuProfile* profile = profiles.StopProfiling("", 1);
626 profiles.StopProfiling(TokenEnumerator::kNoSecurityToken, "", 1);
627 CHECK_NE(NULL, profile); 489 CHECK_NE(NULL, profile);
628 ProfileTreeTestHelper top_down_test_helper(profile->top_down()); 490 ProfileTreeTestHelper top_down_test_helper(profile->top_down());
629 CHECK_EQ(NULL, top_down_test_helper.Walk(entry2)); 491 CHECK_EQ(NULL, top_down_test_helper.Walk(entry2));
630 CHECK_EQ(NULL, top_down_test_helper.Walk(entry3)); 492 CHECK_EQ(NULL, top_down_test_helper.Walk(entry3));
631 ProfileNode* node1 = top_down_test_helper.Walk(entry1); 493 ProfileNode* node1 = top_down_test_helper.Walk(entry1);
632 CHECK_NE(NULL, node1); 494 CHECK_NE(NULL, node1);
633 CHECK_EQ(entry1, node1->entry()); 495 CHECK_EQ(entry1, node1->entry());
634 ProfileNode* node2 = top_down_test_helper.Walk(entry1, entry1); 496 ProfileNode* node2 = top_down_test_helper.Walk(entry1, entry1);
635 CHECK_NE(NULL, node2); 497 CHECK_NE(NULL, node2);
636 CHECK_EQ(entry1, node2->entry()); 498 CHECK_EQ(entry1, node2->entry());
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
693 } 555 }
694 556
695 557
696 static void CheckNodeIds(ProfileNode* node, int* expectedId) { 558 static void CheckNodeIds(ProfileNode* node, int* expectedId) {
697 CHECK_EQ((*expectedId)++, node->id()); 559 CHECK_EQ((*expectedId)++, node->id());
698 for (int i = 0; i < node->children()->length(); i++) { 560 for (int i = 0; i < node->children()->length(); i++) {
699 CheckNodeIds(node->children()->at(i), expectedId); 561 CheckNodeIds(node->children()->at(i), expectedId);
700 } 562 }
701 } 563 }
702 564
565
703 TEST(SampleIds) { 566 TEST(SampleIds) {
704 TestSetup test_setup; 567 TestSetup test_setup;
705 CpuProfilesCollection profiles; 568 CpuProfilesCollection profiles;
706 profiles.StartProfiling("", 1, true); 569 profiles.StartProfiling("", 1, true);
707 ProfileGenerator generator(&profiles); 570 ProfileGenerator generator(&profiles);
708 CodeEntry* entry1 = profiles.NewCodeEntry(i::Logger::FUNCTION_TAG, "aaa"); 571 CodeEntry* entry1 = profiles.NewCodeEntry(i::Logger::FUNCTION_TAG, "aaa");
709 CodeEntry* entry2 = profiles.NewCodeEntry(i::Logger::FUNCTION_TAG, "bbb"); 572 CodeEntry* entry2 = profiles.NewCodeEntry(i::Logger::FUNCTION_TAG, "bbb");
710 CodeEntry* entry3 = profiles.NewCodeEntry(i::Logger::FUNCTION_TAG, "ccc"); 573 CodeEntry* entry3 = profiles.NewCodeEntry(i::Logger::FUNCTION_TAG, "ccc");
711 generator.code_map()->AddCode(ToAddress(0x1500), entry1, 0x200); 574 generator.code_map()->AddCode(ToAddress(0x1500), entry1, 0x200);
712 generator.code_map()->AddCode(ToAddress(0x1700), entry2, 0x100); 575 generator.code_map()->AddCode(ToAddress(0x1700), entry2, 0x100);
(...skipping 15 matching lines...) Expand all
728 sample2.stack[2] = ToAddress(0x1620); 591 sample2.stack[2] = ToAddress(0x1620);
729 sample2.frames_count = 3; 592 sample2.frames_count = 3;
730 generator.RecordTickSample(sample2); 593 generator.RecordTickSample(sample2);
731 TickSample sample3; 594 TickSample sample3;
732 sample3.pc = ToAddress(0x1510); 595 sample3.pc = ToAddress(0x1510);
733 sample3.stack[0] = ToAddress(0x1910); 596 sample3.stack[0] = ToAddress(0x1910);
734 sample3.stack[1] = ToAddress(0x1610); 597 sample3.stack[1] = ToAddress(0x1610);
735 sample3.frames_count = 2; 598 sample3.frames_count = 2;
736 generator.RecordTickSample(sample3); 599 generator.RecordTickSample(sample3);
737 600
738 CpuProfile* profile = 601 CpuProfile* profile = profiles.StopProfiling("", 1);
739 profiles.StopProfiling(TokenEnumerator::kNoSecurityToken, "", 1);
740 int nodeId = 1; 602 int nodeId = 1;
741 CheckNodeIds(profile->top_down()->root(), &nodeId); 603 CheckNodeIds(profile->top_down()->root(), &nodeId);
742 CHECK_EQ(7, nodeId - 1); 604 CHECK_EQ(7, nodeId - 1);
743 605
744 CHECK_EQ(3, profile->samples_count()); 606 CHECK_EQ(3, profile->samples_count());
745 int expected_id[] = {3, 5, 7}; 607 int expected_id[] = {3, 5, 7};
746 for (int i = 0; i < 3; i++) { 608 for (int i = 0; i < 3; i++) {
747 CHECK_EQ(expected_id[i], profile->sample(i)->id()); 609 CHECK_EQ(expected_id[i], profile->sample(i)->id());
748 } 610 }
749 } 611 }
750 612
751 613
752 TEST(NoSamples) { 614 TEST(NoSamples) {
753 TestSetup test_setup; 615 TestSetup test_setup;
754 CpuProfilesCollection profiles; 616 CpuProfilesCollection profiles;
755 profiles.StartProfiling("", 1, false); 617 profiles.StartProfiling("", 1, false);
756 ProfileGenerator generator(&profiles); 618 ProfileGenerator generator(&profiles);
757 CodeEntry* entry1 = profiles.NewCodeEntry(i::Logger::FUNCTION_TAG, "aaa"); 619 CodeEntry* entry1 = profiles.NewCodeEntry(i::Logger::FUNCTION_TAG, "aaa");
758 generator.code_map()->AddCode(ToAddress(0x1500), entry1, 0x200); 620 generator.code_map()->AddCode(ToAddress(0x1500), entry1, 0x200);
759 621
760 // We are building the following calls tree: 622 // We are building the following calls tree:
761 // (root)#1 -> aaa #2 -> aaa #3 - sample1 623 // (root)#1 -> aaa #2 -> aaa #3 - sample1
762 TickSample sample1; 624 TickSample sample1;
763 sample1.pc = ToAddress(0x1600); 625 sample1.pc = ToAddress(0x1600);
764 sample1.stack[0] = ToAddress(0x1510); 626 sample1.stack[0] = ToAddress(0x1510);
765 sample1.frames_count = 1; 627 sample1.frames_count = 1;
766 generator.RecordTickSample(sample1); 628 generator.RecordTickSample(sample1);
767 629
768 CpuProfile* profile = 630 CpuProfile* profile = profiles.StopProfiling("", 1);
769 profiles.StopProfiling(TokenEnumerator::kNoSecurityToken, "", 1);
770 int nodeId = 1; 631 int nodeId = 1;
771 CheckNodeIds(profile->top_down()->root(), &nodeId); 632 CheckNodeIds(profile->top_down()->root(), &nodeId);
772 CHECK_EQ(3, nodeId - 1); 633 CHECK_EQ(3, nodeId - 1);
773 634
774 CHECK_EQ(0, profile->samples_count()); 635 CHECK_EQ(0, profile->samples_count());
775 } 636 }
776 637
777 638
778 // --- P r o f i l e r E x t e n s i o n --- 639 // --- P r o f i l e r E x t e n s i o n ---
779 640
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
853 714
854 CpuProfiler* profiler = i::Isolate::Current()->cpu_profiler(); 715 CpuProfiler* profiler = i::Isolate::Current()->cpu_profiler();
855 CHECK_EQ(0, profiler->GetProfilesCount()); 716 CHECK_EQ(0, profiler->GetProfilesCount());
856 CompileRun( 717 CompileRun(
857 "function c() { startProfiling(); }\n" 718 "function c() { startProfiling(); }\n"
858 "function b() { c(); }\n" 719 "function b() { c(); }\n"
859 "function a() { b(); }\n" 720 "function a() { b(); }\n"
860 "a();\n" 721 "a();\n"
861 "stopProfiling();"); 722 "stopProfiling();");
862 CHECK_EQ(1, profiler->GetProfilesCount()); 723 CHECK_EQ(1, profiler->GetProfilesCount());
863 CpuProfile* profile = profiler->GetProfile(NULL, 0); 724 CpuProfile* profile = profiler->GetProfile(0);
864 const ProfileTree* topDown = profile->top_down(); 725 const ProfileTree* topDown = profile->top_down();
865 const ProfileNode* current = topDown->root(); 726 const ProfileNode* current = topDown->root();
866 const_cast<ProfileNode*>(current)->Print(0); 727 const_cast<ProfileNode*>(current)->Print(0);
867 // The tree should look like this: 728 // The tree should look like this:
868 // (root) 729 // (root)
869 // (anonymous function) 730 // (anonymous function)
870 // a 731 // a
871 // b 732 // b
872 // c 733 // c
873 // There can also be: 734 // There can also be:
(...skipping 25 matching lines...) Expand all
899 i::OS::SNPrintF(title, "%d", i); 760 i::OS::SNPrintF(title, "%d", i);
900 // UID must be > 0. 761 // UID must be > 0.
901 CHECK(collection.StartProfiling(title.start(), i + 1, false)); 762 CHECK(collection.StartProfiling(title.start(), i + 1, false));
902 titles[i] = title.start(); 763 titles[i] = title.start();
903 } 764 }
904 CHECK(!collection.StartProfiling( 765 CHECK(!collection.StartProfiling(
905 "maximum", CpuProfilesCollection::kMaxSimultaneousProfiles + 1, false)); 766 "maximum", CpuProfilesCollection::kMaxSimultaneousProfiles + 1, false));
906 for (int i = 0; i < CpuProfilesCollection::kMaxSimultaneousProfiles; ++i) 767 for (int i = 0; i < CpuProfilesCollection::kMaxSimultaneousProfiles; ++i)
907 i::DeleteArray(titles[i]); 768 i::DeleteArray(titles[i]);
908 } 769 }
770
771
772 static const v8::CpuProfileNode* PickChild(const v8::CpuProfileNode* parent,
773 const char* name) {
774 for (int i = 0; i < parent->GetChildrenCount(); ++i) {
775 const v8::CpuProfileNode* child = parent->GetChild(i);
776 v8::String::AsciiValue function_name(child->GetFunctionName());
777 if (strcmp(*function_name, name) == 0) return child;
778 }
779 return NULL;
780 }
781
782
783 TEST(ProfileNodeScriptId) {
784 // This test does not pass with inlining enabled since inlined functions
785 // don't appear in the stack trace.
786 i::FLAG_use_inlining = false;
787
788 const char* extensions[] = { "v8/profiler" };
789 v8::ExtensionConfiguration config(1, extensions);
790 LocalContext env(&config);
791 v8::HandleScope hs(env->GetIsolate());
792
793 v8::CpuProfiler* profiler = env->GetIsolate()->GetCpuProfiler();
794 CHECK_EQ(0, profiler->GetProfileCount());
795 v8::Handle<v8::Script> script_a = v8::Script::Compile(v8::String::New(
796 "function a() { startProfiling(); }\n"));
797 script_a->Run();
798 v8::Handle<v8::Script> script_b = v8::Script::Compile(v8::String::New(
799 "function b() { a(); }\n"
800 "b();\n"
801 "stopProfiling();\n"));
802 script_b->Run();
803 CHECK_EQ(1, profiler->GetProfileCount());
804 const v8::CpuProfile* profile = profiler->GetCpuProfile(0);
805 const v8::CpuProfileNode* current = profile->GetTopDownRoot();
806 reinterpret_cast<ProfileNode*>(
807 const_cast<v8::CpuProfileNode*>(current))->Print(0);
808 // The tree should look like this:
809 // (root)
810 // (anonymous function)
811 // b
812 // a
813 // There can also be:
814 // startProfiling
815 // if the sampler managed to get a tick.
816 current = PickChild(current, i::ProfileGenerator::kAnonymousFunctionName);
817 CHECK_NE(NULL, const_cast<v8::CpuProfileNode*>(current));
818
819 current = PickChild(current, "b");
820 CHECK_NE(NULL, const_cast<v8::CpuProfileNode*>(current));
821 CHECK_EQ(script_b->GetId(), current->GetScriptId());
822
823 current = PickChild(current, "a");
824 CHECK_NE(NULL, const_cast<v8::CpuProfileNode*>(current));
825 CHECK_EQ(script_a->GetId(), current->GetScriptId());
826 }
827
828
829
830
831 static const char* line_number_test_source_existing_functions =
832 "function foo_at_the_first_line() {\n"
833 "}\n"
834 "foo_at_the_first_line();\n"
835 "function lazy_func_at_forth_line() {}\n";
836
837
838 static const char* line_number_test_source_profile_time_functions =
839 "// Empty first line\n"
840 "function bar_at_the_second_line() {\n"
841 " foo_at_the_first_line();\n"
842 "}\n"
843 "bar_at_the_second_line();\n"
844 "function lazy_func_at_6th_line() {}";
845
846 int GetFunctionLineNumber(LocalContext* env, const char* name) {
847 CpuProfiler* profiler = i::Isolate::Current()->cpu_profiler();
848 CodeMap* code_map = profiler->generator()->code_map();
849 i::Handle<i::JSFunction> func = v8::Utils::OpenHandle(
850 *v8::Local<v8::Function>::Cast(
851 (*(*env))->Global()->Get(v8_str(name))));
852 CodeEntry* func_entry = code_map->FindEntry(func->code()->address());
853 if (!func_entry)
854 FATAL(name);
855 return func_entry->line_number();
856 }
857
858
859 TEST(LineNumber) {
860 i::FLAG_use_inlining = false;
861
862 CcTest::InitializeVM();
863 LocalContext env;
864 i::Isolate* isolate = i::Isolate::Current();
865 TestSetup test_setup;
866
867 i::HandleScope scope(isolate);
868
869 CompileRun(line_number_test_source_existing_functions);
870
871 CpuProfiler* profiler = isolate->cpu_profiler();
872 profiler->StartProfiling("LineNumber");
873
874 CompileRun(line_number_test_source_profile_time_functions);
875
876 profiler->processor()->StopSynchronously();
877
878 CHECK_EQ(1, GetFunctionLineNumber(&env, "foo_at_the_first_line"));
879 CHECK_EQ(0, GetFunctionLineNumber(&env, "lazy_func_at_forth_line"));
880 CHECK_EQ(2, GetFunctionLineNumber(&env, "bar_at_the_second_line"));
881 CHECK_EQ(0, GetFunctionLineNumber(&env, "lazy_func_at_6th_line"));
882
883 profiler->StopProfiling("LineNumber");
884 }
OLDNEW
« no previous file with comments | « test/cctest/test-platform-tls.cc ('k') | test/cctest/test-regexp.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698