blob: 239d8ae695106745f108324d914e09c2d5917a40 [file] [log] [blame]
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001// Copyright 2010 the V8 project authors. All rights reserved.
2//
3// Tests of profiles generator and utilities.
4
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00005#ifdef ENABLE_LOGGING_AND_PROFILING
lrn@chromium.org25156de2010-04-06 13:10:27 +00006
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00007#include "v8.h"
8#include "cpu-profiler-inl.h"
9#include "cctest.h"
10
11namespace i = v8::internal;
12
13using i::CodeEntry;
lrn@chromium.org25156de2010-04-06 13:10:27 +000014using i::CpuProfile;
vegorov@chromium.org26c16f82010-08-11 13:41:03 +000015using i::CpuProfiler;
whesse@chromium.orgcec079d2010-03-22 14:44:04 +000016using i::CpuProfilesCollection;
17using i::ProfileGenerator;
18using i::ProfileNode;
19using i::ProfilerEventsProcessor;
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +000020using i::TokenEnumerator;
whesse@chromium.orgcec079d2010-03-22 14:44:04 +000021
22
23TEST(StartStop) {
24 CpuProfilesCollection profiles;
25 ProfileGenerator generator(&profiles);
26 ProfilerEventsProcessor processor(&generator);
27 processor.Start();
28 while (!processor.running()) {
29 i::Thread::YieldCPU();
30 }
31 processor.Stop();
32 processor.Join();
33}
34
35static v8::Persistent<v8::Context> env;
36
37static void InitializeVM() {
38 if (env.IsEmpty()) env = v8::Context::New();
39 v8::HandleScope scope;
40 env->Enter();
41}
42
43static inline i::Address ToAddress(int n) {
44 return reinterpret_cast<i::Address>(n);
45}
46
47static void EnqueueTickSampleEvent(ProfilerEventsProcessor* proc,
48 i::Address frame1,
49 i::Address frame2 = NULL,
50 i::Address frame3 = NULL) {
51 i::TickSample* sample = proc->TickSampleEvent();
52 sample->pc = frame1;
53 sample->function = frame1;
54 sample->frames_count = 0;
55 if (frame2 != NULL) {
56 sample->stack[0] = frame2;
57 sample->frames_count = 1;
58 }
59 if (frame3 != NULL) {
60 sample->stack[1] = frame3;
61 sample->frames_count = 2;
62 }
63}
64
ager@chromium.org357bf652010-04-12 11:30:10 +000065namespace {
66
67class TestSetup {
68 public:
69 TestSetup()
70 : old_flag_prof_browser_mode_(i::FLAG_prof_browser_mode) {
71 i::FLAG_prof_browser_mode = false;
72 }
73
74 ~TestSetup() {
75 i::FLAG_prof_browser_mode = old_flag_prof_browser_mode_;
76 }
77
78 private:
79 bool old_flag_prof_browser_mode_;
80};
81
82} // namespace
83
whesse@chromium.orgcec079d2010-03-22 14:44:04 +000084TEST(CodeEvents) {
85 InitializeVM();
ager@chromium.org357bf652010-04-12 11:30:10 +000086 TestSetup test_setup;
whesse@chromium.orgcec079d2010-03-22 14:44:04 +000087 CpuProfilesCollection profiles;
lrn@chromium.org25156de2010-04-06 13:10:27 +000088 profiles.StartProfiling("", 1);
whesse@chromium.orgcec079d2010-03-22 14:44:04 +000089 ProfileGenerator generator(&profiles);
90 ProfilerEventsProcessor processor(&generator);
91 processor.Start();
whesse@chromium.orgcec079d2010-03-22 14:44:04 +000092 while (!processor.running()) {
93 i::Thread::YieldCPU();
94 }
95
96 // Enqueue code creation events.
97 i::HandleScope scope;
98 const char* aaa_str = "aaa";
99 i::Handle<i::String> aaa_name = i::Factory::NewStringFromAscii(
whesse@chromium.orgb6e43bb2010-04-14 09:36:28 +0000100 i::Vector<const char>(aaa_str, i::StrLength(aaa_str)));
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000101 processor.CodeCreateEvent(i::Logger::FUNCTION_TAG,
102 *aaa_name,
103 i::Heap::empty_string(),
104 0,
105 ToAddress(0x1000),
106 0x100);
107 processor.CodeCreateEvent(i::Logger::BUILTIN_TAG,
108 "bbb",
109 ToAddress(0x1200),
110 0x80);
111 processor.CodeCreateEvent(i::Logger::STUB_TAG, 5, ToAddress(0x1300), 0x10);
112 processor.CodeCreateEvent(i::Logger::BUILTIN_TAG,
113 "ddd",
114 ToAddress(0x1400),
115 0x80);
116 processor.CodeMoveEvent(ToAddress(0x1400), ToAddress(0x1500));
117 processor.CodeCreateEvent(i::Logger::STUB_TAG, 3, ToAddress(0x1600), 0x10);
118 processor.CodeDeleteEvent(ToAddress(0x1600));
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +0000119 processor.FunctionCreateEvent(ToAddress(0x1700), ToAddress(0x1000),
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +0000120 TokenEnumerator::kNoSecurityToken);
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000121 // Enqueue a tick event to enable code events processing.
122 EnqueueTickSampleEvent(&processor, ToAddress(0x1000));
123
124 processor.Stop();
125 processor.Join();
126
127 // Check the state of profile generator.
128 CodeEntry* entry1 = generator.code_map()->FindEntry(ToAddress(0x1000));
129 CHECK_NE(NULL, entry1);
130 CHECK_EQ(aaa_str, entry1->name());
131 CodeEntry* entry2 = generator.code_map()->FindEntry(ToAddress(0x1200));
132 CHECK_NE(NULL, entry2);
133 CHECK_EQ("bbb", entry2->name());
134 CodeEntry* entry3 = generator.code_map()->FindEntry(ToAddress(0x1300));
135 CHECK_NE(NULL, entry3);
lrn@chromium.org25156de2010-04-06 13:10:27 +0000136 CHECK_EQ("5", entry3->name());
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000137 CHECK_EQ(NULL, generator.code_map()->FindEntry(ToAddress(0x1400)));
138 CodeEntry* entry4 = generator.code_map()->FindEntry(ToAddress(0x1500));
139 CHECK_NE(NULL, entry4);
140 CHECK_EQ("ddd", entry4->name());
141 CHECK_EQ(NULL, generator.code_map()->FindEntry(ToAddress(0x1600)));
142 CodeEntry* entry5 = generator.code_map()->FindEntry(ToAddress(0x1700));
143 CHECK_NE(NULL, entry5);
144 CHECK_EQ(aaa_str, entry5->name());
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000145}
146
147
148template<typename T>
149static int CompareProfileNodes(const T* p1, const T* p2) {
150 return strcmp((*p1)->entry()->name(), (*p2)->entry()->name());
151}
152
153TEST(TickEvents) {
ager@chromium.org357bf652010-04-12 11:30:10 +0000154 TestSetup test_setup;
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000155 CpuProfilesCollection profiles;
lrn@chromium.org25156de2010-04-06 13:10:27 +0000156 profiles.StartProfiling("", 1);
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000157 ProfileGenerator generator(&profiles);
158 ProfilerEventsProcessor processor(&generator);
159 processor.Start();
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000160 while (!processor.running()) {
161 i::Thread::YieldCPU();
162 }
163
164 processor.CodeCreateEvent(i::Logger::BUILTIN_TAG,
165 "bbb",
166 ToAddress(0x1200),
167 0x80);
168 processor.CodeCreateEvent(i::Logger::STUB_TAG, 5, ToAddress(0x1300), 0x10);
169 processor.CodeCreateEvent(i::Logger::BUILTIN_TAG,
170 "ddd",
171 ToAddress(0x1400),
172 0x80);
173 EnqueueTickSampleEvent(&processor, ToAddress(0x1210));
174 EnqueueTickSampleEvent(&processor, ToAddress(0x1305), ToAddress(0x1220));
175 EnqueueTickSampleEvent(&processor,
176 ToAddress(0x1404),
177 ToAddress(0x1305),
178 ToAddress(0x1230));
179
180 processor.Stop();
181 processor.Join();
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +0000182 CpuProfile* profile =
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +0000183 profiles.StopProfiling(TokenEnumerator::kNoSecurityToken, "", 1);
lrn@chromium.org25156de2010-04-06 13:10:27 +0000184 CHECK_NE(NULL, profile);
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000185
186 // Check call trees.
lrn@chromium.org25156de2010-04-06 13:10:27 +0000187 const i::List<ProfileNode*>* top_down_root_children =
188 profile->top_down()->root()->children();
189 CHECK_EQ(1, top_down_root_children->length());
190 CHECK_EQ("bbb", top_down_root_children->last()->entry()->name());
191 const i::List<ProfileNode*>* top_down_bbb_children =
192 top_down_root_children->last()->children();
193 CHECK_EQ(1, top_down_bbb_children->length());
194 CHECK_EQ("5", top_down_bbb_children->last()->entry()->name());
195 const i::List<ProfileNode*>* top_down_stub_children =
196 top_down_bbb_children->last()->children();
197 CHECK_EQ(1, top_down_stub_children->length());
198 CHECK_EQ("ddd", top_down_stub_children->last()->entry()->name());
199 const i::List<ProfileNode*>* top_down_ddd_children =
200 top_down_stub_children->last()->children();
201 CHECK_EQ(0, top_down_ddd_children->length());
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000202
lrn@chromium.org25156de2010-04-06 13:10:27 +0000203 const i::List<ProfileNode*>* bottom_up_root_children_unsorted =
204 profile->bottom_up()->root()->children();
205 CHECK_EQ(3, bottom_up_root_children_unsorted->length());
206 i::List<ProfileNode*> bottom_up_root_children(3);
207 bottom_up_root_children.AddAll(*bottom_up_root_children_unsorted);
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000208 bottom_up_root_children.Sort(&CompareProfileNodes);
lrn@chromium.org25156de2010-04-06 13:10:27 +0000209 CHECK_EQ("5", bottom_up_root_children[0]->entry()->name());
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000210 CHECK_EQ("bbb", bottom_up_root_children[1]->entry()->name());
211 CHECK_EQ("ddd", bottom_up_root_children[2]->entry()->name());
lrn@chromium.org25156de2010-04-06 13:10:27 +0000212 const i::List<ProfileNode*>* bottom_up_stub_children =
213 bottom_up_root_children[0]->children();
214 CHECK_EQ(1, bottom_up_stub_children->length());
215 CHECK_EQ("bbb", bottom_up_stub_children->last()->entry()->name());
216 const i::List<ProfileNode*>* bottom_up_bbb_children =
217 bottom_up_root_children[1]->children();
218 CHECK_EQ(0, bottom_up_bbb_children->length());
219 const i::List<ProfileNode*>* bottom_up_ddd_children =
220 bottom_up_root_children[2]->children();
221 CHECK_EQ(1, bottom_up_ddd_children->length());
222 CHECK_EQ("5", bottom_up_ddd_children->last()->entry()->name());
223 const i::List<ProfileNode*>* bottom_up_ddd_stub_children =
224 bottom_up_ddd_children->last()->children();
225 CHECK_EQ(1, bottom_up_ddd_stub_children->length());
226 CHECK_EQ("bbb", bottom_up_ddd_stub_children->last()->entry()->name());
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000227}
lrn@chromium.org25156de2010-04-06 13:10:27 +0000228
vegorov@chromium.org26c16f82010-08-11 13:41:03 +0000229
230// http://crbug/51594
231// This test must not crash.
232TEST(CrashIfStoppingLastNonExistentProfile) {
233 InitializeVM();
234 TestSetup test_setup;
235 CpuProfiler::Setup();
236 CpuProfiler::StartProfiling("1");
237 CpuProfiler::StopProfiling("2");
238 CpuProfiler::StartProfiling("1");
239 CpuProfiler::StopProfiling("");
240 CpuProfiler::TearDown();
241}
242
ricow@chromium.orgc9c80822010-04-21 08:22:37 +0000243#endif // ENABLE_LOGGING_AND_PROFILING