v8  3.11.10(node0.8.26)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
test-profile-generator.cc
Go to the documentation of this file.
1 // Copyright 2010 the V8 project authors. All rights reserved.
2 //
3 // Tests of profiles generator and utilities.
4 
5 #include "v8.h"
7 #include "cctest.h"
8 #include "../include/v8-profiler.h"
9 
10 using i::CodeEntry;
11 using i::CodeMap;
12 using i::CpuProfile;
13 using i::CpuProfiler;
15 using i::ProfileNode;
16 using i::ProfileTree;
19 using i::TickSample;
20 using i::TokenEnumerator;
21 using i::Vector;
22 
23 
24 namespace v8 {
25 namespace internal {
26 
28  public:
30  return &te->token_removed_;
31  }
32 };
33 
34 } } // namespace v8::internal
35 
36 TEST(TokenEnumerator) {
37  TokenEnumerator te;
38  CHECK_EQ(TokenEnumerator::kNoSecurityToken, te.GetTokenId(NULL));
41  CHECK_EQ(0, te.GetTokenId(*v8::Utils::OpenHandle(*token1)));
42  CHECK_EQ(0, te.GetTokenId(*v8::Utils::OpenHandle(*token1)));
44  CHECK_EQ(1, te.GetTokenId(*v8::Utils::OpenHandle(*token2)));
45  CHECK_EQ(1, te.GetTokenId(*v8::Utils::OpenHandle(*token2)));
46  CHECK_EQ(0, te.GetTokenId(*v8::Utils::OpenHandle(*token1)));
47  {
50  CHECK_EQ(2, te.GetTokenId(*v8::Utils::OpenHandle(*token3)));
51  CHECK_EQ(1, te.GetTokenId(*v8::Utils::OpenHandle(*token2)));
52  CHECK_EQ(0, te.GetTokenId(*v8::Utils::OpenHandle(*token1)));
53  }
55  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
57  CHECK_EQ(1, te.GetTokenId(*v8::Utils::OpenHandle(*token2)));
58  CHECK_EQ(0, te.GetTokenId(*v8::Utils::OpenHandle(*token1)));
59 }
60 
61 
62 TEST(ProfileNodeFindOrAddChild) {
63  ProfileNode node(NULL, NULL);
64  CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa", "", 0,
65  TokenEnumerator::kNoSecurityToken);
66  ProfileNode* childNode1 = node.FindOrAddChild(&entry1);
67  CHECK_NE(NULL, childNode1);
68  CHECK_EQ(childNode1, node.FindOrAddChild(&entry1));
69  CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb", "", 0,
70  TokenEnumerator::kNoSecurityToken);
71  ProfileNode* childNode2 = node.FindOrAddChild(&entry2);
72  CHECK_NE(NULL, childNode2);
73  CHECK_NE(childNode1, childNode2);
74  CHECK_EQ(childNode1, node.FindOrAddChild(&entry1));
75  CHECK_EQ(childNode2, node.FindOrAddChild(&entry2));
76  CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc", "", 0,
77  TokenEnumerator::kNoSecurityToken);
78  ProfileNode* childNode3 = node.FindOrAddChild(&entry3);
79  CHECK_NE(NULL, childNode3);
80  CHECK_NE(childNode1, childNode3);
81  CHECK_NE(childNode2, childNode3);
82  CHECK_EQ(childNode1, node.FindOrAddChild(&entry1));
83  CHECK_EQ(childNode2, node.FindOrAddChild(&entry2));
84  CHECK_EQ(childNode3, node.FindOrAddChild(&entry3));
85 }
86 
87 
88 TEST(ProfileNodeFindOrAddChildForSameFunction) {
89  const char* empty = "";
90  const char* aaa = "aaa";
91  ProfileNode node(NULL, NULL);
92  CodeEntry entry1(i::Logger::FUNCTION_TAG, empty, aaa, empty, 0,
93  TokenEnumerator::kNoSecurityToken);
94  ProfileNode* childNode1 = node.FindOrAddChild(&entry1);
95  CHECK_NE(NULL, childNode1);
96  CHECK_EQ(childNode1, node.FindOrAddChild(&entry1));
97  // The same function again.
98  CodeEntry entry2(i::Logger::FUNCTION_TAG, empty, aaa, empty, 0,
99  TokenEnumerator::kNoSecurityToken);
100  CHECK_EQ(childNode1, node.FindOrAddChild(&entry2));
101  // Now with a different security token.
102  CodeEntry entry3(i::Logger::FUNCTION_TAG, empty, aaa, empty, 0,
103  TokenEnumerator::kNoSecurityToken + 1);
104  CHECK_EQ(childNode1, node.FindOrAddChild(&entry3));
105 }
106 
107 
108 namespace {
109 
110 class ProfileTreeTestHelper {
111  public:
112  explicit ProfileTreeTestHelper(const ProfileTree* tree)
113  : tree_(tree) { }
114 
115  ProfileNode* Walk(CodeEntry* entry1,
116  CodeEntry* entry2 = NULL,
117  CodeEntry* entry3 = NULL) {
118  ProfileNode* node = tree_->root();
119  node = node->FindChild(entry1);
120  if (node == NULL) return NULL;
121  if (entry2 != NULL) {
122  node = node->FindChild(entry2);
123  if (node == NULL) return NULL;
124  }
125  if (entry3 != NULL) {
126  node = node->FindChild(entry3);
127  }
128  return node;
129  }
130 
131  private:
132  const ProfileTree* tree_;
133 };
134 
135 } // namespace
136 
137 TEST(ProfileTreeAddPathFromStart) {
138  CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa", "", 0,
139  TokenEnumerator::kNoSecurityToken);
140  CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb", "", 0,
141  TokenEnumerator::kNoSecurityToken);
142  CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc", "", 0,
143  TokenEnumerator::kNoSecurityToken);
144  ProfileTree tree;
145  ProfileTreeTestHelper helper(&tree);
146  CHECK_EQ(NULL, helper.Walk(&entry1));
147  CHECK_EQ(NULL, helper.Walk(&entry2));
148  CHECK_EQ(NULL, helper.Walk(&entry3));
149 
150  CodeEntry* path[] = {NULL, &entry1, NULL, &entry2, NULL, NULL, &entry3, NULL};
151  Vector<CodeEntry*> path_vec(path, sizeof(path) / sizeof(path[0]));
152  tree.AddPathFromStart(path_vec);
153  CHECK_EQ(NULL, helper.Walk(&entry2));
154  CHECK_EQ(NULL, helper.Walk(&entry3));
155  ProfileNode* node1 = helper.Walk(&entry1);
156  CHECK_NE(NULL, node1);
157  CHECK_EQ(0, node1->total_ticks());
158  CHECK_EQ(0, node1->self_ticks());
159  CHECK_EQ(NULL, helper.Walk(&entry1, &entry1));
160  CHECK_EQ(NULL, helper.Walk(&entry1, &entry3));
161  ProfileNode* node2 = helper.Walk(&entry1, &entry2);
162  CHECK_NE(NULL, node2);
163  CHECK_NE(node1, node2);
164  CHECK_EQ(0, node2->total_ticks());
165  CHECK_EQ(0, node2->self_ticks());
166  CHECK_EQ(NULL, helper.Walk(&entry1, &entry2, &entry1));
167  CHECK_EQ(NULL, helper.Walk(&entry1, &entry2, &entry2));
168  ProfileNode* node3 = helper.Walk(&entry1, &entry2, &entry3);
169  CHECK_NE(NULL, node3);
170  CHECK_NE(node1, node3);
171  CHECK_NE(node2, node3);
172  CHECK_EQ(0, node3->total_ticks());
173  CHECK_EQ(1, node3->self_ticks());
174 
175  tree.AddPathFromStart(path_vec);
176  CHECK_EQ(node1, helper.Walk(&entry1));
177  CHECK_EQ(node2, helper.Walk(&entry1, &entry2));
178  CHECK_EQ(node3, helper.Walk(&entry1, &entry2, &entry3));
179  CHECK_EQ(0, node1->total_ticks());
180  CHECK_EQ(0, node1->self_ticks());
181  CHECK_EQ(0, node2->total_ticks());
182  CHECK_EQ(0, node2->self_ticks());
183  CHECK_EQ(0, node3->total_ticks());
184  CHECK_EQ(2, node3->self_ticks());
185 
186  CodeEntry* path2[] = {&entry1, &entry2, &entry2};
187  Vector<CodeEntry*> path2_vec(path2, sizeof(path2) / sizeof(path2[0]));
188  tree.AddPathFromStart(path2_vec);
189  CHECK_EQ(NULL, helper.Walk(&entry2));
190  CHECK_EQ(NULL, helper.Walk(&entry3));
191  CHECK_EQ(node1, helper.Walk(&entry1));
192  CHECK_EQ(NULL, helper.Walk(&entry1, &entry1));
193  CHECK_EQ(NULL, helper.Walk(&entry1, &entry3));
194  CHECK_EQ(node2, helper.Walk(&entry1, &entry2));
195  CHECK_EQ(NULL, helper.Walk(&entry1, &entry2, &entry1));
196  CHECK_EQ(node3, helper.Walk(&entry1, &entry2, &entry3));
197  CHECK_EQ(0, node3->total_ticks());
198  CHECK_EQ(2, node3->self_ticks());
199  ProfileNode* node4 = helper.Walk(&entry1, &entry2, &entry2);
200  CHECK_NE(NULL, node4);
201  CHECK_NE(node3, node4);
202  CHECK_EQ(0, node4->total_ticks());
203  CHECK_EQ(1, node4->self_ticks());
204 }
205 
206 
207 TEST(ProfileTreeAddPathFromEnd) {
208  CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa", "", 0,
209  TokenEnumerator::kNoSecurityToken);
210  CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb", "", 0,
211  TokenEnumerator::kNoSecurityToken);
212  CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc", "", 0,
213  TokenEnumerator::kNoSecurityToken);
214  ProfileTree tree;
215  ProfileTreeTestHelper helper(&tree);
216  CHECK_EQ(NULL, helper.Walk(&entry1));
217  CHECK_EQ(NULL, helper.Walk(&entry2));
218  CHECK_EQ(NULL, helper.Walk(&entry3));
219 
220  CodeEntry* path[] = {NULL, &entry3, NULL, &entry2, NULL, NULL, &entry1, NULL};
221  Vector<CodeEntry*> path_vec(path, sizeof(path) / sizeof(path[0]));
222  tree.AddPathFromEnd(path_vec);
223  CHECK_EQ(NULL, helper.Walk(&entry2));
224  CHECK_EQ(NULL, helper.Walk(&entry3));
225  ProfileNode* node1 = helper.Walk(&entry1);
226  CHECK_NE(NULL, node1);
227  CHECK_EQ(0, node1->total_ticks());
228  CHECK_EQ(0, node1->self_ticks());
229  CHECK_EQ(NULL, helper.Walk(&entry1, &entry1));
230  CHECK_EQ(NULL, helper.Walk(&entry1, &entry3));
231  ProfileNode* node2 = helper.Walk(&entry1, &entry2);
232  CHECK_NE(NULL, node2);
233  CHECK_NE(node1, node2);
234  CHECK_EQ(0, node2->total_ticks());
235  CHECK_EQ(0, node2->self_ticks());
236  CHECK_EQ(NULL, helper.Walk(&entry1, &entry2, &entry1));
237  CHECK_EQ(NULL, helper.Walk(&entry1, &entry2, &entry2));
238  ProfileNode* node3 = helper.Walk(&entry1, &entry2, &entry3);
239  CHECK_NE(NULL, node3);
240  CHECK_NE(node1, node3);
241  CHECK_NE(node2, node3);
242  CHECK_EQ(0, node3->total_ticks());
243  CHECK_EQ(1, node3->self_ticks());
244 
245  tree.AddPathFromEnd(path_vec);
246  CHECK_EQ(node1, helper.Walk(&entry1));
247  CHECK_EQ(node2, helper.Walk(&entry1, &entry2));
248  CHECK_EQ(node3, helper.Walk(&entry1, &entry2, &entry3));
249  CHECK_EQ(0, node1->total_ticks());
250  CHECK_EQ(0, node1->self_ticks());
251  CHECK_EQ(0, node2->total_ticks());
252  CHECK_EQ(0, node2->self_ticks());
253  CHECK_EQ(0, node3->total_ticks());
254  CHECK_EQ(2, node3->self_ticks());
255 
256  CodeEntry* path2[] = {&entry2, &entry2, &entry1};
257  Vector<CodeEntry*> path2_vec(path2, sizeof(path2) / sizeof(path2[0]));
258  tree.AddPathFromEnd(path2_vec);
259  CHECK_EQ(NULL, helper.Walk(&entry2));
260  CHECK_EQ(NULL, helper.Walk(&entry3));
261  CHECK_EQ(node1, helper.Walk(&entry1));
262  CHECK_EQ(NULL, helper.Walk(&entry1, &entry1));
263  CHECK_EQ(NULL, helper.Walk(&entry1, &entry3));
264  CHECK_EQ(node2, helper.Walk(&entry1, &entry2));
265  CHECK_EQ(NULL, helper.Walk(&entry1, &entry2, &entry1));
266  CHECK_EQ(node3, helper.Walk(&entry1, &entry2, &entry3));
267  CHECK_EQ(0, node3->total_ticks());
268  CHECK_EQ(2, node3->self_ticks());
269  ProfileNode* node4 = helper.Walk(&entry1, &entry2, &entry2);
270  CHECK_NE(NULL, node4);
271  CHECK_NE(node3, node4);
272  CHECK_EQ(0, node4->total_ticks());
273  CHECK_EQ(1, node4->self_ticks());
274 }
275 
276 
277 TEST(ProfileTreeCalculateTotalTicks) {
278  ProfileTree empty_tree;
279  CHECK_EQ(0, empty_tree.root()->total_ticks());
280  CHECK_EQ(0, empty_tree.root()->self_ticks());
281  empty_tree.CalculateTotalTicks();
282  CHECK_EQ(0, empty_tree.root()->total_ticks());
283  CHECK_EQ(0, empty_tree.root()->self_ticks());
284  empty_tree.root()->IncrementSelfTicks();
285  CHECK_EQ(0, empty_tree.root()->total_ticks());
286  CHECK_EQ(1, empty_tree.root()->self_ticks());
287  empty_tree.CalculateTotalTicks();
288  CHECK_EQ(1, empty_tree.root()->total_ticks());
289  CHECK_EQ(1, empty_tree.root()->self_ticks());
290 
291  CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa", "", 0,
292  TokenEnumerator::kNoSecurityToken);
293  CodeEntry* e1_path[] = {&entry1};
294  Vector<CodeEntry*> e1_path_vec(
295  e1_path, sizeof(e1_path) / sizeof(e1_path[0]));
296 
297  ProfileTree single_child_tree;
298  single_child_tree.AddPathFromStart(e1_path_vec);
299  single_child_tree.root()->IncrementSelfTicks();
300  CHECK_EQ(0, single_child_tree.root()->total_ticks());
301  CHECK_EQ(1, single_child_tree.root()->self_ticks());
302  ProfileTreeTestHelper single_child_helper(&single_child_tree);
303  ProfileNode* node1 = single_child_helper.Walk(&entry1);
304  CHECK_NE(NULL, node1);
305  CHECK_EQ(0, node1->total_ticks());
306  CHECK_EQ(1, node1->self_ticks());
307  single_child_tree.CalculateTotalTicks();
308  CHECK_EQ(2, single_child_tree.root()->total_ticks());
309  CHECK_EQ(1, single_child_tree.root()->self_ticks());
310  CHECK_EQ(1, node1->total_ticks());
311  CHECK_EQ(1, node1->self_ticks());
312 
313  CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb", "", 0,
314  TokenEnumerator::kNoSecurityToken);
315  CodeEntry* e1_e2_path[] = {&entry1, &entry2};
316  Vector<CodeEntry*> e1_e2_path_vec(
317  e1_e2_path, sizeof(e1_e2_path) / sizeof(e1_e2_path[0]));
318 
319  ProfileTree flat_tree;
320  ProfileTreeTestHelper flat_helper(&flat_tree);
321  flat_tree.AddPathFromStart(e1_path_vec);
322  flat_tree.AddPathFromStart(e1_path_vec);
323  flat_tree.AddPathFromStart(e1_e2_path_vec);
324  flat_tree.AddPathFromStart(e1_e2_path_vec);
325  flat_tree.AddPathFromStart(e1_e2_path_vec);
326  // Results in {root,0,0} -> {entry1,0,2} -> {entry2,0,3}
327  CHECK_EQ(0, flat_tree.root()->total_ticks());
328  CHECK_EQ(0, flat_tree.root()->self_ticks());
329  node1 = flat_helper.Walk(&entry1);
330  CHECK_NE(NULL, node1);
331  CHECK_EQ(0, node1->total_ticks());
332  CHECK_EQ(2, node1->self_ticks());
333  ProfileNode* node2 = flat_helper.Walk(&entry1, &entry2);
334  CHECK_NE(NULL, node2);
335  CHECK_EQ(0, node2->total_ticks());
336  CHECK_EQ(3, node2->self_ticks());
337  flat_tree.CalculateTotalTicks();
338  // Must calculate {root,5,0} -> {entry1,5,2} -> {entry2,3,3}
339  CHECK_EQ(5, flat_tree.root()->total_ticks());
340  CHECK_EQ(0, flat_tree.root()->self_ticks());
341  CHECK_EQ(5, node1->total_ticks());
342  CHECK_EQ(2, node1->self_ticks());
343  CHECK_EQ(3, node2->total_ticks());
344  CHECK_EQ(3, node2->self_ticks());
345 
346  CodeEntry* e2_path[] = {&entry2};
347  Vector<CodeEntry*> e2_path_vec(
348  e2_path, sizeof(e2_path) / sizeof(e2_path[0]));
349  CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc", "", 0,
350  TokenEnumerator::kNoSecurityToken);
351  CodeEntry* e3_path[] = {&entry3};
352  Vector<CodeEntry*> e3_path_vec(
353  e3_path, sizeof(e3_path) / sizeof(e3_path[0]));
354 
355  ProfileTree wide_tree;
356  ProfileTreeTestHelper wide_helper(&wide_tree);
357  wide_tree.AddPathFromStart(e1_path_vec);
358  wide_tree.AddPathFromStart(e1_path_vec);
359  wide_tree.AddPathFromStart(e1_e2_path_vec);
360  wide_tree.AddPathFromStart(e2_path_vec);
361  wide_tree.AddPathFromStart(e2_path_vec);
362  wide_tree.AddPathFromStart(e2_path_vec);
363  wide_tree.AddPathFromStart(e3_path_vec);
364  wide_tree.AddPathFromStart(e3_path_vec);
365  wide_tree.AddPathFromStart(e3_path_vec);
366  wide_tree.AddPathFromStart(e3_path_vec);
367  // Results in -> {entry1,0,2} -> {entry2,0,1}
368  // {root,0,0} -> {entry2,0,3}
369  // -> {entry3,0,4}
370  CHECK_EQ(0, wide_tree.root()->total_ticks());
371  CHECK_EQ(0, wide_tree.root()->self_ticks());
372  node1 = wide_helper.Walk(&entry1);
373  CHECK_NE(NULL, node1);
374  CHECK_EQ(0, node1->total_ticks());
375  CHECK_EQ(2, node1->self_ticks());
376  ProfileNode* node1_2 = wide_helper.Walk(&entry1, &entry2);
377  CHECK_NE(NULL, node1_2);
378  CHECK_EQ(0, node1_2->total_ticks());
379  CHECK_EQ(1, node1_2->self_ticks());
380  node2 = wide_helper.Walk(&entry2);
381  CHECK_NE(NULL, node2);
382  CHECK_EQ(0, node2->total_ticks());
383  CHECK_EQ(3, node2->self_ticks());
384  ProfileNode* node3 = wide_helper.Walk(&entry3);
385  CHECK_NE(NULL, node3);
386  CHECK_EQ(0, node3->total_ticks());
387  CHECK_EQ(4, node3->self_ticks());
388  wide_tree.CalculateTotalTicks();
389  // Calculates -> {entry1,3,2} -> {entry2,1,1}
390  // {root,10,0} -> {entry2,3,3}
391  // -> {entry3,4,4}
392  CHECK_EQ(10, wide_tree.root()->total_ticks());
393  CHECK_EQ(0, wide_tree.root()->self_ticks());
394  CHECK_EQ(3, node1->total_ticks());
395  CHECK_EQ(2, node1->self_ticks());
396  CHECK_EQ(1, node1_2->total_ticks());
397  CHECK_EQ(1, node1_2->self_ticks());
398  CHECK_EQ(3, node2->total_ticks());
399  CHECK_EQ(3, node2->self_ticks());
400  CHECK_EQ(4, node3->total_ticks());
401  CHECK_EQ(4, node3->self_ticks());
402 }
403 
404 
405 TEST(ProfileTreeFilteredClone) {
406  ProfileTree source_tree;
407  const int token0 = 0, token1 = 1, token2 = 2;
408  CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa", "", 0, token0);
409  CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb", "", 0, token1);
410  CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc", "", 0, token0);
411  CodeEntry entry4(
412  i::Logger::FUNCTION_TAG, "", "ddd", "", 0,
413  TokenEnumerator::kInheritsSecurityToken);
414 
415  {
416  CodeEntry* e1_e2_path[] = {&entry1, &entry2};
417  Vector<CodeEntry*> e1_e2_path_vec(
418  e1_e2_path, sizeof(e1_e2_path) / sizeof(e1_e2_path[0]));
419  source_tree.AddPathFromStart(e1_e2_path_vec);
420  CodeEntry* e2_e4_path[] = {&entry2, &entry4};
421  Vector<CodeEntry*> e2_e4_path_vec(
422  e2_e4_path, sizeof(e2_e4_path) / sizeof(e2_e4_path[0]));
423  source_tree.AddPathFromStart(e2_e4_path_vec);
424  CodeEntry* e3_e1_path[] = {&entry3, &entry1};
425  Vector<CodeEntry*> e3_e1_path_vec(
426  e3_e1_path, sizeof(e3_e1_path) / sizeof(e3_e1_path[0]));
427  source_tree.AddPathFromStart(e3_e1_path_vec);
428  CodeEntry* e3_e2_path[] = {&entry3, &entry2};
429  Vector<CodeEntry*> e3_e2_path_vec(
430  e3_e2_path, sizeof(e3_e2_path) / sizeof(e3_e2_path[0]));
431  source_tree.AddPathFromStart(e3_e2_path_vec);
432  source_tree.CalculateTotalTicks();
433  // Results in -> {entry1,0,1,0} -> {entry2,1,1,1}
434  // {root,0,4,-1} -> {entry2,0,1,1} -> {entry4,1,1,inherits}
435  // -> {entry3,0,2,0} -> {entry1,1,1,0}
436  // -> {entry2,1,1,1}
437  CHECK_EQ(4, source_tree.root()->total_ticks());
438  CHECK_EQ(0, source_tree.root()->self_ticks());
439  }
440 
441  {
442  ProfileTree token0_tree;
443  token0_tree.FilteredClone(&source_tree, token0);
444  // Should be -> {entry1,1,1,0}
445  // {root,1,4,-1} -> {entry3,1,2,0} -> {entry1,1,1,0}
446  // [self ticks from filtered nodes are attributed to their parents]
447  CHECK_EQ(4, token0_tree.root()->total_ticks());
448  CHECK_EQ(1, token0_tree.root()->self_ticks());
449  ProfileTreeTestHelper token0_helper(&token0_tree);
450  ProfileNode* node1 = token0_helper.Walk(&entry1);
451  CHECK_NE(NULL, node1);
452  CHECK_EQ(1, node1->total_ticks());
453  CHECK_EQ(1, node1->self_ticks());
454  CHECK_EQ(NULL, token0_helper.Walk(&entry2));
455  ProfileNode* node3 = token0_helper.Walk(&entry3);
456  CHECK_NE(NULL, node3);
457  CHECK_EQ(2, node3->total_ticks());
458  CHECK_EQ(1, node3->self_ticks());
459  ProfileNode* node3_1 = token0_helper.Walk(&entry3, &entry1);
460  CHECK_NE(NULL, node3_1);
461  CHECK_EQ(1, node3_1->total_ticks());
462  CHECK_EQ(1, node3_1->self_ticks());
463  CHECK_EQ(NULL, token0_helper.Walk(&entry3, &entry2));
464  }
465 
466  {
467  ProfileTree token1_tree;
468  token1_tree.FilteredClone(&source_tree, token1);
469  // Should be
470  // {root,1,4,-1} -> {entry2,2,3,1} -> {entry4,1,1,inherits}
471  // [child nodes referring to the same entry get merged and
472  // their self times summed up]
473  CHECK_EQ(4, token1_tree.root()->total_ticks());
474  CHECK_EQ(1, token1_tree.root()->self_ticks());
475  ProfileTreeTestHelper token1_helper(&token1_tree);
476  CHECK_EQ(NULL, token1_helper.Walk(&entry1));
477  CHECK_EQ(NULL, token1_helper.Walk(&entry3));
478  ProfileNode* node2 = token1_helper.Walk(&entry2);
479  CHECK_NE(NULL, node2);
480  CHECK_EQ(3, node2->total_ticks());
481  CHECK_EQ(2, node2->self_ticks());
482  ProfileNode* node2_4 = token1_helper.Walk(&entry2, &entry4);
483  CHECK_NE(NULL, node2_4);
484  CHECK_EQ(1, node2_4->total_ticks());
485  CHECK_EQ(1, node2_4->self_ticks());
486  }
487 
488  {
489  ProfileTree token2_tree;
490  token2_tree.FilteredClone(&source_tree, token2);
491  // Should be
492  // {root,4,4,-1}
493  // [no nodes, all ticks get migrated into root node]
494  CHECK_EQ(4, token2_tree.root()->total_ticks());
495  CHECK_EQ(4, token2_tree.root()->self_ticks());
496  ProfileTreeTestHelper token2_helper(&token2_tree);
497  CHECK_EQ(NULL, token2_helper.Walk(&entry1));
498  CHECK_EQ(NULL, token2_helper.Walk(&entry2));
499  CHECK_EQ(NULL, token2_helper.Walk(&entry3));
500  }
501 }
502 
503 
504 static inline i::Address ToAddress(int n) {
505  return reinterpret_cast<i::Address>(n);
506 }
507 
508 TEST(CodeMapAddCode) {
509  CodeMap code_map;
510  CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa", "", 0,
511  TokenEnumerator::kNoSecurityToken);
512  CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb", "", 0,
513  TokenEnumerator::kNoSecurityToken);
514  CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc", "", 0,
515  TokenEnumerator::kNoSecurityToken);
516  CodeEntry entry4(i::Logger::FUNCTION_TAG, "", "ddd", "", 0,
517  TokenEnumerator::kNoSecurityToken);
518  code_map.AddCode(ToAddress(0x1500), &entry1, 0x200);
519  code_map.AddCode(ToAddress(0x1700), &entry2, 0x100);
520  code_map.AddCode(ToAddress(0x1900), &entry3, 0x50);
521  code_map.AddCode(ToAddress(0x1950), &entry4, 0x10);
522  CHECK_EQ(NULL, code_map.FindEntry(0));
523  CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1500 - 1)));
524  CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1500)));
525  CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1500 + 0x100)));
526  CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1500 + 0x200 - 1)));
527  CHECK_EQ(&entry2, code_map.FindEntry(ToAddress(0x1700)));
528  CHECK_EQ(&entry2, code_map.FindEntry(ToAddress(0x1700 + 0x50)));
529  CHECK_EQ(&entry2, code_map.FindEntry(ToAddress(0x1700 + 0x100 - 1)));
530  CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1700 + 0x100)));
531  CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1900 - 1)));
532  CHECK_EQ(&entry3, code_map.FindEntry(ToAddress(0x1900)));
533  CHECK_EQ(&entry3, code_map.FindEntry(ToAddress(0x1900 + 0x28)));
534  CHECK_EQ(&entry4, code_map.FindEntry(ToAddress(0x1950)));
535  CHECK_EQ(&entry4, code_map.FindEntry(ToAddress(0x1950 + 0x7)));
536  CHECK_EQ(&entry4, code_map.FindEntry(ToAddress(0x1950 + 0x10 - 1)));
537  CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1950 + 0x10)));
538  CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0xFFFFFFFF)));
539 }
540 
541 
542 TEST(CodeMapMoveAndDeleteCode) {
543  CodeMap code_map;
544  CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa", "", 0,
545  TokenEnumerator::kNoSecurityToken);
546  CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb", "", 0,
547  TokenEnumerator::kNoSecurityToken);
548  code_map.AddCode(ToAddress(0x1500), &entry1, 0x200);
549  code_map.AddCode(ToAddress(0x1700), &entry2, 0x100);
550  CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1500)));
551  CHECK_EQ(&entry2, code_map.FindEntry(ToAddress(0x1700)));
552  code_map.MoveCode(ToAddress(0x1500), ToAddress(0x1700)); // Deprecate bbb.
553  CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1500)));
554  CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1700)));
555  CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc", "", 0,
556  TokenEnumerator::kNoSecurityToken);
557  code_map.AddCode(ToAddress(0x1750), &entry3, 0x100);
558  CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1700)));
559  CHECK_EQ(&entry3, code_map.FindEntry(ToAddress(0x1750)));
560 }
561 
562 
563 namespace {
564 
565 class TestSetup {
566  public:
567  TestSetup()
568  : old_flag_prof_browser_mode_(i::FLAG_prof_browser_mode) {
569  i::FLAG_prof_browser_mode = false;
570  }
571 
572  ~TestSetup() {
573  i::FLAG_prof_browser_mode = old_flag_prof_browser_mode_;
574  }
575 
576  private:
577  bool old_flag_prof_browser_mode_;
578 };
579 
580 } // namespace
581 
582 TEST(RecordTickSample) {
583  TestSetup test_setup;
584  CpuProfilesCollection profiles;
585  profiles.StartProfiling("", 1);
586  ProfileGenerator generator(&profiles);
587  CodeEntry* entry1 = generator.NewCodeEntry(i::Logger::FUNCTION_TAG, "aaa");
588  CodeEntry* entry2 = generator.NewCodeEntry(i::Logger::FUNCTION_TAG, "bbb");
589  CodeEntry* entry3 = generator.NewCodeEntry(i::Logger::FUNCTION_TAG, "ccc");
590  generator.code_map()->AddCode(ToAddress(0x1500), entry1, 0x200);
591  generator.code_map()->AddCode(ToAddress(0x1700), entry2, 0x100);
592  generator.code_map()->AddCode(ToAddress(0x1900), entry3, 0x50);
593 
594  // We are building the following calls tree:
595  // -> aaa - sample1
596  // aaa -> bbb -> ccc - sample2
597  // -> ccc -> aaa - sample3
598  TickSample sample1;
599  sample1.pc = ToAddress(0x1600);
600  sample1.tos = ToAddress(0x1500);
601  sample1.stack[0] = ToAddress(0x1510);
602  sample1.frames_count = 1;
603  generator.RecordTickSample(sample1);
604  TickSample sample2;
605  sample2.pc = ToAddress(0x1925);
606  sample2.tos = ToAddress(0x1900);
607  sample2.stack[0] = ToAddress(0x1780);
608  sample2.stack[1] = ToAddress(0x10000); // non-existent.
609  sample2.stack[2] = ToAddress(0x1620);
610  sample2.frames_count = 3;
611  generator.RecordTickSample(sample2);
612  TickSample sample3;
613  sample3.pc = ToAddress(0x1510);
614  sample3.tos = ToAddress(0x1500);
615  sample3.stack[0] = ToAddress(0x1910);
616  sample3.stack[1] = ToAddress(0x1610);
617  sample3.frames_count = 2;
618  generator.RecordTickSample(sample3);
619 
620  CpuProfile* profile =
621  profiles.StopProfiling(TokenEnumerator::kNoSecurityToken, "", 1);
622  CHECK_NE(NULL, profile);
623  ProfileTreeTestHelper top_down_test_helper(profile->top_down());
624  CHECK_EQ(NULL, top_down_test_helper.Walk(entry2));
625  CHECK_EQ(NULL, top_down_test_helper.Walk(entry3));
626  ProfileNode* node1 = top_down_test_helper.Walk(entry1);
627  CHECK_NE(NULL, node1);
628  CHECK_EQ(entry1, node1->entry());
629  ProfileNode* node2 = top_down_test_helper.Walk(entry1, entry1);
630  CHECK_NE(NULL, node2);
631  CHECK_EQ(entry1, node2->entry());
632  ProfileNode* node3 = top_down_test_helper.Walk(entry1, entry2, entry3);
633  CHECK_NE(NULL, node3);
634  CHECK_EQ(entry3, node3->entry());
635  ProfileNode* node4 = top_down_test_helper.Walk(entry1, entry3, entry1);
636  CHECK_NE(NULL, node4);
637  CHECK_EQ(entry1, node4->entry());
638 }
639 
640 
641 TEST(SampleRateCalculator) {
642  const double kSamplingIntervalMs = i::Logger::kSamplingIntervalMs;
643 
644  // Verify that ticking exactly in query intervals results in the
645  // initial sampling interval.
646  double time = 0.0;
647  SampleRateCalculator calc1;
648  CHECK_EQ(kSamplingIntervalMs, calc1.ticks_per_ms());
649  calc1.UpdateMeasurements(time);
650  CHECK_EQ(kSamplingIntervalMs, calc1.ticks_per_ms());
651  time += SampleRateCalculator::kWallTimeQueryIntervalMs;
652  calc1.UpdateMeasurements(time);
653  CHECK_EQ(kSamplingIntervalMs, calc1.ticks_per_ms());
654  time += SampleRateCalculator::kWallTimeQueryIntervalMs;
655  calc1.UpdateMeasurements(time);
656  CHECK_EQ(kSamplingIntervalMs, calc1.ticks_per_ms());
657  time += SampleRateCalculator::kWallTimeQueryIntervalMs;
658  calc1.UpdateMeasurements(time);
659  CHECK_EQ(kSamplingIntervalMs, calc1.ticks_per_ms());
660 
661  SampleRateCalculator calc2;
662  time = 0.0;
663  CHECK_EQ(kSamplingIntervalMs, calc2.ticks_per_ms());
664  calc2.UpdateMeasurements(time);
665  CHECK_EQ(kSamplingIntervalMs, calc2.ticks_per_ms());
666  time += SampleRateCalculator::kWallTimeQueryIntervalMs * 0.5;
667  calc2.UpdateMeasurements(time);
668  // (1.0 + 2.0) / 2
669  CHECK_EQ(kSamplingIntervalMs * 1.5, calc2.ticks_per_ms());
670  time += SampleRateCalculator::kWallTimeQueryIntervalMs * 0.75;
671  calc2.UpdateMeasurements(time);
672  // (1.0 + 2.0 + 2.0) / 3
673  CHECK_EQ(kSamplingIntervalMs * 5.0, floor(calc2.ticks_per_ms() * 3.0 + 0.5));
674 
675  SampleRateCalculator calc3;
676  time = 0.0;
677  CHECK_EQ(kSamplingIntervalMs, calc3.ticks_per_ms());
678  calc3.UpdateMeasurements(time);
679  CHECK_EQ(kSamplingIntervalMs, calc3.ticks_per_ms());
680  time += SampleRateCalculator::kWallTimeQueryIntervalMs * 2;
681  calc3.UpdateMeasurements(time);
682  // (1.0 + 0.5) / 2
683  CHECK_EQ(kSamplingIntervalMs * 0.75, calc3.ticks_per_ms());
684  time += SampleRateCalculator::kWallTimeQueryIntervalMs * 1.5;
685  calc3.UpdateMeasurements(time);
686  // (1.0 + 0.5 + 0.5) / 3
687  CHECK_EQ(kSamplingIntervalMs * 2.0, floor(calc3.ticks_per_ms() * 3.0 + 0.5));
688 }
689 
690 
691 // --- P r o f i l e r E x t e n s i o n ---
692 
694  public:
695  ProfilerExtension() : v8::Extension("v8/profiler", kSource) { }
700  private:
701  static const char* kSource;
702 };
703 
704 
705 const char* ProfilerExtension::kSource =
706  "native function startProfiling();"
707  "native function stopProfiling();";
708 
711  if (name->Equals(v8::String::New("startProfiling"))) {
713  } else if (name->Equals(v8::String::New("stopProfiling"))) {
715  } else {
716  CHECK(false);
718  }
719 }
720 
721 
723  const v8::Arguments& args) {
724  if (args.Length() > 0)
725  v8::CpuProfiler::StartProfiling(args[0].As<v8::String>());
726  else
728  return v8::Undefined();
729 }
730 
731 
733  const v8::Arguments& args) {
734  if (args.Length() > 0)
735  v8::CpuProfiler::StopProfiling(args[0].As<v8::String>());
736  else
738  return v8::Undefined();
739 }
740 
741 
742 static ProfilerExtension kProfilerExtension;
743 v8::DeclareExtension kProfilerExtensionDeclaration(&kProfilerExtension);
744 static v8::Persistent<v8::Context> env;
745 
746 static const ProfileNode* PickChild(const ProfileNode* parent,
747  const char* name) {
748  for (int i = 0; i < parent->children()->length(); ++i) {
749  const ProfileNode* child = parent->children()->at(i);
750  if (strcmp(child->entry()->name(), name) == 0) return child;
751  }
752  return NULL;
753 }
754 
755 
756 TEST(RecordStackTraceAtStartProfiling) {
757  // This test does not pass with inlining enabled since inlined functions
758  // don't appear in the stack trace.
759  i::FLAG_use_inlining = false;
760 
761  if (env.IsEmpty()) {
762  v8::HandleScope scope;
763  const char* extensions[] = { "v8/profiler" };
764  v8::ExtensionConfiguration config(1, extensions);
765  env = v8::Context::New(&config);
766  }
767  v8::HandleScope scope;
768  env->Enter();
769 
770  CHECK_EQ(0, CpuProfiler::GetProfilesCount());
771  CompileRun(
772  "function c() { startProfiling(); }\n"
773  "function b() { c(); }\n"
774  "function a() { b(); }\n"
775  "a();\n"
776  "stopProfiling();");
777  CHECK_EQ(1, CpuProfiler::GetProfilesCount());
778  CpuProfile* profile =
779  CpuProfiler::GetProfile(NULL, 0);
780  const ProfileTree* topDown = profile->top_down();
781  const ProfileNode* current = topDown->root();
782  const_cast<ProfileNode*>(current)->Print(0);
783  // The tree should look like this:
784  // (root)
785  // (anonymous function)
786  // a
787  // b
788  // c
789  // There can also be:
790  // startProfiling
791  // if the sampler managed to get a tick.
792  current = PickChild(current, "(anonymous function)");
793  CHECK_NE(NULL, const_cast<ProfileNode*>(current));
794  current = PickChild(current, "a");
795  CHECK_NE(NULL, const_cast<ProfileNode*>(current));
796  current = PickChild(current, "b");
797  CHECK_NE(NULL, const_cast<ProfileNode*>(current));
798  current = PickChild(current, "c");
799  CHECK_NE(NULL, const_cast<ProfileNode*>(current));
800  CHECK(current->children()->length() == 0 ||
801  current->children()->length() == 1);
802  if (current->children()->length() == 1) {
803  current = PickChild(current, "startProfiling");
804  CHECK_EQ(0, current->children()->length());
805  }
806 }
807 
808 
809 TEST(Issue51919) {
810  CpuProfilesCollection collection;
811  i::EmbeddedVector<char*,
812  CpuProfilesCollection::kMaxSimultaneousProfiles> titles;
813  for (int i = 0; i < CpuProfilesCollection::kMaxSimultaneousProfiles; ++i) {
815  i::OS::SNPrintF(title, "%d", i);
816  CHECK(collection.StartProfiling(title.start(), i + 1)); // UID must be > 0.
817  titles[i] = title.start();
818  }
819  CHECK(!collection.StartProfiling(
820  "maximum", CpuProfilesCollection::kMaxSimultaneousProfiles + 1));
821  for (int i = 0; i < CpuProfilesCollection::kMaxSimultaneousProfiles; ++i)
822  i::DeleteArray(titles[i]);
823 }
byte * Address
Definition: globals.h:172
#define CHECK_EQ(expected, value)
Definition: checks.h:219
static Local< FunctionTemplate > New(InvocationCallback callback=0, Handle< Value > data=Handle< Value >(), Handle< Signature > signature=Handle< Signature >())
Definition: api.cc:943
static i::List< bool > * token_removed(TokenEnumerator *te)
Extension(const char *name, const char *source=0, int dep_count=0, const char **deps=0, int source_length=-1)
Definition: api.cc:531
value format" "after each garbage collection") DEFINE_bool(print_cumulative_gc_stat, false, "print cumulative GC statistics in name=value format on exit") DEFINE_bool(trace_gc_verbose, false, "print more details following each garbage collection") DEFINE_bool(trace_fragmentation, false, "report fragmentation for old pointer and data pages") DEFINE_bool(collect_maps, true, "garbage collect maps from which no objects can be reached") DEFINE_bool(flush_code, true, "flush code that we expect not to use again before full gc") DEFINE_bool(incremental_marking, true, "use incremental marking") DEFINE_bool(incremental_marking_steps, true, "do incremental marking steps") DEFINE_bool(trace_incremental_marking, false, "trace progress of the incremental marking") DEFINE_bool(use_idle_notification, true, "Use idle notification to reduce memory footprint.") DEFINE_bool(send_idle_notification, false, "Send idle notifcation between stress runs.") DEFINE_bool(use_ic, true, "use inline caching") DEFINE_bool(native_code_counters, false, "generate extra code for manipulating stats counters") DEFINE_bool(always_compact, false, "Perform compaction on every full GC") DEFINE_bool(lazy_sweeping, true, "Use lazy sweeping for old pointer and data spaces") DEFINE_bool(never_compact, false, "Never perform compaction on full GC-testing only") DEFINE_bool(compact_code_space, true, "Compact code space on full non-incremental collections") DEFINE_bool(cleanup_code_caches_at_gc, true, "Flush inline caches prior to mark compact collection and" "flush code caches in maps during mark compact cycle.") DEFINE_int(random_seed, 0, "Default seed for initializing random generator" "(0, the default, means to use system random).") DEFINE_bool(use_verbose_printer, true, "allows verbose printing") DEFINE_bool(allow_natives_syntax, false, "allow natives syntax") DEFINE_bool(trace_sim, false, "Trace simulator execution") DEFINE_bool(check_icache, false, "Check icache flushes in ARM and MIPS simulator") DEFINE_int(stop_sim_at, 0, "Simulator stop after x number of instructions") DEFINE_int(sim_stack_alignment, 8, "Stack alingment in bytes in simulator(4 or 8, 8 is default)") DEFINE_bool(trace_exception, false, "print stack trace when throwing exceptions") DEFINE_bool(preallocate_message_memory, false, "preallocate some memory to build stack traces.") DEFINE_bool(randomize_hashes, true, "randomize hashes to avoid predictable hash collisions" "(with snapshots this option cannot override the baked-in seed)") DEFINE_int(hash_seed, 0, "Fixed seed to use to hash property keys(0 means random)" "(with snapshots this option cannot override the baked-in seed)") DEFINE_bool(preemption, false, "activate a 100ms timer that switches between V8 threads") DEFINE_bool(regexp_optimization, true, "generate optimized regexp code") DEFINE_bool(testing_bool_flag, true, "testing_bool_flag") DEFINE_int(testing_int_flag, 13, "testing_int_flag") DEFINE_float(testing_float_flag, 2.5, "float-flag") DEFINE_string(testing_string_flag, "Hello, world!", "string-flag") DEFINE_int(testing_prng_seed, 42, "Seed used for threading test randomness") DEFINE_string(testing_serialization_file, "/tmp/serdes", "file in which to serialize heap") DEFINE_bool(help, false, "Print usage message, including flags, on console") DEFINE_bool(dump_counters, false, "Dump counters on exit") DEFINE_string(map_counters, "", "Map counters to a file") DEFINE_args(js_arguments, JSARGUMENTS_INIT, "Pass all remaining arguments to the script.Alias for\"--\".") DEFINE_bool(debug_compile_events, true,"Enable debugger compile events") DEFINE_bool(debug_script_collected_events, true,"Enable debugger script collected events") DEFINE_bool(gdbjit, false,"enable GDBJIT interface (disables compacting GC)") DEFINE_bool(gdbjit_full, false,"enable GDBJIT interface for all code objects") DEFINE_bool(gdbjit_dump, false,"dump elf objects with debug info to disk") DEFINE_string(gdbjit_dump_filter,"","dump only objects containing this substring") DEFINE_bool(force_marking_deque_overflows, false,"force overflows of marking deque by reducing it's size ""to 64 words") DEFINE_bool(stress_compaction, false,"stress the GC compactor to flush out bugs (implies ""--force_marking_deque_overflows)")#define FLAG DEFINE_bool(enable_slow_asserts, false,"enable asserts that are slow to execute") DEFINE_bool(trace_codegen, false,"print name of functions for which code is generated") DEFINE_bool(print_source, false,"pretty print source code") DEFINE_bool(print_builtin_source, false,"pretty print source code for builtins") DEFINE_bool(print_ast, false,"print source AST") DEFINE_bool(print_builtin_ast, false,"print source AST for builtins") DEFINE_string(stop_at,"","function name where to insert a breakpoint") DEFINE_bool(print_builtin_scopes, false,"print scopes for builtins") DEFINE_bool(print_scopes, false,"print scopes") DEFINE_bool(trace_contexts, false,"trace contexts operations") DEFINE_bool(gc_greedy, false,"perform GC prior to some allocations") DEFINE_bool(gc_verbose, false,"print stuff during garbage collection") DEFINE_bool(heap_stats, false,"report heap statistics before and after GC") DEFINE_bool(code_stats, false,"report code statistics after GC") DEFINE_bool(verify_heap, false,"verify heap pointers before and after GC") DEFINE_bool(print_handles, false,"report handles after GC") DEFINE_bool(print_global_handles, false,"report global handles after GC") DEFINE_bool(trace_ic, false,"trace inline cache state transitions") DEFINE_bool(print_interfaces, false,"print interfaces") DEFINE_bool(print_interface_details, false,"print interface inference details") DEFINE_int(print_interface_depth, 5,"depth for printing interfaces") DEFINE_bool(trace_normalization, false,"prints when objects are turned into dictionaries.") DEFINE_bool(trace_lazy, false,"trace lazy compilation") DEFINE_bool(collect_heap_spill_statistics, false,"report heap spill statistics along with heap_stats ""(requires heap_stats)") DEFINE_bool(trace_isolates, false,"trace isolate state changes") DEFINE_bool(log_state_changes, false,"Log state changes.") DEFINE_bool(regexp_possessive_quantifier, false,"enable possessive quantifier syntax for testing") DEFINE_bool(trace_regexp_bytecodes, false,"trace regexp bytecode execution") DEFINE_bool(trace_regexp_assembler, false,"trace regexp macro assembler calls.")#define FLAG DEFINE_bool(log, false,"Minimal logging (no API, code, GC, suspect, or handles samples).") DEFINE_bool(log_all, false,"Log all events to the log file.") DEFINE_bool(log_runtime, false,"Activate runtime system %Log call.") DEFINE_bool(log_api, false,"Log API events to the log file.") DEFINE_bool(log_code, false,"Log code events to the log file without profiling.") DEFINE_bool(log_gc, false,"Log heap samples on garbage collection for the hp2ps tool.") DEFINE_bool(log_handles, false,"Log global handle events.") DEFINE_bool(log_snapshot_positions, false,"log positions of (de)serialized objects in the snapshot.") DEFINE_bool(log_suspect, false,"Log suspect operations.") DEFINE_bool(prof, false,"Log statistical profiling information (implies --log-code).") DEFINE_bool(prof_auto, true,"Used with --prof, starts profiling automatically") DEFINE_bool(prof_lazy, false,"Used with --prof, only does sampling and logging"" when profiler is active (implies --noprof_auto).") DEFINE_bool(prof_browser_mode, true,"Used with --prof, turns on browser-compatible mode for profiling.") DEFINE_bool(log_regexp, false,"Log regular expression execution.") DEFINE_bool(sliding_state_window, false,"Update sliding state window counters.") DEFINE_string(logfile,"v8.log","Specify the name of the log file.") DEFINE_bool(ll_prof, false,"Enable low-level linux profiler.")#define FLAG DEFINE_bool(trace_elements_transitions, false,"trace elements transitions") DEFINE_bool(print_code_stubs, false,"print code stubs") DEFINE_bool(test_secondary_stub_cache, false,"test secondary stub cache by disabling the primary one") DEFINE_bool(test_primary_stub_cache, false,"test primary stub cache by disabling the secondary one") DEFINE_bool(print_code, false,"print generated code") DEFINE_bool(print_opt_code, false,"print optimized code") DEFINE_bool(print_unopt_code, false,"print unoptimized code before ""printing optimized code based on it") DEFINE_bool(print_code_verbose, false,"print more information for code") DEFINE_bool(print_builtin_code, false,"print generated code for builtins")#43"/Users/thlorenz/dev/dx/v8-perf/build/v8/src/flags.cc"2#define FLAG_MODE_DEFINE_DEFAULTS#1"/Users/thlorenz/dev/dx/v8-perf/build/v8/src/flag-definitions.h"1#define FLAG_FULL(ftype, ctype, nam, def, cmt)#define FLAG_READONLY(ftype, ctype, nam, def, cmt)#define DEFINE_implication(whenflag, thenflag)#define DEFINE_bool(nam, def, cmt)#define DEFINE_int(nam, def, cmt)#define DEFINE_float(nam, def, cmt)#define DEFINE_string(nam, def, cmt)#define DEFINE_args(nam, def, cmt)#define FLAG DEFINE_bool(use_strict, false,"enforce strict mode") DEFINE_bool(es5_readonly, false,"activate correct semantics for inheriting readonliness") DEFINE_bool(es52_globals, false,"activate new semantics for global var declarations") DEFINE_bool(harmony_typeof, false,"enable harmony semantics for typeof") DEFINE_bool(harmony_scoping, false,"enable harmony block scoping") DEFINE_bool(harmony_modules, false,"enable harmony modules (implies block scoping)") DEFINE_bool(harmony_proxies, false,"enable harmony proxies") DEFINE_bool(harmony_collections, false,"enable harmony collections (sets, maps, and weak maps)") DEFINE_bool(harmony, false,"enable all harmony features (except typeof)") DEFINE_implication(harmony, harmony_scoping) DEFINE_implication(harmony, harmony_modules) DEFINE_implication(harmony, harmony_proxies) DEFINE_implication(harmony, harmony_collections) DEFINE_implication(harmony_modules, harmony_scoping) DEFINE_bool(packed_arrays, false,"optimizes arrays that have no holes") DEFINE_bool(smi_only_arrays, true,"tracks arrays with only smi values") DEFINE_bool(clever_optimizations, true,"Optimize object size, Array shift, DOM strings and string +") DEFINE_bool(unbox_double_arrays, true,"automatically unbox arrays of doubles") DEFINE_bool(string_slices, true,"use string slices") DEFINE_bool(crankshaft, true,"use crankshaft") DEFINE_string(hydrogen_filter,"","optimization filter") DEFINE_bool(use_range, true,"use hydrogen range analysis") DEFINE_bool(eliminate_dead_phis, true,"eliminate dead phis") DEFINE_bool(use_gvn, true,"use hydrogen global value numbering") DEFINE_bool(use_canonicalizing, true,"use hydrogen instruction canonicalizing") DEFINE_bool(use_inlining, true,"use function inlining") DEFINE_int(max_inlined_source_size, 600,"maximum source size in bytes considered for a single inlining") DEFINE_int(max_inlined_nodes, 196,"maximum number of AST nodes considered for a single inlining") DEFINE_int(max_inlined_nodes_cumulative, 196,"maximum cumulative number of AST nodes considered for inlining") DEFINE_bool(loop_invariant_code_motion, true,"loop invariant code motion") DEFINE_bool(collect_megamorphic_maps_from_stub_cache, true,"crankshaft harvests type feedback from stub cache") DEFINE_bool(hydrogen_stats, false,"print statistics for hydrogen") DEFINE_bool(trace_hydrogen, false,"trace generated hydrogen to file") DEFINE_string(trace_phase,"Z","trace generated IR for specified phases") DEFINE_bool(trace_inlining, false,"trace inlining decisions") DEFINE_bool(trace_alloc, false,"trace register allocator") DEFINE_bool(trace_all_uses, false,"trace all use positions") DEFINE_bool(trace_range, false,"trace range analysis") DEFINE_bool(trace_gvn, false,"trace global value numbering") DEFINE_bool(trace_representation, false,"trace representation types") DEFINE_bool(stress_pointer_maps, false,"pointer map for every instruction") DEFINE_bool(stress_environments, false,"environment for every instruction") DEFINE_int(deopt_every_n_times, 0,"deoptimize every n times a deopt point is passed") DEFINE_bool(trap_on_deopt, false,"put a break point before deoptimizing") DEFINE_bool(deoptimize_uncommon_cases, true,"deoptimize uncommon cases") DEFINE_bool(polymorphic_inlining, true,"polymorphic inlining") DEFINE_bool(use_osr, true,"use on-stack replacement") DEFINE_bool(array_bounds_checks_elimination, false,"perform array bounds checks elimination") DEFINE_bool(array_index_dehoisting, false,"perform array index dehoisting") DEFINE_bool(trace_osr, false,"trace on-stack replacement") DEFINE_int(stress_runs, 0,"number of stress runs") DEFINE_bool(optimize_closures, true,"optimize closures") DEFINE_bool(inline_construct, true,"inline constructor calls") DEFINE_bool(inline_arguments, true,"inline functions with arguments object") DEFINE_int(loop_weight, 1,"loop weight for representation inference") DEFINE_bool(optimize_for_in, true,"optimize functions containing for-in loops") DEFINE_bool(experimental_profiler, true,"enable all profiler experiments") DEFINE_bool(watch_ic_patching, false,"profiler considers IC stability") DEFINE_int(frame_count, 1,"number of stack frames inspected by the profiler") DEFINE_bool(self_optimization, false,"primitive functions trigger their own optimization") DEFINE_bool(direct_self_opt, false,"call recompile stub directly when self-optimizing") DEFINE_bool(retry_self_opt, false,"re-try self-optimization if it failed") DEFINE_bool(count_based_interrupts, false,"trigger profiler ticks based on counting instead of timing") DEFINE_bool(interrupt_at_exit, false,"insert an interrupt check at function exit") DEFINE_bool(weighted_back_edges, false,"weight back edges by jump distance for interrupt triggering") DEFINE_int(interrupt_budget, 5900,"execution budget before interrupt is triggered") DEFINE_int(type_info_threshold, 15,"percentage of ICs that must have type info to allow optimization") DEFINE_int(self_opt_count, 130,"call count before self-optimization") DEFINE_implication(experimental_profiler, watch_ic_patching) DEFINE_implication(experimental_profiler, self_optimization) DEFINE_implication(experimental_profiler, retry_self_opt) DEFINE_implication(experimental_profiler, count_based_interrupts) DEFINE_implication(experimental_profiler, interrupt_at_exit) DEFINE_implication(experimental_profiler, weighted_back_edges) DEFINE_bool(trace_opt_verbose, false,"extra verbose compilation tracing") DEFINE_implication(trace_opt_verbose, trace_opt) DEFINE_bool(debug_code, false,"generate extra code (assertions) for debugging") DEFINE_bool(code_comments, false,"emit comments in code disassembly") DEFINE_bool(enable_sse2, true,"enable use of SSE2 instructions if available") DEFINE_bool(enable_sse3, true,"enable use of SSE3 instructions if available") DEFINE_bool(enable_sse4_1, true,"enable use of SSE4.1 instructions if available") DEFINE_bool(enable_cmov, true,"enable use of CMOV instruction if available") DEFINE_bool(enable_rdtsc, true,"enable use of RDTSC instruction if available") DEFINE_bool(enable_sahf, true,"enable use of SAHF instruction if available (X64 only)") DEFINE_bool(enable_vfp3, true,"enable use of VFP3 instructions if available - this implies ""enabling ARMv7 instructions (ARM only)") DEFINE_bool(enable_armv7, true,"enable use of ARMv7 instructions if available (ARM only)") DEFINE_bool(enable_fpu, true,"enable use of MIPS FPU instructions if available (MIPS only)") DEFINE_string(expose_natives_as, NULL,"expose natives in global object") DEFINE_string(expose_debug_as, NULL,"expose debug in global object") DEFINE_bool(expose_gc, false,"expose gc extension") DEFINE_bool(expose_externalize_string, false,"expose externalize string extension") DEFINE_int(stack_trace_limit, 10,"number of stack frames to capture") DEFINE_bool(builtins_in_stack_traces, false,"show built-in functions in stack traces") DEFINE_bool(disable_native_files, false,"disable builtin natives files") DEFINE_bool(inline_new, true,"use fast inline allocation") DEFINE_bool(stack_trace_on_abort, true,"print a stack trace if an assertion failure occurs") DEFINE_bool(trace, false,"trace function calls") DEFINE_bool(mask_constants_with_cookie, true,"use random jit cookie to mask large constants") DEFINE_bool(lazy, true,"use lazy compilation") DEFINE_bool(trace_opt, false,"trace lazy optimization") DEFINE_bool(trace_opt_stats, false,"trace lazy optimization statistics") DEFINE_bool(opt, true,"use adaptive optimizations") DEFINE_bool(always_opt, false,"always try to optimize functions") DEFINE_bool(prepare_always_opt, false,"prepare for turning on always opt") DEFINE_bool(trace_deopt, false,"trace deoptimization") DEFINE_int(min_preparse_length, 1024,"minimum length for automatic enable preparsing") DEFINE_bool(always_full_compiler, false,"try to use the dedicated run-once backend for all code") DEFINE_bool(trace_bailout, false,"print reasons for falling back to using the classic V8 backend") DEFINE_bool(compilation_cache, true,"enable compilation cache") DEFINE_bool(cache_prototype_transitions, true,"cache prototype transitions") DEFINE_bool(trace_debug_json, false,"trace debugging JSON request/response") DEFINE_bool(debugger_auto_break, true,"automatically set the debug break flag when debugger commands are ""in the queue") DEFINE_bool(enable_liveedit, true,"enable liveedit experimental feature") DEFINE_bool(break_on_abort, true,"always cause a debug break before aborting") DEFINE_int(stack_size, kPointerSize *123,"default size of stack region v8 is allowed to use (in kBytes)") DEFINE_int(max_stack_trace_source_length, 300,"maximum length of function source code printed in a stack trace.") DEFINE_bool(always_inline_smi_code, false,"always inline smi code in non-opt code") DEFINE_int(max_new_space_size, 0,"max size of the new generation (in kBytes)") DEFINE_int(max_old_space_size, 0,"max size of the old generation (in Mbytes)") DEFINE_int(max_executable_size, 0,"max size of executable memory (in Mbytes)") DEFINE_bool(gc_global, false,"always perform global GCs") DEFINE_int(gc_interval,-1,"garbage collect after <n> allocations") DEFINE_bool(trace_gc, false,"print one trace line following each garbage collection") DEFINE_bool(trace_gc_nvp, false,"print one detailed trace line in name=value format ""after each garbage collection") DEFINE_bool(print_cumulative_gc_stat, false,"print cumulative GC statistics in name=value format on exit") DEFINE_bool(trace_gc_verbose, false,"print more details following each garbage collection") DEFINE_bool(trace_fragmentation, false,"report fragmentation for old pointer and data pages") DEFINE_bool(collect_maps, true,"garbage collect maps from which no objects can be reached") DEFINE_bool(flush_code, true,"flush code that we expect not to use again before full gc") DEFINE_bool(incremental_marking, true,"use incremental marking") DEFINE_bool(incremental_marking_steps, true,"do incremental marking steps") DEFINE_bool(trace_incremental_marking, false,"trace progress of the incremental marking") DEFINE_bool(use_idle_notification, true,"Use idle notification to reduce memory footprint.") DEFINE_bool(send_idle_notification, false,"Send idle notifcation between stress runs.") DEFINE_bool(use_ic, true,"use inline caching") DEFINE_bool(native_code_counters, false,"generate extra code for manipulating stats counters") DEFINE_bool(always_compact, false,"Perform compaction on every full GC") DEFINE_bool(lazy_sweeping, true,"Use lazy sweeping for old pointer and data spaces") DEFINE_bool(never_compact, false,"Never perform compaction on full GC - testing only") DEFINE_bool(compact_code_space, true,"Compact code space on full non-incremental collections") DEFINE_bool(cleanup_code_caches_at_gc, true,"Flush inline caches prior to mark compact collection and ""flush code caches in maps during mark compact cycle.") DEFINE_int(random_seed, 0,"Default seed for initializing random generator ""(0, the default, means to use system random).") DEFINE_bool(use_verbose_printer, true,"allows verbose printing") DEFINE_bool(allow_natives_syntax, false,"allow natives syntax") DEFINE_bool(trace_sim, false,"Trace simulator execution") DEFINE_bool(check_icache, false,"Check icache flushes in ARM and MIPS simulator") DEFINE_int(stop_sim_at, 0,"Simulator stop after x number of instructions") DEFINE_int(sim_stack_alignment, 8,"Stack alingment in bytes in simulator (4 or 8, 8 is default)") DEFINE_bool(trace_exception, false,"print stack trace when throwing exceptions") DEFINE_bool(preallocate_message_memory, false,"preallocate some memory to build stack traces.") DEFINE_bool(randomize_hashes, true,"randomize hashes to avoid predictable hash collisions ""(with snapshots this option cannot override the baked-in seed)") DEFINE_int(hash_seed, 0,"Fixed seed to use to hash property keys (0 means random)""(with snapshots this option cannot override the baked-in seed)") DEFINE_bool(preemption, false,"activate a 100ms timer that switches between V8 threads") DEFINE_bool(regexp_optimization, true,"generate optimized regexp code") DEFINE_bool(testing_bool_flag, true,"testing_bool_flag") DEFINE_int(testing_int_flag, 13,"testing_int_flag") DEFINE_float(testing_float_flag, 2.5,"float-flag") DEFINE_string(testing_string_flag,"Hello, world!","string-flag") DEFINE_int(testing_prng_seed, 42,"Seed used for threading test randomness") DEFINE_string(testing_serialization_file,"/tmp/serdes","file in which to serialize heap") DEFINE_bool(help, false,"Print usage message, including flags, on console") DEFINE_bool(dump_counters, false,"Dump counters on exit") DEFINE_string(map_counters,"","Map counters to a file") DEFINE_args(js_arguments, JSARGUMENTS_INIT,"Pass all remaining arguments to the script. Alias for \"--\".") DEFINE_bool(debug_compile_events, true,"Enable debugger compile events") DEFINE_bool(debug_script_collected_events, true,"Enable debugger script collected events") DEFINE_bool(gdbjit, false,"enable GDBJIT interface (disables compacting GC)") DEFINE_bool(gdbjit_full, false,"enable GDBJIT interface for all code objects") DEFINE_bool(gdbjit_dump, false,"dump elf objects with debug info to disk") DEFINE_string(gdbjit_dump_filter,"","dump only objects containing this substring") DEFINE_bool(force_marking_deque_overflows, false,"force overflows of marking deque by reducing it's size ""to 64 words") DEFINE_bool(stress_compaction, false,"stress the GC compactor to flush out bugs (implies ""--force_marking_deque_overflows)")#define FLAG DEFINE_bool(enable_slow_asserts, false,"enable asserts that are slow to execute") DEFINE_bool(trace_codegen, false,"print name of functions for which code is generated") DEFINE_bool(print_source, false,"pretty print source code") DEFINE_bool(print_builtin_source, false,"pretty print source code for builtins") DEFINE_bool(print_ast, false,"print source AST") DEFINE_bool(print_builtin_ast, false,"print source AST for builtins") DEFINE_string(stop_at,"","function name where to insert a breakpoint") DEFINE_bool(print_builtin_scopes, false,"print scopes for builtins") DEFINE_bool(print_scopes, false,"print scopes") DEFINE_bool(trace_contexts, false,"trace contexts operations") DEFINE_bool(gc_greedy, false,"perform GC prior to some allocations") DEFINE_bool(gc_verbose, false,"print stuff during garbage collection") DEFINE_bool(heap_stats, false,"report heap statistics before and after GC") DEFINE_bool(code_stats, false,"report code statistics after GC") DEFINE_bool(verify_heap, false,"verify heap pointers before and after GC") DEFINE_bool(print_handles, false,"report handles after GC") DEFINE_bool(print_global_handles, false,"report global handles after GC") DEFINE_bool(trace_ic, false,"trace inline cache state transitions") DEFINE_bool(print_interfaces, false,"print interfaces") DEFINE_bool(print_interface_details, false,"print interface inference details") DEFINE_int(print_interface_depth, 5,"depth for printing interfaces") DEFINE_bool(trace_normalization, false,"prints when objects are turned into dictionaries.") DEFINE_bool(trace_lazy, false,"trace lazy compilation") DEFINE_bool(collect_heap_spill_statistics, false,"report heap spill statistics along with heap_stats ""(requires heap_stats)") DEFINE_bool(trace_isolates, false,"trace isolate state changes") DEFINE_bool(log_state_changes, false,"Log state changes.") DEFINE_bool(regexp_possessive_quantifier, false,"enable possessive quantifier syntax for testing") DEFINE_bool(trace_regexp_bytecodes, false,"trace regexp bytecode execution") DEFINE_bool(trace_regexp_assembler, false,"trace regexp macro assembler calls.")#define FLAG DEFINE_bool(log, false,"Minimal logging (no API, code, GC, suspect, or handles samples).") DEFINE_bool(log_all, false,"Log all events to the log file.") DEFINE_bool(log_runtime, false,"Activate runtime system %Log call.") DEFINE_bool(log_api, false,"Log API events to the log file.") DEFINE_bool(log_code, false,"Log code events to the log file without profiling.") DEFINE_bool(log_gc, false,"Log heap samples on garbage collection for the hp2ps tool.") DEFINE_bool(log_handles, false,"Log global handle events.") DEFINE_bool(log_snapshot_positions, false,"log positions of (de)serialized objects in the snapshot.") DEFINE_bool(log_suspect, false,"Log suspect operations.") DEFINE_bool(prof, false,"Log statistical profiling information (implies --log-code).") DEFINE_bool(prof_auto, true,"Used with --prof, starts profiling automatically") DEFINE_bool(prof_lazy, false,"Used with --prof, only does sampling and logging"" when profiler is active (implies --noprof_auto).") DEFINE_bool(prof_browser_mode, true,"Used with --prof, turns on browser-compatible mode for profiling.") DEFINE_bool(log_regexp, false,"Log regular expression execution.") DEFINE_bool(sliding_state_window, false,"Update sliding state window counters.") DEFINE_string(logfile,"v8.log","Specify the name of the log file.") DEFINE_bool(ll_prof, false,"Enable low-level linux profiler.")#define FLAG DEFINE_bool(trace_elements_transitions, false,"trace elements transitions") DEFINE_bool(print_code_stubs, false,"print code stubs") DEFINE_bool(test_secondary_stub_cache, false,"test secondary stub cache by disabling the primary one") DEFINE_bool(test_primary_stub_cache, false,"test primary stub cache by disabling the secondary one") DEFINE_bool(print_code, false,"print generated code") DEFINE_bool(print_opt_code, false,"print optimized code") DEFINE_bool(print_unopt_code, false,"print unoptimized code before ""printing optimized code based on it") DEFINE_bool(print_code_verbose, false,"print more information for code") DEFINE_bool(print_builtin_code, false,"print generated code for builtins")#47"/Users/thlorenz/dev/dx/v8-perf/build/v8/src/flags.cc"2 namespace{struct Flag{enum FlagType{TYPE_BOOL, TYPE_INT, TYPE_FLOAT, TYPE_STRING, TYPE_ARGS} name
Definition: flags.cc:1349
static V8EXPORT Local< String > New(const char *data, int length=-1)
Definition: api.cc:4655
v8::Handle< v8::Value > Print(const v8::Arguments &args)
#define CHECK(condition)
Definition: checks.h:56
V8EXPORT bool Equals(Handle< Value > that) const
Definition: api.cc:2676
T * start() const
Definition: utils.h:389
static void StartProfiling(Handle< String > title)
Definition: api.cc:5952
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination trace on stack replacement optimize closures functions with arguments object optimize functions containing for in loops profiler considers IC stability primitive functions trigger their own optimization re try self optimization if it failed insert an interrupt check at function exit execution budget before interrupt is triggered call count before self optimization self_optimization count_based_interrupts weighted_back_edges trace_opt emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 enable use of ARMv7 instructions if enable use of MIPS FPU instructions if NULL
static const int kNoGCFlags
Definition: heap.h:1049
int Length() const
Definition: v8.h:4143
const char * name() const
Definition: v8.h:2544
Definition: v8.h:104
static Vector< T > New(int length)
Definition: utils.h:369
#define CHECK_NE(unexpected, value)
Definition: checks.h:223
TEST(TokenEnumerator)
static int SNPrintF(Vector< char > str, const char *format,...)
static v8::Handle< v8::Value > StopProfiling(const v8::Arguments &args)
static v8::Handle< v8::Value > StartProfiling(const v8::Arguments &args)
virtual v8::Handle< v8::FunctionTemplate > GetNativeFunction(v8::Handle< v8::String > name)
#define HEAP
Definition: isolate.h:1408
static const int kSamplingIntervalMs
Definition: log.h:302
Handle< Primitive > V8EXPORT Undefined()
Definition: api.cc:546
bool IsEmpty() const
Definition: v8.h:208
static Persistent< Context > New(ExtensionConfiguration *extensions=NULL, Handle< ObjectTemplate > global_template=Handle< ObjectTemplate >(), Handle< Value > global_object=Handle< Value >())
Definition: api.cc:4308
static const CpuProfile * StopProfiling(Handle< String > title, Handle< Value > security_token=Handle< Value >())
Definition: api.cc:5959
void DeleteArray(T *array)
Definition: allocation.h:91
Definition: v8.h:105
static v8::internal::Handle< v8::internal::TemplateInfo > OpenHandle(const Template *that)