blob: f587fc8a17baf3588cac6dd9b7d90afd68acdf31 [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;
whesse@chromium.orgcec079d2010-03-22 14:44:04 +000015using i::CpuProfilesCollection;
16using i::ProfileGenerator;
17using i::ProfileNode;
18using i::ProfilerEventsProcessor;
19
20
21TEST(StartStop) {
22 CpuProfilesCollection profiles;
23 ProfileGenerator generator(&profiles);
24 ProfilerEventsProcessor processor(&generator);
25 processor.Start();
26 while (!processor.running()) {
27 i::Thread::YieldCPU();
28 }
29 processor.Stop();
30 processor.Join();
31}
32
33static v8::Persistent<v8::Context> env;
34
35static void InitializeVM() {
36 if (env.IsEmpty()) env = v8::Context::New();
37 v8::HandleScope scope;
38 env->Enter();
39}
40
41static inline i::Address ToAddress(int n) {
42 return reinterpret_cast<i::Address>(n);
43}
44
45static void EnqueueTickSampleEvent(ProfilerEventsProcessor* proc,
46 i::Address frame1,
47 i::Address frame2 = NULL,
48 i::Address frame3 = NULL) {
49 i::TickSample* sample = proc->TickSampleEvent();
50 sample->pc = frame1;
51 sample->function = frame1;
52 sample->frames_count = 0;
53 if (frame2 != NULL) {
54 sample->stack[0] = frame2;
55 sample->frames_count = 1;
56 }
57 if (frame3 != NULL) {
58 sample->stack[1] = frame3;
59 sample->frames_count = 2;
60 }
61}
62
ager@chromium.org357bf652010-04-12 11:30:10 +000063namespace {
64
65class TestSetup {
66 public:
67 TestSetup()
68 : old_flag_prof_browser_mode_(i::FLAG_prof_browser_mode) {
69 i::FLAG_prof_browser_mode = false;
70 }
71
72 ~TestSetup() {
73 i::FLAG_prof_browser_mode = old_flag_prof_browser_mode_;
74 }
75
76 private:
77 bool old_flag_prof_browser_mode_;
78};
79
80} // namespace
81
whesse@chromium.orgcec079d2010-03-22 14:44:04 +000082TEST(CodeEvents) {
83 InitializeVM();
ager@chromium.org357bf652010-04-12 11:30:10 +000084 TestSetup test_setup;
whesse@chromium.orgcec079d2010-03-22 14:44:04 +000085 CpuProfilesCollection profiles;
lrn@chromium.org25156de2010-04-06 13:10:27 +000086 profiles.StartProfiling("", 1);
whesse@chromium.orgcec079d2010-03-22 14:44:04 +000087 ProfileGenerator generator(&profiles);
88 ProfilerEventsProcessor processor(&generator);
89 processor.Start();
whesse@chromium.orgcec079d2010-03-22 14:44:04 +000090 while (!processor.running()) {
91 i::Thread::YieldCPU();
92 }
93
94 // Enqueue code creation events.
95 i::HandleScope scope;
96 const char* aaa_str = "aaa";
97 i::Handle<i::String> aaa_name = i::Factory::NewStringFromAscii(
whesse@chromium.orgb6e43bb2010-04-14 09:36:28 +000098 i::Vector<const char>(aaa_str, i::StrLength(aaa_str)));
whesse@chromium.orgcec079d2010-03-22 14:44:04 +000099 processor.CodeCreateEvent(i::Logger::FUNCTION_TAG,
100 *aaa_name,
101 i::Heap::empty_string(),
102 0,
103 ToAddress(0x1000),
104 0x100);
105 processor.CodeCreateEvent(i::Logger::BUILTIN_TAG,
106 "bbb",
107 ToAddress(0x1200),
108 0x80);
109 processor.CodeCreateEvent(i::Logger::STUB_TAG, 5, ToAddress(0x1300), 0x10);
110 processor.CodeCreateEvent(i::Logger::BUILTIN_TAG,
111 "ddd",
112 ToAddress(0x1400),
113 0x80);
114 processor.CodeMoveEvent(ToAddress(0x1400), ToAddress(0x1500));
115 processor.CodeCreateEvent(i::Logger::STUB_TAG, 3, ToAddress(0x1600), 0x10);
116 processor.CodeDeleteEvent(ToAddress(0x1600));
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +0000117 processor.FunctionCreateEvent(ToAddress(0x1700), ToAddress(0x1000),
118 CodeEntry::kNoSecurityToken);
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000119 // Enqueue a tick event to enable code events processing.
120 EnqueueTickSampleEvent(&processor, ToAddress(0x1000));
121
122 processor.Stop();
123 processor.Join();
124
125 // Check the state of profile generator.
126 CodeEntry* entry1 = generator.code_map()->FindEntry(ToAddress(0x1000));
127 CHECK_NE(NULL, entry1);
128 CHECK_EQ(aaa_str, entry1->name());
129 CodeEntry* entry2 = generator.code_map()->FindEntry(ToAddress(0x1200));
130 CHECK_NE(NULL, entry2);
131 CHECK_EQ("bbb", entry2->name());
132 CodeEntry* entry3 = generator.code_map()->FindEntry(ToAddress(0x1300));
133 CHECK_NE(NULL, entry3);
lrn@chromium.org25156de2010-04-06 13:10:27 +0000134 CHECK_EQ("5", entry3->name());
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000135 CHECK_EQ(NULL, generator.code_map()->FindEntry(ToAddress(0x1400)));
136 CodeEntry* entry4 = generator.code_map()->FindEntry(ToAddress(0x1500));
137 CHECK_NE(NULL, entry4);
138 CHECK_EQ("ddd", entry4->name());
139 CHECK_EQ(NULL, generator.code_map()->FindEntry(ToAddress(0x1600)));
140 CodeEntry* entry5 = generator.code_map()->FindEntry(ToAddress(0x1700));
141 CHECK_NE(NULL, entry5);
142 CHECK_EQ(aaa_str, entry5->name());
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000143}
144
145
146template<typename T>
147static int CompareProfileNodes(const T* p1, const T* p2) {
148 return strcmp((*p1)->entry()->name(), (*p2)->entry()->name());
149}
150
151TEST(TickEvents) {
ager@chromium.org357bf652010-04-12 11:30:10 +0000152 TestSetup test_setup;
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000153 CpuProfilesCollection profiles;
lrn@chromium.org25156de2010-04-06 13:10:27 +0000154 profiles.StartProfiling("", 1);
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000155 ProfileGenerator generator(&profiles);
156 ProfilerEventsProcessor processor(&generator);
157 processor.Start();
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000158 while (!processor.running()) {
159 i::Thread::YieldCPU();
160 }
161
162 processor.CodeCreateEvent(i::Logger::BUILTIN_TAG,
163 "bbb",
164 ToAddress(0x1200),
165 0x80);
166 processor.CodeCreateEvent(i::Logger::STUB_TAG, 5, ToAddress(0x1300), 0x10);
167 processor.CodeCreateEvent(i::Logger::BUILTIN_TAG,
168 "ddd",
169 ToAddress(0x1400),
170 0x80);
171 EnqueueTickSampleEvent(&processor, ToAddress(0x1210));
172 EnqueueTickSampleEvent(&processor, ToAddress(0x1305), ToAddress(0x1220));
173 EnqueueTickSampleEvent(&processor,
174 ToAddress(0x1404),
175 ToAddress(0x1305),
176 ToAddress(0x1230));
177
178 processor.Stop();
179 processor.Join();
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +0000180 CpuProfile* profile =
181 profiles.StopProfiling(CodeEntry::kNoSecurityToken, "", 1);
lrn@chromium.org25156de2010-04-06 13:10:27 +0000182 CHECK_NE(NULL, profile);
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000183
184 // Check call trees.
lrn@chromium.org25156de2010-04-06 13:10:27 +0000185 const i::List<ProfileNode*>* top_down_root_children =
186 profile->top_down()->root()->children();
187 CHECK_EQ(1, top_down_root_children->length());
188 CHECK_EQ("bbb", top_down_root_children->last()->entry()->name());
189 const i::List<ProfileNode*>* top_down_bbb_children =
190 top_down_root_children->last()->children();
191 CHECK_EQ(1, top_down_bbb_children->length());
192 CHECK_EQ("5", top_down_bbb_children->last()->entry()->name());
193 const i::List<ProfileNode*>* top_down_stub_children =
194 top_down_bbb_children->last()->children();
195 CHECK_EQ(1, top_down_stub_children->length());
196 CHECK_EQ("ddd", top_down_stub_children->last()->entry()->name());
197 const i::List<ProfileNode*>* top_down_ddd_children =
198 top_down_stub_children->last()->children();
199 CHECK_EQ(0, top_down_ddd_children->length());
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000200
lrn@chromium.org25156de2010-04-06 13:10:27 +0000201 const i::List<ProfileNode*>* bottom_up_root_children_unsorted =
202 profile->bottom_up()->root()->children();
203 CHECK_EQ(3, bottom_up_root_children_unsorted->length());
204 i::List<ProfileNode*> bottom_up_root_children(3);
205 bottom_up_root_children.AddAll(*bottom_up_root_children_unsorted);
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000206 bottom_up_root_children.Sort(&CompareProfileNodes);
lrn@chromium.org25156de2010-04-06 13:10:27 +0000207 CHECK_EQ("5", bottom_up_root_children[0]->entry()->name());
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000208 CHECK_EQ("bbb", bottom_up_root_children[1]->entry()->name());
209 CHECK_EQ("ddd", bottom_up_root_children[2]->entry()->name());
lrn@chromium.org25156de2010-04-06 13:10:27 +0000210 const i::List<ProfileNode*>* bottom_up_stub_children =
211 bottom_up_root_children[0]->children();
212 CHECK_EQ(1, bottom_up_stub_children->length());
213 CHECK_EQ("bbb", bottom_up_stub_children->last()->entry()->name());
214 const i::List<ProfileNode*>* bottom_up_bbb_children =
215 bottom_up_root_children[1]->children();
216 CHECK_EQ(0, bottom_up_bbb_children->length());
217 const i::List<ProfileNode*>* bottom_up_ddd_children =
218 bottom_up_root_children[2]->children();
219 CHECK_EQ(1, bottom_up_ddd_children->length());
220 CHECK_EQ("5", bottom_up_ddd_children->last()->entry()->name());
221 const i::List<ProfileNode*>* bottom_up_ddd_stub_children =
222 bottom_up_ddd_children->last()->children();
223 CHECK_EQ(1, bottom_up_ddd_stub_children->length());
224 CHECK_EQ("bbb", bottom_up_ddd_stub_children->last()->entry()->name());
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000225}
lrn@chromium.org25156de2010-04-06 13:10:27 +0000226
ricow@chromium.orgc9c80822010-04-21 08:22:37 +0000227#endif // ENABLE_LOGGING_AND_PROFILING