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