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 #include "v8.h" | 5 #include "v8.h" |
6 #include "cpu-profiler-inl.h" | 6 #include "cpu-profiler-inl.h" |
7 #include "cctest.h" | 7 #include "cctest.h" |
8 #include "platform.h" | |
9 #include "../include/v8-profiler.h" | 8 #include "../include/v8-profiler.h" |
10 | 9 |
11 using i::CodeEntry; | 10 using i::CodeEntry; |
12 using i::CpuProfile; | 11 using i::CpuProfile; |
13 using i::CpuProfiler; | 12 using i::CpuProfiler; |
14 using i::CpuProfilesCollection; | 13 using i::CpuProfilesCollection; |
15 using i::ProfileGenerator; | 14 using i::ProfileGenerator; |
16 using i::ProfileNode; | 15 using i::ProfileNode; |
17 using i::ProfilerEventsProcessor; | 16 using i::ProfilerEventsProcessor; |
18 using i::TokenEnumerator; | 17 using i::TokenEnumerator; |
19 | 18 |
20 | 19 |
21 TEST(StartStop) { | 20 TEST(StartStop) { |
22 CpuProfilesCollection profiles; | 21 CpuProfilesCollection profiles; |
23 ProfileGenerator generator(&profiles); | 22 ProfileGenerator generator(&profiles); |
24 ProfilerEventsProcessor processor(&generator, NULL, 1000); | 23 ProfilerEventsProcessor processor(&generator); |
25 processor.Start(); | 24 processor.Start(); |
26 processor.Stop(); | 25 processor.Stop(); |
27 processor.Join(); | 26 processor.Join(); |
28 } | 27 } |
29 | 28 |
30 static v8::Persistent<v8::Context> env; | 29 static v8::Persistent<v8::Context> env; |
31 | 30 |
32 static void InitializeVM() { | 31 static void InitializeVM() { |
33 if (env.IsEmpty()) env = v8::Context::New(); | 32 if (env.IsEmpty()) env = v8::Context::New(); |
34 v8::HandleScope scope; | 33 v8::HandleScope scope; |
35 env->Enter(); | 34 env->Enter(); |
36 } | 35 } |
37 | 36 |
38 static inline i::Address ToAddress(int n) { | 37 static inline i::Address ToAddress(int n) { |
39 return reinterpret_cast<i::Address>(n); | 38 return reinterpret_cast<i::Address>(n); |
40 } | 39 } |
41 | 40 |
42 static void AddTickSampleEvent(ProfilerEventsProcessor* processor, | 41 static void EnqueueTickSampleEvent(ProfilerEventsProcessor* proc, |
43 i::Address frame1, | 42 i::Address frame1, |
44 i::Address frame2 = NULL, | 43 i::Address frame2 = NULL, |
45 i::Address frame3 = NULL) { | 44 i::Address frame3 = NULL) { |
46 i::TickSample* sample; | 45 i::TickSample* sample = proc->TickSampleEvent(); |
47 i::OS::Sleep(20); | |
48 while ((sample = processor->StartTickSampleEvent()) == NULL) i::OS::Sleep(20); | |
49 sample->pc = frame1; | 46 sample->pc = frame1; |
50 sample->tos = frame1; | 47 sample->tos = frame1; |
51 sample->frames_count = 0; | 48 sample->frames_count = 0; |
52 if (frame2 != NULL) { | 49 if (frame2 != NULL) { |
53 sample->stack[0] = frame2; | 50 sample->stack[0] = frame2; |
54 sample->frames_count = 1; | 51 sample->frames_count = 1; |
55 } | 52 } |
56 if (frame3 != NULL) { | 53 if (frame3 != NULL) { |
57 sample->stack[1] = frame3; | 54 sample->stack[1] = frame3; |
58 sample->frames_count = 2; | 55 sample->frames_count = 2; |
59 } | 56 } |
60 processor->FinishTickSampleEvent(); | |
61 } | 57 } |
62 | 58 |
63 namespace { | 59 namespace { |
64 | 60 |
65 class TestSetup { | 61 class TestSetup { |
66 public: | 62 public: |
67 TestSetup() | 63 TestSetup() |
68 : old_flag_prof_browser_mode_(i::FLAG_prof_browser_mode) { | 64 : old_flag_prof_browser_mode_(i::FLAG_prof_browser_mode) { |
69 i::FLAG_prof_browser_mode = false; | 65 i::FLAG_prof_browser_mode = false; |
70 } | 66 } |
71 | 67 |
72 ~TestSetup() { | 68 ~TestSetup() { |
73 i::FLAG_prof_browser_mode = old_flag_prof_browser_mode_; | 69 i::FLAG_prof_browser_mode = old_flag_prof_browser_mode_; |
74 } | 70 } |
75 | 71 |
76 private: | 72 private: |
77 bool old_flag_prof_browser_mode_; | 73 bool old_flag_prof_browser_mode_; |
78 }; | 74 }; |
79 | 75 |
80 } // namespace | 76 } // namespace |
81 | 77 |
82 TEST(CodeEvents) { | 78 TEST(CodeEvents) { |
83 InitializeVM(); | 79 InitializeVM(); |
84 TestSetup test_setup; | 80 TestSetup test_setup; |
85 CpuProfilesCollection profiles; | 81 CpuProfilesCollection profiles; |
86 profiles.StartProfiling("", 1); | 82 profiles.StartProfiling("", 1); |
87 ProfileGenerator generator(&profiles); | 83 ProfileGenerator generator(&profiles); |
88 ProfilerEventsProcessor processor(&generator, NULL, 1000); | 84 ProfilerEventsProcessor processor(&generator); |
89 processor.Start(); | 85 processor.Start(); |
90 | 86 |
91 // Enqueue code creation events. | 87 // Enqueue code creation events. |
92 i::HandleScope scope; | 88 i::HandleScope scope; |
93 const char* aaa_str = "aaa"; | 89 const char* aaa_str = "aaa"; |
94 i::Handle<i::String> aaa_name = FACTORY->NewStringFromAscii( | 90 i::Handle<i::String> aaa_name = FACTORY->NewStringFromAscii( |
95 i::Vector<const char>(aaa_str, i::StrLength(aaa_str))); | 91 i::Vector<const char>(aaa_str, i::StrLength(aaa_str))); |
96 processor.CodeCreateEvent(i::Logger::FUNCTION_TAG, | 92 processor.CodeCreateEvent(i::Logger::FUNCTION_TAG, |
97 *aaa_name, | 93 *aaa_name, |
98 HEAP->empty_string(), | 94 HEAP->empty_string(), |
99 0, | 95 0, |
100 ToAddress(0x1000), | 96 ToAddress(0x1000), |
101 0x100, | 97 0x100, |
102 ToAddress(0x10000)); | 98 ToAddress(0x10000)); |
103 processor.CodeCreateEvent(i::Logger::BUILTIN_TAG, | 99 processor.CodeCreateEvent(i::Logger::BUILTIN_TAG, |
104 "bbb", | 100 "bbb", |
105 ToAddress(0x1200), | 101 ToAddress(0x1200), |
106 0x80); | 102 0x80); |
107 processor.CodeCreateEvent(i::Logger::STUB_TAG, 5, ToAddress(0x1300), 0x10); | 103 processor.CodeCreateEvent(i::Logger::STUB_TAG, 5, ToAddress(0x1300), 0x10); |
108 processor.CodeCreateEvent(i::Logger::BUILTIN_TAG, | 104 processor.CodeCreateEvent(i::Logger::BUILTIN_TAG, |
109 "ddd", | 105 "ddd", |
110 ToAddress(0x1400), | 106 ToAddress(0x1400), |
111 0x80); | 107 0x80); |
112 processor.CodeMoveEvent(ToAddress(0x1400), ToAddress(0x1500)); | 108 processor.CodeMoveEvent(ToAddress(0x1400), ToAddress(0x1500)); |
113 processor.CodeCreateEvent(i::Logger::STUB_TAG, 3, ToAddress(0x1600), 0x10); | 109 processor.CodeCreateEvent(i::Logger::STUB_TAG, 3, ToAddress(0x1600), 0x10); |
114 processor.CodeCreateEvent(i::Logger::STUB_TAG, 4, ToAddress(0x1605), 0x10); | 110 processor.CodeCreateEvent(i::Logger::STUB_TAG, 4, ToAddress(0x1605), 0x10); |
115 // Add a tick event to enable code events processing. | 111 // Enqueue a tick event to enable code events processing. |
116 AddTickSampleEvent(&processor, ToAddress(0x1000)); | 112 EnqueueTickSampleEvent(&processor, ToAddress(0x1000)); |
117 | 113 |
118 processor.Stop(); | 114 processor.Stop(); |
119 processor.Join(); | 115 processor.Join(); |
120 | 116 |
121 // Check the state of profile generator. | 117 // Check the state of profile generator. |
122 CodeEntry* entry1 = generator.code_map()->FindEntry(ToAddress(0x1000)); | 118 CodeEntry* entry1 = generator.code_map()->FindEntry(ToAddress(0x1000)); |
123 CHECK_NE(NULL, entry1); | 119 CHECK_NE(NULL, entry1); |
124 CHECK_EQ(aaa_str, entry1->name()); | 120 CHECK_EQ(aaa_str, entry1->name()); |
125 CodeEntry* entry2 = generator.code_map()->FindEntry(ToAddress(0x1200)); | 121 CodeEntry* entry2 = generator.code_map()->FindEntry(ToAddress(0x1200)); |
126 CHECK_NE(NULL, entry2); | 122 CHECK_NE(NULL, entry2); |
(...skipping 12 matching lines...) Expand all Loading... |
139 template<typename T> | 135 template<typename T> |
140 static int CompareProfileNodes(const T* p1, const T* p2) { | 136 static int CompareProfileNodes(const T* p1, const T* p2) { |
141 return strcmp((*p1)->entry()->name(), (*p2)->entry()->name()); | 137 return strcmp((*p1)->entry()->name(), (*p2)->entry()->name()); |
142 } | 138 } |
143 | 139 |
144 TEST(TickEvents) { | 140 TEST(TickEvents) { |
145 TestSetup test_setup; | 141 TestSetup test_setup; |
146 CpuProfilesCollection profiles; | 142 CpuProfilesCollection profiles; |
147 profiles.StartProfiling("", 1); | 143 profiles.StartProfiling("", 1); |
148 ProfileGenerator generator(&profiles); | 144 ProfileGenerator generator(&profiles); |
149 ProfilerEventsProcessor processor(&generator, NULL, 1000); | 145 ProfilerEventsProcessor processor(&generator); |
150 processor.Start(); | 146 processor.Start(); |
151 | 147 |
152 processor.CodeCreateEvent(i::Logger::BUILTIN_TAG, | 148 processor.CodeCreateEvent(i::Logger::BUILTIN_TAG, |
153 "bbb", | 149 "bbb", |
154 ToAddress(0x1200), | 150 ToAddress(0x1200), |
155 0x80); | 151 0x80); |
156 processor.CodeCreateEvent(i::Logger::STUB_TAG, 5, ToAddress(0x1300), 0x10); | 152 processor.CodeCreateEvent(i::Logger::STUB_TAG, 5, ToAddress(0x1300), 0x10); |
157 processor.CodeCreateEvent(i::Logger::BUILTIN_TAG, | 153 processor.CodeCreateEvent(i::Logger::BUILTIN_TAG, |
158 "ddd", | 154 "ddd", |
159 ToAddress(0x1400), | 155 ToAddress(0x1400), |
160 0x80); | 156 0x80); |
161 AddTickSampleEvent(&processor, ToAddress(0x1210)); | 157 EnqueueTickSampleEvent(&processor, ToAddress(0x1210)); |
162 AddTickSampleEvent(&processor, ToAddress(0x1305), ToAddress(0x1220)); | 158 EnqueueTickSampleEvent(&processor, ToAddress(0x1305), ToAddress(0x1220)); |
163 AddTickSampleEvent(&processor, | 159 EnqueueTickSampleEvent(&processor, |
164 ToAddress(0x1404), | 160 ToAddress(0x1404), |
165 ToAddress(0x1305), | 161 ToAddress(0x1305), |
166 ToAddress(0x1230)); | 162 ToAddress(0x1230)); |
167 | 163 |
168 processor.Stop(); | 164 processor.Stop(); |
169 processor.Join(); | 165 processor.Join(); |
170 CpuProfile* profile = | 166 CpuProfile* profile = |
171 profiles.StopProfiling(TokenEnumerator::kNoSecurityToken, "", 1); | 167 profiles.StopProfiling(TokenEnumerator::kNoSecurityToken, "", 1); |
172 CHECK_NE(NULL, profile); | 168 CHECK_NE(NULL, profile); |
173 | 169 |
174 // Check call trees. | 170 // Check call trees. |
175 const i::List<ProfileNode*>* top_down_root_children = | 171 const i::List<ProfileNode*>* top_down_root_children = |
176 profile->top_down()->root()->children(); | 172 profile->top_down()->root()->children(); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
229 } | 225 } |
230 | 226 |
231 | 227 |
232 // http://code.google.com/p/v8/issues/detail?id=1398 | 228 // http://code.google.com/p/v8/issues/detail?id=1398 |
233 // Long stacks (exceeding max frames limit) must not be erased. | 229 // Long stacks (exceeding max frames limit) must not be erased. |
234 TEST(Issue1398) { | 230 TEST(Issue1398) { |
235 TestSetup test_setup; | 231 TestSetup test_setup; |
236 CpuProfilesCollection profiles; | 232 CpuProfilesCollection profiles; |
237 profiles.StartProfiling("", 1); | 233 profiles.StartProfiling("", 1); |
238 ProfileGenerator generator(&profiles); | 234 ProfileGenerator generator(&profiles); |
239 ProfilerEventsProcessor processor(&generator, NULL, 1000); | 235 ProfilerEventsProcessor processor(&generator); |
240 processor.Start(); | 236 processor.Start(); |
241 | 237 |
242 processor.CodeCreateEvent(i::Logger::BUILTIN_TAG, | 238 processor.CodeCreateEvent(i::Logger::BUILTIN_TAG, |
243 "bbb", | 239 "bbb", |
244 ToAddress(0x1200), | 240 ToAddress(0x1200), |
245 0x80); | 241 0x80); |
246 | 242 |
247 i::TickSample* sample = processor.StartTickSampleEvent(); | 243 i::TickSample* sample = processor.TickSampleEvent(); |
248 sample->pc = ToAddress(0x1200); | 244 sample->pc = ToAddress(0x1200); |
249 sample->tos = 0; | 245 sample->tos = 0; |
250 sample->frames_count = i::TickSample::kMaxFramesCount; | 246 sample->frames_count = i::TickSample::kMaxFramesCount; |
251 for (int i = 0; i < sample->frames_count; ++i) { | 247 for (int i = 0; i < sample->frames_count; ++i) { |
252 sample->stack[i] = ToAddress(0x1200); | 248 sample->stack[i] = ToAddress(0x1200); |
253 } | 249 } |
254 processor.FinishTickSampleEvent(); | |
255 | 250 |
256 processor.Stop(); | 251 processor.Stop(); |
257 processor.Join(); | 252 processor.Join(); |
258 CpuProfile* profile = | 253 CpuProfile* profile = |
259 profiles.StopProfiling(TokenEnumerator::kNoSecurityToken, "", 1); | 254 profiles.StopProfiling(TokenEnumerator::kNoSecurityToken, "", 1); |
260 CHECK_NE(NULL, profile); | 255 CHECK_NE(NULL, profile); |
261 | 256 |
262 int actual_depth = 0; | 257 int actual_depth = 0; |
263 const ProfileNode* node = profile->top_down()->root(); | 258 const ProfileNode* node = profile->top_down()->root(); |
264 while (node->children()->length() > 0) { | 259 while (node->children()->length() > 0) { |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
395 CHECK_EQ(NULL, v8::CpuProfiler::FindProfile(uid2)); | 390 CHECK_EQ(NULL, v8::CpuProfiler::FindProfile(uid2)); |
396 CHECK_EQ(p3, v8::CpuProfiler::FindProfile(uid3)); | 391 CHECK_EQ(p3, v8::CpuProfiler::FindProfile(uid3)); |
397 const_cast<v8::CpuProfile*>(p2)->Delete(); | 392 const_cast<v8::CpuProfile*>(p2)->Delete(); |
398 CHECK_EQ(1, v8::CpuProfiler::GetProfilesCount()); | 393 CHECK_EQ(1, v8::CpuProfiler::GetProfilesCount()); |
399 CHECK_EQ(NULL, v8::CpuProfiler::FindProfile(uid2)); | 394 CHECK_EQ(NULL, v8::CpuProfiler::FindProfile(uid2)); |
400 CHECK_EQ(p3, v8::CpuProfiler::FindProfile(uid3)); | 395 CHECK_EQ(p3, v8::CpuProfiler::FindProfile(uid3)); |
401 const_cast<v8::CpuProfile*>(p3)->Delete(); | 396 const_cast<v8::CpuProfile*>(p3)->Delete(); |
402 CHECK_EQ(0, CpuProfiler::GetProfilesCount()); | 397 CHECK_EQ(0, CpuProfiler::GetProfilesCount()); |
403 CHECK_EQ(NULL, v8::CpuProfiler::FindProfile(uid3)); | 398 CHECK_EQ(NULL, v8::CpuProfiler::FindProfile(uid3)); |
404 } | 399 } |
OLD | NEW |