OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
2 // | 2 // |
3 // Tests of profiles generator and utilities. | 3 // Tests of profiles generator and utilities. |
4 | 4 |
5 #ifdef ENABLE_LOGGING_AND_PROFILING | 5 #ifdef ENABLE_LOGGING_AND_PROFILING |
6 | 6 |
7 #include "v8.h" | 7 #include "v8.h" |
8 #include "profile-generator-inl.h" | 8 #include "profile-generator-inl.h" |
9 #include "cctest.h" | 9 #include "cctest.h" |
10 | 10 |
11 namespace i = v8::internal; | 11 namespace i = v8::internal; |
12 | 12 |
13 using i::CodeEntry; | 13 using i::CodeEntry; |
14 using i::CodeMap; | 14 using i::CodeMap; |
15 using i::CpuProfile; | 15 using i::CpuProfile; |
16 using i::CpuProfilesCollection; | 16 using i::CpuProfilesCollection; |
17 using i::ProfileNode; | 17 using i::ProfileNode; |
18 using i::ProfileTree; | 18 using i::ProfileTree; |
19 using i::ProfileGenerator; | 19 using i::ProfileGenerator; |
20 using i::SampleRateCalculator; | 20 using i::SampleRateCalculator; |
21 using i::TickSample; | 21 using i::TickSample; |
| 22 using i::TokenEnumerator; |
22 using i::Vector; | 23 using i::Vector; |
23 | 24 |
24 | 25 |
| 26 namespace v8 { |
| 27 namespace internal { |
| 28 |
| 29 class TokenEnumeratorTester { |
| 30 public: |
| 31 static i::List<bool>* token_removed(TokenEnumerator* te) { |
| 32 return &te->token_removed_; |
| 33 } |
| 34 }; |
| 35 |
| 36 } } // namespace v8::internal |
| 37 |
| 38 TEST(TokenEnumerator) { |
| 39 TokenEnumerator te; |
| 40 CHECK_EQ(CodeEntry::kNoSecurityToken, te.GetTokenId(NULL)); |
| 41 v8::HandleScope hs; |
| 42 v8::Local<v8::String> token1(v8::String::New("1")); |
| 43 CHECK_EQ(0, te.GetTokenId(*v8::Utils::OpenHandle(*token1))); |
| 44 CHECK_EQ(0, te.GetTokenId(*v8::Utils::OpenHandle(*token1))); |
| 45 v8::Local<v8::String> token2(v8::String::New("2")); |
| 46 CHECK_EQ(1, te.GetTokenId(*v8::Utils::OpenHandle(*token2))); |
| 47 CHECK_EQ(1, te.GetTokenId(*v8::Utils::OpenHandle(*token2))); |
| 48 CHECK_EQ(0, te.GetTokenId(*v8::Utils::OpenHandle(*token1))); |
| 49 { |
| 50 v8::HandleScope hs; |
| 51 v8::Local<v8::String> token3(v8::String::New("3")); |
| 52 CHECK_EQ(2, te.GetTokenId(*v8::Utils::OpenHandle(*token3))); |
| 53 CHECK_EQ(1, te.GetTokenId(*v8::Utils::OpenHandle(*token2))); |
| 54 CHECK_EQ(0, te.GetTokenId(*v8::Utils::OpenHandle(*token1))); |
| 55 } |
| 56 CHECK(!i::TokenEnumeratorTester::token_removed(&te)->at(2)); |
| 57 i::Heap::CollectAllGarbage(false); |
| 58 CHECK(i::TokenEnumeratorTester::token_removed(&te)->at(2)); |
| 59 CHECK_EQ(1, te.GetTokenId(*v8::Utils::OpenHandle(*token2))); |
| 60 CHECK_EQ(0, te.GetTokenId(*v8::Utils::OpenHandle(*token1))); |
| 61 } |
| 62 |
| 63 |
25 TEST(ProfileNodeFindOrAddChild) { | 64 TEST(ProfileNodeFindOrAddChild) { |
26 ProfileNode node(NULL, NULL); | 65 ProfileNode node(NULL, NULL); |
27 CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa", "", 0); | 66 CodeEntry entry1( |
| 67 i::Logger::FUNCTION_TAG, "", "aaa", "", 0, CodeEntry::kNoSecurityToken); |
28 ProfileNode* childNode1 = node.FindOrAddChild(&entry1); | 68 ProfileNode* childNode1 = node.FindOrAddChild(&entry1); |
29 CHECK_NE(NULL, childNode1); | 69 CHECK_NE(NULL, childNode1); |
30 CHECK_EQ(childNode1, node.FindOrAddChild(&entry1)); | 70 CHECK_EQ(childNode1, node.FindOrAddChild(&entry1)); |
31 CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb", "", 0); | 71 CodeEntry entry2( |
| 72 i::Logger::FUNCTION_TAG, "", "bbb", "", 0, CodeEntry::kNoSecurityToken); |
32 ProfileNode* childNode2 = node.FindOrAddChild(&entry2); | 73 ProfileNode* childNode2 = node.FindOrAddChild(&entry2); |
33 CHECK_NE(NULL, childNode2); | 74 CHECK_NE(NULL, childNode2); |
34 CHECK_NE(childNode1, childNode2); | 75 CHECK_NE(childNode1, childNode2); |
35 CHECK_EQ(childNode1, node.FindOrAddChild(&entry1)); | 76 CHECK_EQ(childNode1, node.FindOrAddChild(&entry1)); |
36 CHECK_EQ(childNode2, node.FindOrAddChild(&entry2)); | 77 CHECK_EQ(childNode2, node.FindOrAddChild(&entry2)); |
37 CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc", "", 0); | 78 CodeEntry entry3( |
| 79 i::Logger::FUNCTION_TAG, "", "ccc", "", 0, CodeEntry::kNoSecurityToken); |
38 ProfileNode* childNode3 = node.FindOrAddChild(&entry3); | 80 ProfileNode* childNode3 = node.FindOrAddChild(&entry3); |
39 CHECK_NE(NULL, childNode3); | 81 CHECK_NE(NULL, childNode3); |
40 CHECK_NE(childNode1, childNode3); | 82 CHECK_NE(childNode1, childNode3); |
41 CHECK_NE(childNode2, childNode3); | 83 CHECK_NE(childNode2, childNode3); |
42 CHECK_EQ(childNode1, node.FindOrAddChild(&entry1)); | 84 CHECK_EQ(childNode1, node.FindOrAddChild(&entry1)); |
43 CHECK_EQ(childNode2, node.FindOrAddChild(&entry2)); | 85 CHECK_EQ(childNode2, node.FindOrAddChild(&entry2)); |
44 CHECK_EQ(childNode3, node.FindOrAddChild(&entry3)); | 86 CHECK_EQ(childNode3, node.FindOrAddChild(&entry3)); |
45 } | 87 } |
46 | 88 |
47 | 89 |
(...skipping 20 matching lines...) Expand all Loading... |
68 return node; | 110 return node; |
69 } | 111 } |
70 | 112 |
71 private: | 113 private: |
72 const ProfileTree* tree_; | 114 const ProfileTree* tree_; |
73 }; | 115 }; |
74 | 116 |
75 } // namespace | 117 } // namespace |
76 | 118 |
77 TEST(ProfileTreeAddPathFromStart) { | 119 TEST(ProfileTreeAddPathFromStart) { |
78 CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa", "", 0); | 120 CodeEntry entry1( |
79 CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb", "", 0); | 121 i::Logger::FUNCTION_TAG, "", "aaa", "", 0, CodeEntry::kNoSecurityToken); |
80 CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc", "", 0); | 122 CodeEntry entry2( |
| 123 i::Logger::FUNCTION_TAG, "", "bbb", "", 0, CodeEntry::kNoSecurityToken); |
| 124 CodeEntry entry3( |
| 125 i::Logger::FUNCTION_TAG, "", "ccc", "", 0, CodeEntry::kNoSecurityToken); |
81 ProfileTree tree; | 126 ProfileTree tree; |
82 ProfileTreeTestHelper helper(&tree); | 127 ProfileTreeTestHelper helper(&tree); |
83 CHECK_EQ(NULL, helper.Walk(&entry1)); | 128 CHECK_EQ(NULL, helper.Walk(&entry1)); |
84 CHECK_EQ(NULL, helper.Walk(&entry2)); | 129 CHECK_EQ(NULL, helper.Walk(&entry2)); |
85 CHECK_EQ(NULL, helper.Walk(&entry3)); | 130 CHECK_EQ(NULL, helper.Walk(&entry3)); |
86 | 131 |
87 CodeEntry* path[] = {NULL, &entry1, NULL, &entry2, NULL, NULL, &entry3, NULL}; | 132 CodeEntry* path[] = {NULL, &entry1, NULL, &entry2, NULL, NULL, &entry3, NULL}; |
88 Vector<CodeEntry*> path_vec(path, sizeof(path) / sizeof(path[0])); | 133 Vector<CodeEntry*> path_vec(path, sizeof(path) / sizeof(path[0])); |
89 tree.AddPathFromStart(path_vec); | 134 tree.AddPathFromStart(path_vec); |
90 CHECK_EQ(NULL, helper.Walk(&entry2)); | 135 CHECK_EQ(NULL, helper.Walk(&entry2)); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 CHECK_EQ(2, node3->self_ticks()); | 180 CHECK_EQ(2, node3->self_ticks()); |
136 ProfileNode* node4 = helper.Walk(&entry1, &entry2, &entry2); | 181 ProfileNode* node4 = helper.Walk(&entry1, &entry2, &entry2); |
137 CHECK_NE(NULL, node4); | 182 CHECK_NE(NULL, node4); |
138 CHECK_NE(node3, node4); | 183 CHECK_NE(node3, node4); |
139 CHECK_EQ(0, node4->total_ticks()); | 184 CHECK_EQ(0, node4->total_ticks()); |
140 CHECK_EQ(1, node4->self_ticks()); | 185 CHECK_EQ(1, node4->self_ticks()); |
141 } | 186 } |
142 | 187 |
143 | 188 |
144 TEST(ProfileTreeAddPathFromEnd) { | 189 TEST(ProfileTreeAddPathFromEnd) { |
145 CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa", "", 0); | 190 CodeEntry entry1( |
146 CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb", "", 0); | 191 i::Logger::FUNCTION_TAG, "", "aaa", "", 0, CodeEntry::kNoSecurityToken); |
147 CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc", "", 0); | 192 CodeEntry entry2( |
| 193 i::Logger::FUNCTION_TAG, "", "bbb", "", 0, CodeEntry::kNoSecurityToken); |
| 194 CodeEntry entry3( |
| 195 i::Logger::FUNCTION_TAG, "", "ccc", "", 0, CodeEntry::kNoSecurityToken); |
148 ProfileTree tree; | 196 ProfileTree tree; |
149 ProfileTreeTestHelper helper(&tree); | 197 ProfileTreeTestHelper helper(&tree); |
150 CHECK_EQ(NULL, helper.Walk(&entry1)); | 198 CHECK_EQ(NULL, helper.Walk(&entry1)); |
151 CHECK_EQ(NULL, helper.Walk(&entry2)); | 199 CHECK_EQ(NULL, helper.Walk(&entry2)); |
152 CHECK_EQ(NULL, helper.Walk(&entry3)); | 200 CHECK_EQ(NULL, helper.Walk(&entry3)); |
153 | 201 |
154 CodeEntry* path[] = {NULL, &entry3, NULL, &entry2, NULL, NULL, &entry1, NULL}; | 202 CodeEntry* path[] = {NULL, &entry3, NULL, &entry2, NULL, NULL, &entry1, NULL}; |
155 Vector<CodeEntry*> path_vec(path, sizeof(path) / sizeof(path[0])); | 203 Vector<CodeEntry*> path_vec(path, sizeof(path) / sizeof(path[0])); |
156 tree.AddPathFromEnd(path_vec); | 204 tree.AddPathFromEnd(path_vec); |
157 CHECK_EQ(NULL, helper.Walk(&entry2)); | 205 CHECK_EQ(NULL, helper.Walk(&entry2)); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
215 empty_tree.CalculateTotalTicks(); | 263 empty_tree.CalculateTotalTicks(); |
216 CHECK_EQ(0, empty_tree.root()->total_ticks()); | 264 CHECK_EQ(0, empty_tree.root()->total_ticks()); |
217 CHECK_EQ(0, empty_tree.root()->self_ticks()); | 265 CHECK_EQ(0, empty_tree.root()->self_ticks()); |
218 empty_tree.root()->IncrementSelfTicks(); | 266 empty_tree.root()->IncrementSelfTicks(); |
219 CHECK_EQ(0, empty_tree.root()->total_ticks()); | 267 CHECK_EQ(0, empty_tree.root()->total_ticks()); |
220 CHECK_EQ(1, empty_tree.root()->self_ticks()); | 268 CHECK_EQ(1, empty_tree.root()->self_ticks()); |
221 empty_tree.CalculateTotalTicks(); | 269 empty_tree.CalculateTotalTicks(); |
222 CHECK_EQ(1, empty_tree.root()->total_ticks()); | 270 CHECK_EQ(1, empty_tree.root()->total_ticks()); |
223 CHECK_EQ(1, empty_tree.root()->self_ticks()); | 271 CHECK_EQ(1, empty_tree.root()->self_ticks()); |
224 | 272 |
225 CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa", "", 0); | 273 CodeEntry entry1( |
226 CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb", "", 0); | 274 i::Logger::FUNCTION_TAG, "", "aaa", "", 0, CodeEntry::kNoSecurityToken); |
227 CodeEntry* e1_path[] = {&entry1}; | 275 CodeEntry* e1_path[] = {&entry1}; |
228 Vector<CodeEntry*> e1_path_vec( | 276 Vector<CodeEntry*> e1_path_vec( |
229 e1_path, sizeof(e1_path) / sizeof(e1_path[0])); | 277 e1_path, sizeof(e1_path) / sizeof(e1_path[0])); |
| 278 |
| 279 ProfileTree single_child_tree; |
| 280 single_child_tree.AddPathFromStart(e1_path_vec); |
| 281 single_child_tree.root()->IncrementSelfTicks(); |
| 282 CHECK_EQ(0, single_child_tree.root()->total_ticks()); |
| 283 CHECK_EQ(1, single_child_tree.root()->self_ticks()); |
| 284 ProfileTreeTestHelper single_child_helper(&single_child_tree); |
| 285 ProfileNode* node1 = single_child_helper.Walk(&entry1); |
| 286 CHECK_NE(NULL, node1); |
| 287 CHECK_EQ(0, node1->total_ticks()); |
| 288 CHECK_EQ(1, node1->self_ticks()); |
| 289 single_child_tree.CalculateTotalTicks(); |
| 290 CHECK_EQ(2, single_child_tree.root()->total_ticks()); |
| 291 CHECK_EQ(1, single_child_tree.root()->self_ticks()); |
| 292 CHECK_EQ(1, node1->total_ticks()); |
| 293 CHECK_EQ(1, node1->self_ticks()); |
| 294 |
| 295 CodeEntry entry2( |
| 296 i::Logger::FUNCTION_TAG, "", "bbb", "", 0, CodeEntry::kNoSecurityToken); |
230 CodeEntry* e1_e2_path[] = {&entry1, &entry2}; | 297 CodeEntry* e1_e2_path[] = {&entry1, &entry2}; |
231 Vector<CodeEntry*> e1_e2_path_vec( | 298 Vector<CodeEntry*> e1_e2_path_vec( |
232 e1_e2_path, sizeof(e1_e2_path) / sizeof(e1_e2_path[0])); | 299 e1_e2_path, sizeof(e1_e2_path) / sizeof(e1_e2_path[0])); |
233 | 300 |
234 ProfileTree flat_tree; | 301 ProfileTree flat_tree; |
235 ProfileTreeTestHelper flat_helper(&flat_tree); | 302 ProfileTreeTestHelper flat_helper(&flat_tree); |
236 flat_tree.AddPathFromStart(e1_path_vec); | 303 flat_tree.AddPathFromStart(e1_path_vec); |
237 flat_tree.AddPathFromStart(e1_path_vec); | 304 flat_tree.AddPathFromStart(e1_path_vec); |
238 flat_tree.AddPathFromStart(e1_e2_path_vec); | 305 flat_tree.AddPathFromStart(e1_e2_path_vec); |
239 flat_tree.AddPathFromStart(e1_e2_path_vec); | 306 flat_tree.AddPathFromStart(e1_e2_path_vec); |
240 flat_tree.AddPathFromStart(e1_e2_path_vec); | 307 flat_tree.AddPathFromStart(e1_e2_path_vec); |
241 // Results in {root,0,0} -> {entry1,0,2} -> {entry2,0,3} | 308 // Results in {root,0,0} -> {entry1,0,2} -> {entry2,0,3} |
242 CHECK_EQ(0, flat_tree.root()->total_ticks()); | 309 CHECK_EQ(0, flat_tree.root()->total_ticks()); |
243 CHECK_EQ(0, flat_tree.root()->self_ticks()); | 310 CHECK_EQ(0, flat_tree.root()->self_ticks()); |
244 ProfileNode* node1 = flat_helper.Walk(&entry1); | 311 node1 = flat_helper.Walk(&entry1); |
245 CHECK_NE(NULL, node1); | 312 CHECK_NE(NULL, node1); |
246 CHECK_EQ(0, node1->total_ticks()); | 313 CHECK_EQ(0, node1->total_ticks()); |
247 CHECK_EQ(2, node1->self_ticks()); | 314 CHECK_EQ(2, node1->self_ticks()); |
248 ProfileNode* node2 = flat_helper.Walk(&entry1, &entry2); | 315 ProfileNode* node2 = flat_helper.Walk(&entry1, &entry2); |
249 CHECK_NE(NULL, node2); | 316 CHECK_NE(NULL, node2); |
250 CHECK_EQ(0, node2->total_ticks()); | 317 CHECK_EQ(0, node2->total_ticks()); |
251 CHECK_EQ(3, node2->self_ticks()); | 318 CHECK_EQ(3, node2->self_ticks()); |
252 flat_tree.CalculateTotalTicks(); | 319 flat_tree.CalculateTotalTicks(); |
253 // Must calculate {root,5,0} -> {entry1,5,2} -> {entry2,3,3} | 320 // Must calculate {root,5,0} -> {entry1,5,2} -> {entry2,3,3} |
254 CHECK_EQ(5, flat_tree.root()->total_ticks()); | 321 CHECK_EQ(5, flat_tree.root()->total_ticks()); |
255 CHECK_EQ(0, flat_tree.root()->self_ticks()); | 322 CHECK_EQ(0, flat_tree.root()->self_ticks()); |
256 CHECK_EQ(5, node1->total_ticks()); | 323 CHECK_EQ(5, node1->total_ticks()); |
257 CHECK_EQ(2, node1->self_ticks()); | 324 CHECK_EQ(2, node1->self_ticks()); |
258 CHECK_EQ(3, node2->total_ticks()); | 325 CHECK_EQ(3, node2->total_ticks()); |
259 CHECK_EQ(3, node2->self_ticks()); | 326 CHECK_EQ(3, node2->self_ticks()); |
260 | 327 |
261 CodeEntry* e2_path[] = {&entry2}; | 328 CodeEntry* e2_path[] = {&entry2}; |
262 Vector<CodeEntry*> e2_path_vec( | 329 Vector<CodeEntry*> e2_path_vec( |
263 e2_path, sizeof(e2_path) / sizeof(e2_path[0])); | 330 e2_path, sizeof(e2_path) / sizeof(e2_path[0])); |
264 CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc", "", 0); | 331 CodeEntry entry3( |
| 332 i::Logger::FUNCTION_TAG, "", "ccc", "", 0, CodeEntry::kNoSecurityToken); |
265 CodeEntry* e3_path[] = {&entry3}; | 333 CodeEntry* e3_path[] = {&entry3}; |
266 Vector<CodeEntry*> e3_path_vec( | 334 Vector<CodeEntry*> e3_path_vec( |
267 e3_path, sizeof(e3_path) / sizeof(e3_path[0])); | 335 e3_path, sizeof(e3_path) / sizeof(e3_path[0])); |
268 | 336 |
269 ProfileTree wide_tree; | 337 ProfileTree wide_tree; |
270 ProfileTreeTestHelper wide_helper(&wide_tree); | 338 ProfileTreeTestHelper wide_helper(&wide_tree); |
271 wide_tree.AddPathFromStart(e1_path_vec); | 339 wide_tree.AddPathFromStart(e1_path_vec); |
272 wide_tree.AddPathFromStart(e1_path_vec); | 340 wide_tree.AddPathFromStart(e1_path_vec); |
273 wide_tree.AddPathFromStart(e1_e2_path_vec); | 341 wide_tree.AddPathFromStart(e1_e2_path_vec); |
274 wide_tree.AddPathFromStart(e2_path_vec); | 342 wide_tree.AddPathFromStart(e2_path_vec); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
309 CHECK_EQ(2, node1->self_ticks()); | 377 CHECK_EQ(2, node1->self_ticks()); |
310 CHECK_EQ(1, node1_2->total_ticks()); | 378 CHECK_EQ(1, node1_2->total_ticks()); |
311 CHECK_EQ(1, node1_2->self_ticks()); | 379 CHECK_EQ(1, node1_2->self_ticks()); |
312 CHECK_EQ(3, node2->total_ticks()); | 380 CHECK_EQ(3, node2->total_ticks()); |
313 CHECK_EQ(3, node2->self_ticks()); | 381 CHECK_EQ(3, node2->self_ticks()); |
314 CHECK_EQ(4, node3->total_ticks()); | 382 CHECK_EQ(4, node3->total_ticks()); |
315 CHECK_EQ(4, node3->self_ticks()); | 383 CHECK_EQ(4, node3->self_ticks()); |
316 } | 384 } |
317 | 385 |
318 | 386 |
| 387 TEST(ProfileTreeFilteredClone) { |
| 388 ProfileTree source_tree; |
| 389 const int token0 = 0, token1 = 1, token2 = 2; |
| 390 CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa", "", 0, token0); |
| 391 CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb", "", 0, token1); |
| 392 CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc", "", 0, token0); |
| 393 CodeEntry entry4( |
| 394 i::Logger::FUNCTION_TAG, "", "ddd", "", 0, |
| 395 CodeEntry::kInheritsSecurityToken); |
| 396 |
| 397 { |
| 398 CodeEntry* e1_e2_path[] = {&entry1, &entry2}; |
| 399 Vector<CodeEntry*> e1_e2_path_vec( |
| 400 e1_e2_path, sizeof(e1_e2_path) / sizeof(e1_e2_path[0])); |
| 401 source_tree.AddPathFromStart(e1_e2_path_vec); |
| 402 CodeEntry* e2_e4_path[] = {&entry2, &entry4}; |
| 403 Vector<CodeEntry*> e2_e4_path_vec( |
| 404 e2_e4_path, sizeof(e2_e4_path) / sizeof(e2_e4_path[0])); |
| 405 source_tree.AddPathFromStart(e2_e4_path_vec); |
| 406 CodeEntry* e3_e1_path[] = {&entry3, &entry1}; |
| 407 Vector<CodeEntry*> e3_e1_path_vec( |
| 408 e3_e1_path, sizeof(e3_e1_path) / sizeof(e3_e1_path[0])); |
| 409 source_tree.AddPathFromStart(e3_e1_path_vec); |
| 410 CodeEntry* e3_e2_path[] = {&entry3, &entry2}; |
| 411 Vector<CodeEntry*> e3_e2_path_vec( |
| 412 e3_e2_path, sizeof(e3_e2_path) / sizeof(e3_e2_path[0])); |
| 413 source_tree.AddPathFromStart(e3_e2_path_vec); |
| 414 source_tree.CalculateTotalTicks(); |
| 415 // Results in -> {entry1,0,1,0} -> {entry2,1,1,1} |
| 416 // {root,0,4,-1} -> {entry2,0,1,1} -> {entry4,1,1,inherits} |
| 417 // -> {entry3,0,2,0} -> {entry1,1,1,0} |
| 418 // -> {entry2,1,1,1} |
| 419 CHECK_EQ(4, source_tree.root()->total_ticks()); |
| 420 CHECK_EQ(0, source_tree.root()->self_ticks()); |
| 421 } |
| 422 |
| 423 { |
| 424 ProfileTree token0_tree; |
| 425 token0_tree.FilteredClone(&source_tree, token0); |
| 426 // Should be -> {entry1,1,1,0} |
| 427 // {root,1,4,-1} -> {entry3,1,2,0} -> {entry1,1,1,0} |
| 428 // [self ticks from filtered nodes are attributed to their parents] |
| 429 CHECK_EQ(4, token0_tree.root()->total_ticks()); |
| 430 CHECK_EQ(1, token0_tree.root()->self_ticks()); |
| 431 ProfileTreeTestHelper token0_helper(&token0_tree); |
| 432 ProfileNode* node1 = token0_helper.Walk(&entry1); |
| 433 CHECK_NE(NULL, node1); |
| 434 CHECK_EQ(1, node1->total_ticks()); |
| 435 CHECK_EQ(1, node1->self_ticks()); |
| 436 CHECK_EQ(NULL, token0_helper.Walk(&entry2)); |
| 437 ProfileNode* node3 = token0_helper.Walk(&entry3); |
| 438 CHECK_NE(NULL, node3); |
| 439 CHECK_EQ(2, node3->total_ticks()); |
| 440 CHECK_EQ(1, node3->self_ticks()); |
| 441 ProfileNode* node3_1 = token0_helper.Walk(&entry3, &entry1); |
| 442 CHECK_NE(NULL, node3_1); |
| 443 CHECK_EQ(1, node3_1->total_ticks()); |
| 444 CHECK_EQ(1, node3_1->self_ticks()); |
| 445 CHECK_EQ(NULL, token0_helper.Walk(&entry3, &entry2)); |
| 446 } |
| 447 |
| 448 { |
| 449 ProfileTree token1_tree; |
| 450 token1_tree.FilteredClone(&source_tree, token1); |
| 451 // Should be |
| 452 // {root,1,4,-1} -> {entry2,2,3,1} -> {entry4,1,1,inherits} |
| 453 // [child nodes referring to the same entry get merged and |
| 454 // their self times summed up] |
| 455 CHECK_EQ(4, token1_tree.root()->total_ticks()); |
| 456 CHECK_EQ(1, token1_tree.root()->self_ticks()); |
| 457 ProfileTreeTestHelper token1_helper(&token1_tree); |
| 458 CHECK_EQ(NULL, token1_helper.Walk(&entry1)); |
| 459 CHECK_EQ(NULL, token1_helper.Walk(&entry3)); |
| 460 ProfileNode* node2 = token1_helper.Walk(&entry2); |
| 461 CHECK_NE(NULL, node2); |
| 462 CHECK_EQ(3, node2->total_ticks()); |
| 463 CHECK_EQ(2, node2->self_ticks()); |
| 464 ProfileNode* node2_4 = token1_helper.Walk(&entry2, &entry4); |
| 465 CHECK_NE(NULL, node2_4); |
| 466 CHECK_EQ(1, node2_4->total_ticks()); |
| 467 CHECK_EQ(1, node2_4->self_ticks()); |
| 468 } |
| 469 |
| 470 { |
| 471 ProfileTree token2_tree; |
| 472 token2_tree.FilteredClone(&source_tree, token2); |
| 473 // Should be |
| 474 // {root,4,4,-1} |
| 475 // [no nodes, all ticks get migrated into root node] |
| 476 CHECK_EQ(4, token2_tree.root()->total_ticks()); |
| 477 CHECK_EQ(4, token2_tree.root()->self_ticks()); |
| 478 ProfileTreeTestHelper token2_helper(&token2_tree); |
| 479 CHECK_EQ(NULL, token2_helper.Walk(&entry1)); |
| 480 CHECK_EQ(NULL, token2_helper.Walk(&entry2)); |
| 481 CHECK_EQ(NULL, token2_helper.Walk(&entry3)); |
| 482 } |
| 483 } |
| 484 |
| 485 |
319 static inline i::Address ToAddress(int n) { | 486 static inline i::Address ToAddress(int n) { |
320 return reinterpret_cast<i::Address>(n); | 487 return reinterpret_cast<i::Address>(n); |
321 } | 488 } |
322 | 489 |
323 TEST(CodeMapAddCode) { | 490 TEST(CodeMapAddCode) { |
324 CodeMap code_map; | 491 CodeMap code_map; |
325 CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa", "", 0); | 492 CodeEntry entry1( |
326 CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb", "", 0); | 493 i::Logger::FUNCTION_TAG, "", "aaa", "", 0, CodeEntry::kNoSecurityToken); |
327 CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc", "", 0); | 494 CodeEntry entry2( |
328 CodeEntry entry4(i::Logger::FUNCTION_TAG, "", "ddd", "", 0); | 495 i::Logger::FUNCTION_TAG, "", "bbb", "", 0, CodeEntry::kNoSecurityToken); |
| 496 CodeEntry entry3( |
| 497 i::Logger::FUNCTION_TAG, "", "ccc", "", 0, CodeEntry::kNoSecurityToken); |
| 498 CodeEntry entry4( |
| 499 i::Logger::FUNCTION_TAG, "", "ddd", "", 0, CodeEntry::kNoSecurityToken); |
329 code_map.AddCode(ToAddress(0x1500), &entry1, 0x200); | 500 code_map.AddCode(ToAddress(0x1500), &entry1, 0x200); |
330 code_map.AddCode(ToAddress(0x1700), &entry2, 0x100); | 501 code_map.AddCode(ToAddress(0x1700), &entry2, 0x100); |
331 code_map.AddCode(ToAddress(0x1900), &entry3, 0x50); | 502 code_map.AddCode(ToAddress(0x1900), &entry3, 0x50); |
332 code_map.AddCode(ToAddress(0x1950), &entry4, 0x10); | 503 code_map.AddCode(ToAddress(0x1950), &entry4, 0x10); |
333 CHECK_EQ(NULL, code_map.FindEntry(0)); | 504 CHECK_EQ(NULL, code_map.FindEntry(0)); |
334 CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1500 - 1))); | 505 CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1500 - 1))); |
335 CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1500))); | 506 CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1500))); |
336 CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1500 + 0x100))); | 507 CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1500 + 0x100))); |
337 CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1500 + 0x200 - 1))); | 508 CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1500 + 0x200 - 1))); |
338 CHECK_EQ(&entry2, code_map.FindEntry(ToAddress(0x1700))); | 509 CHECK_EQ(&entry2, code_map.FindEntry(ToAddress(0x1700))); |
339 CHECK_EQ(&entry2, code_map.FindEntry(ToAddress(0x1700 + 0x50))); | 510 CHECK_EQ(&entry2, code_map.FindEntry(ToAddress(0x1700 + 0x50))); |
340 CHECK_EQ(&entry2, code_map.FindEntry(ToAddress(0x1700 + 0x100 - 1))); | 511 CHECK_EQ(&entry2, code_map.FindEntry(ToAddress(0x1700 + 0x100 - 1))); |
341 CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1700 + 0x100))); | 512 CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1700 + 0x100))); |
342 CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1900 - 1))); | 513 CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1900 - 1))); |
343 CHECK_EQ(&entry3, code_map.FindEntry(ToAddress(0x1900))); | 514 CHECK_EQ(&entry3, code_map.FindEntry(ToAddress(0x1900))); |
344 CHECK_EQ(&entry3, code_map.FindEntry(ToAddress(0x1900 + 0x28))); | 515 CHECK_EQ(&entry3, code_map.FindEntry(ToAddress(0x1900 + 0x28))); |
345 CHECK_EQ(&entry4, code_map.FindEntry(ToAddress(0x1950))); | 516 CHECK_EQ(&entry4, code_map.FindEntry(ToAddress(0x1950))); |
346 CHECK_EQ(&entry4, code_map.FindEntry(ToAddress(0x1950 + 0x7))); | 517 CHECK_EQ(&entry4, code_map.FindEntry(ToAddress(0x1950 + 0x7))); |
347 CHECK_EQ(&entry4, code_map.FindEntry(ToAddress(0x1950 + 0x10 - 1))); | 518 CHECK_EQ(&entry4, code_map.FindEntry(ToAddress(0x1950 + 0x10 - 1))); |
348 CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1950 + 0x10))); | 519 CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1950 + 0x10))); |
349 CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0xFFFFFFFF))); | 520 CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0xFFFFFFFF))); |
350 } | 521 } |
351 | 522 |
352 | 523 |
353 TEST(CodeMapMoveAndDeleteCode) { | 524 TEST(CodeMapMoveAndDeleteCode) { |
354 CodeMap code_map; | 525 CodeMap code_map; |
355 CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa", "", 0); | 526 CodeEntry entry1( |
356 CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb", "", 0); | 527 i::Logger::FUNCTION_TAG, "", "aaa", "", 0, CodeEntry::kNoSecurityToken); |
| 528 CodeEntry entry2( |
| 529 i::Logger::FUNCTION_TAG, "", "bbb", "", 0, CodeEntry::kNoSecurityToken); |
357 code_map.AddCode(ToAddress(0x1500), &entry1, 0x200); | 530 code_map.AddCode(ToAddress(0x1500), &entry1, 0x200); |
358 code_map.AddCode(ToAddress(0x1700), &entry2, 0x100); | 531 code_map.AddCode(ToAddress(0x1700), &entry2, 0x100); |
359 CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1500))); | 532 CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1500))); |
360 CHECK_EQ(&entry2, code_map.FindEntry(ToAddress(0x1700))); | 533 CHECK_EQ(&entry2, code_map.FindEntry(ToAddress(0x1700))); |
361 code_map.MoveCode(ToAddress(0x1500), ToAddress(0x1800)); | 534 code_map.MoveCode(ToAddress(0x1500), ToAddress(0x1800)); |
362 CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1500))); | 535 CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1500))); |
363 CHECK_EQ(&entry2, code_map.FindEntry(ToAddress(0x1700))); | 536 CHECK_EQ(&entry2, code_map.FindEntry(ToAddress(0x1700))); |
364 CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1800))); | 537 CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1800))); |
365 code_map.DeleteCode(ToAddress(0x1700)); | 538 code_map.DeleteCode(ToAddress(0x1700)); |
366 CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1700))); | 539 CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1700))); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
418 sample2.frames_count = 3; | 591 sample2.frames_count = 3; |
419 generator.RecordTickSample(sample2); | 592 generator.RecordTickSample(sample2); |
420 TickSample sample3; | 593 TickSample sample3; |
421 sample3.pc = ToAddress(0x1510); | 594 sample3.pc = ToAddress(0x1510); |
422 sample3.function = ToAddress(0x1500); | 595 sample3.function = ToAddress(0x1500); |
423 sample3.stack[0] = ToAddress(0x1910); | 596 sample3.stack[0] = ToAddress(0x1910); |
424 sample3.stack[1] = ToAddress(0x1610); | 597 sample3.stack[1] = ToAddress(0x1610); |
425 sample3.frames_count = 2; | 598 sample3.frames_count = 2; |
426 generator.RecordTickSample(sample3); | 599 generator.RecordTickSample(sample3); |
427 | 600 |
428 CpuProfile* profile = profiles.StopProfiling("", 1); | 601 CpuProfile* profile = |
| 602 profiles.StopProfiling(CodeEntry::kNoSecurityToken, "", 1); |
429 CHECK_NE(NULL, profile); | 603 CHECK_NE(NULL, profile); |
430 ProfileTreeTestHelper top_down_test_helper(profile->top_down()); | 604 ProfileTreeTestHelper top_down_test_helper(profile->top_down()); |
431 CHECK_EQ(NULL, top_down_test_helper.Walk(entry2)); | 605 CHECK_EQ(NULL, top_down_test_helper.Walk(entry2)); |
432 CHECK_EQ(NULL, top_down_test_helper.Walk(entry3)); | 606 CHECK_EQ(NULL, top_down_test_helper.Walk(entry3)); |
433 ProfileNode* node1 = top_down_test_helper.Walk(entry1); | 607 ProfileNode* node1 = top_down_test_helper.Walk(entry1); |
434 CHECK_NE(NULL, node1); | 608 CHECK_NE(NULL, node1); |
435 CHECK_EQ(entry1, node1->entry()); | 609 CHECK_EQ(entry1, node1->entry()); |
436 ProfileNode* node2 = top_down_test_helper.Walk(entry1, entry1); | 610 ProfileNode* node2 = top_down_test_helper.Walk(entry1, entry1); |
437 CHECK_NE(NULL, node2); | 611 CHECK_NE(NULL, node2); |
438 CHECK_EQ(entry1, node2->entry()); | 612 CHECK_EQ(entry1, node2->entry()); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
488 calc3.UpdateMeasurements(time); | 662 calc3.UpdateMeasurements(time); |
489 // (1.0 + 0.5) / 2 | 663 // (1.0 + 0.5) / 2 |
490 CHECK_EQ(kSamplingIntervalMs * 0.75, calc3.ticks_per_ms()); | 664 CHECK_EQ(kSamplingIntervalMs * 0.75, calc3.ticks_per_ms()); |
491 time += SampleRateCalculator::kWallTimeQueryIntervalMs * 1.5; | 665 time += SampleRateCalculator::kWallTimeQueryIntervalMs * 1.5; |
492 calc3.UpdateMeasurements(time); | 666 calc3.UpdateMeasurements(time); |
493 // (1.0 + 0.5 + 0.5) / 3 | 667 // (1.0 + 0.5 + 0.5) / 3 |
494 CHECK_EQ(kSamplingIntervalMs * 0.66666, calc3.ticks_per_ms()); | 668 CHECK_EQ(kSamplingIntervalMs * 0.66666, calc3.ticks_per_ms()); |
495 } | 669 } |
496 | 670 |
497 #endif // ENABLE_LOGGING_AND_PROFILING | 671 #endif // ENABLE_LOGGING_AND_PROFILING |
OLD | NEW |