blob: 5e1b9f2a7f5316850a83627631e9ba4e0f024738 [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
lrn@chromium.org25156de2010-04-06 13:10:27 +00005#ifdef ENABLE_CPP_PROFILES_PROCESSOR
6
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
63TEST(CodeEvents) {
64 InitializeVM();
65 CpuProfilesCollection profiles;
lrn@chromium.org25156de2010-04-06 13:10:27 +000066 profiles.StartProfiling("", 1);
whesse@chromium.orgcec079d2010-03-22 14:44:04 +000067 ProfileGenerator generator(&profiles);
68 ProfilerEventsProcessor processor(&generator);
69 processor.Start();
whesse@chromium.orgcec079d2010-03-22 14:44:04 +000070 while (!processor.running()) {
71 i::Thread::YieldCPU();
72 }
73
74 // Enqueue code creation events.
75 i::HandleScope scope;
76 const char* aaa_str = "aaa";
77 i::Handle<i::String> aaa_name = i::Factory::NewStringFromAscii(
78 i::Vector<const char>(aaa_str, strlen(aaa_str)));
79 processor.CodeCreateEvent(i::Logger::FUNCTION_TAG,
80 *aaa_name,
81 i::Heap::empty_string(),
82 0,
83 ToAddress(0x1000),
84 0x100);
85 processor.CodeCreateEvent(i::Logger::BUILTIN_TAG,
86 "bbb",
87 ToAddress(0x1200),
88 0x80);
89 processor.CodeCreateEvent(i::Logger::STUB_TAG, 5, ToAddress(0x1300), 0x10);
90 processor.CodeCreateEvent(i::Logger::BUILTIN_TAG,
91 "ddd",
92 ToAddress(0x1400),
93 0x80);
94 processor.CodeMoveEvent(ToAddress(0x1400), ToAddress(0x1500));
95 processor.CodeCreateEvent(i::Logger::STUB_TAG, 3, ToAddress(0x1600), 0x10);
96 processor.CodeDeleteEvent(ToAddress(0x1600));
97 processor.FunctionCreateEvent(ToAddress(0x1700), ToAddress(0x1000));
98 // Enqueue a tick event to enable code events processing.
99 EnqueueTickSampleEvent(&processor, ToAddress(0x1000));
100
101 processor.Stop();
102 processor.Join();
103
104 // Check the state of profile generator.
105 CodeEntry* entry1 = generator.code_map()->FindEntry(ToAddress(0x1000));
106 CHECK_NE(NULL, entry1);
107 CHECK_EQ(aaa_str, entry1->name());
108 CodeEntry* entry2 = generator.code_map()->FindEntry(ToAddress(0x1200));
109 CHECK_NE(NULL, entry2);
110 CHECK_EQ("bbb", entry2->name());
111 CodeEntry* entry3 = generator.code_map()->FindEntry(ToAddress(0x1300));
112 CHECK_NE(NULL, entry3);
lrn@chromium.org25156de2010-04-06 13:10:27 +0000113 CHECK_EQ("5", entry3->name());
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000114 CHECK_EQ(NULL, generator.code_map()->FindEntry(ToAddress(0x1400)));
115 CodeEntry* entry4 = generator.code_map()->FindEntry(ToAddress(0x1500));
116 CHECK_NE(NULL, entry4);
117 CHECK_EQ("ddd", entry4->name());
118 CHECK_EQ(NULL, generator.code_map()->FindEntry(ToAddress(0x1600)));
119 CodeEntry* entry5 = generator.code_map()->FindEntry(ToAddress(0x1700));
120 CHECK_NE(NULL, entry5);
121 CHECK_EQ(aaa_str, entry5->name());
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000122}
123
124
125template<typename T>
126static int CompareProfileNodes(const T* p1, const T* p2) {
127 return strcmp((*p1)->entry()->name(), (*p2)->entry()->name());
128}
129
130TEST(TickEvents) {
131 CpuProfilesCollection profiles;
lrn@chromium.org25156de2010-04-06 13:10:27 +0000132 profiles.StartProfiling("", 1);
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000133 ProfileGenerator generator(&profiles);
134 ProfilerEventsProcessor processor(&generator);
135 processor.Start();
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000136 while (!processor.running()) {
137 i::Thread::YieldCPU();
138 }
139
140 processor.CodeCreateEvent(i::Logger::BUILTIN_TAG,
141 "bbb",
142 ToAddress(0x1200),
143 0x80);
144 processor.CodeCreateEvent(i::Logger::STUB_TAG, 5, ToAddress(0x1300), 0x10);
145 processor.CodeCreateEvent(i::Logger::BUILTIN_TAG,
146 "ddd",
147 ToAddress(0x1400),
148 0x80);
149 EnqueueTickSampleEvent(&processor, ToAddress(0x1210));
150 EnqueueTickSampleEvent(&processor, ToAddress(0x1305), ToAddress(0x1220));
151 EnqueueTickSampleEvent(&processor,
152 ToAddress(0x1404),
153 ToAddress(0x1305),
154 ToAddress(0x1230));
155
156 processor.Stop();
157 processor.Join();
lrn@chromium.org25156de2010-04-06 13:10:27 +0000158 CpuProfile* profile = profiles.StopProfiling("");
159 CHECK_NE(NULL, profile);
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000160
161 // Check call trees.
lrn@chromium.org25156de2010-04-06 13:10:27 +0000162 const i::List<ProfileNode*>* top_down_root_children =
163 profile->top_down()->root()->children();
164 CHECK_EQ(1, top_down_root_children->length());
165 CHECK_EQ("bbb", top_down_root_children->last()->entry()->name());
166 const i::List<ProfileNode*>* top_down_bbb_children =
167 top_down_root_children->last()->children();
168 CHECK_EQ(1, top_down_bbb_children->length());
169 CHECK_EQ("5", top_down_bbb_children->last()->entry()->name());
170 const i::List<ProfileNode*>* top_down_stub_children =
171 top_down_bbb_children->last()->children();
172 CHECK_EQ(1, top_down_stub_children->length());
173 CHECK_EQ("ddd", top_down_stub_children->last()->entry()->name());
174 const i::List<ProfileNode*>* top_down_ddd_children =
175 top_down_stub_children->last()->children();
176 CHECK_EQ(0, top_down_ddd_children->length());
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000177
lrn@chromium.org25156de2010-04-06 13:10:27 +0000178 const i::List<ProfileNode*>* bottom_up_root_children_unsorted =
179 profile->bottom_up()->root()->children();
180 CHECK_EQ(3, bottom_up_root_children_unsorted->length());
181 i::List<ProfileNode*> bottom_up_root_children(3);
182 bottom_up_root_children.AddAll(*bottom_up_root_children_unsorted);
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000183 bottom_up_root_children.Sort(&CompareProfileNodes);
lrn@chromium.org25156de2010-04-06 13:10:27 +0000184 CHECK_EQ("5", bottom_up_root_children[0]->entry()->name());
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000185 CHECK_EQ("bbb", bottom_up_root_children[1]->entry()->name());
186 CHECK_EQ("ddd", bottom_up_root_children[2]->entry()->name());
lrn@chromium.org25156de2010-04-06 13:10:27 +0000187 const i::List<ProfileNode*>* bottom_up_stub_children =
188 bottom_up_root_children[0]->children();
189 CHECK_EQ(1, bottom_up_stub_children->length());
190 CHECK_EQ("bbb", bottom_up_stub_children->last()->entry()->name());
191 const i::List<ProfileNode*>* bottom_up_bbb_children =
192 bottom_up_root_children[1]->children();
193 CHECK_EQ(0, bottom_up_bbb_children->length());
194 const i::List<ProfileNode*>* bottom_up_ddd_children =
195 bottom_up_root_children[2]->children();
196 CHECK_EQ(1, bottom_up_ddd_children->length());
197 CHECK_EQ("5", bottom_up_ddd_children->last()->entry()->name());
198 const i::List<ProfileNode*>* bottom_up_ddd_stub_children =
199 bottom_up_ddd_children->last()->children();
200 CHECK_EQ(1, bottom_up_ddd_stub_children->length());
201 CHECK_EQ("bbb", bottom_up_ddd_stub_children->last()->entry()->name());
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000202}
lrn@chromium.org25156de2010-04-06 13:10:27 +0000203
204#endif // ENABLE_CPP_PROFILES_PROCESSOR