OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 ~TestSetup() { | 90 ~TestSetup() { |
91 i::FLAG_prof_browser_mode = old_flag_prof_browser_mode_; | 91 i::FLAG_prof_browser_mode = old_flag_prof_browser_mode_; |
92 } | 92 } |
93 | 93 |
94 private: | 94 private: |
95 bool old_flag_prof_browser_mode_; | 95 bool old_flag_prof_browser_mode_; |
96 }; | 96 }; |
97 | 97 |
98 } // namespace | 98 } // namespace |
99 | 99 |
100 | |
101 i::Code* CreateCode(LocalContext* env) { | |
102 static int counter = 0; | |
103 char script[256]; | |
104 char name[32]; | |
105 snprintf(name, sizeof(name), "function_%d", ++counter); | |
106 snprintf(script, sizeof(script), | |
107 "function %s() {\n" | |
108 "var counter = 0;\n" | |
109 "for (var i = 0; i < %d; ++i) counter += i;\n" | |
110 "return '%s_' + counter;\n" | |
111 "}\n" | |
112 "%s();\n", name, counter, name, name); | |
113 CompileRun(script); | |
114 i::Handle<i::JSFunction> fun = v8::Utils::OpenHandle( | |
115 *v8::Local<v8::Function>::Cast((*env)->Global()->Get(v8_str(name)))); | |
116 fprintf(stderr, "code size: %d\n", fun->code()->ExecutableSize()); | |
117 return fun->code(); | |
118 } | |
119 | |
120 | |
121 TEST(CodeEvents) { | 100 TEST(CodeEvents) { |
122 CcTest::InitializeVM(); | 101 CcTest::InitializeVM(); |
123 LocalContext env; | |
124 i::Isolate* isolate = i::Isolate::Current(); | 102 i::Isolate* isolate = i::Isolate::Current(); |
| 103 i::Heap* heap = isolate->heap(); |
125 i::Factory* factory = isolate->factory(); | 104 i::Factory* factory = isolate->factory(); |
126 TestSetup test_setup; | 105 TestSetup test_setup; |
127 | 106 CpuProfilesCollection profiles; |
128 i::HandleScope scope(isolate); | 107 profiles.StartProfiling("", 1, false); |
129 | 108 ProfileGenerator generator(&profiles); |
130 i::Code* aaa_code = CreateCode(&env); | 109 ProfilerEventsProcessor processor(&generator, &profiles); |
131 i::Code* comment_code = CreateCode(&env); | |
132 i::Code* args5_code = CreateCode(&env); | |
133 i::Code* comment2_code = CreateCode(&env); | |
134 i::Code* moved_code = CreateCode(&env); | |
135 i::Code* args3_code = CreateCode(&env); | |
136 i::Code* args4_code = CreateCode(&env); | |
137 | |
138 CpuProfilesCollection* profiles = new CpuProfilesCollection; | |
139 profiles->StartProfiling("", 1, false); | |
140 ProfileGenerator generator(profiles); | |
141 ProfilerEventsProcessor processor(&generator, profiles); | |
142 processor.Start(); | 110 processor.Start(); |
143 CpuProfiler profiler(isolate, profiles, &generator, &processor); | |
144 | 111 |
145 // Enqueue code creation events. | 112 // Enqueue code creation events. |
| 113 i::HandleScope scope(isolate); |
146 const char* aaa_str = "aaa"; | 114 const char* aaa_str = "aaa"; |
147 i::Handle<i::String> aaa_name = factory->NewStringFromAscii( | 115 i::Handle<i::String> aaa_name = factory->NewStringFromAscii( |
148 i::Vector<const char>(aaa_str, i::StrLength(aaa_str))); | 116 i::Vector<const char>(aaa_str, i::StrLength(aaa_str))); |
149 profiler.CodeCreateEvent(i::Logger::FUNCTION_TAG, aaa_code, *aaa_name); | 117 processor.CodeCreateEvent(i::Logger::FUNCTION_TAG, |
150 profiler.CodeCreateEvent(i::Logger::BUILTIN_TAG, comment_code, "comment"); | 118 *aaa_name, |
151 profiler.CodeCreateEvent(i::Logger::STUB_TAG, args5_code, 5); | 119 heap->empty_string(), |
152 profiler.CodeCreateEvent(i::Logger::BUILTIN_TAG, comment2_code, "comment2"); | 120 0, |
153 profiler.CodeMoveEvent(comment2_code->address(), moved_code->address()); | 121 ToAddress(0x1000), |
154 profiler.CodeCreateEvent(i::Logger::STUB_TAG, args3_code, 3); | 122 0x100, |
155 profiler.CodeCreateEvent(i::Logger::STUB_TAG, args4_code, 4); | 123 ToAddress(0x10000), |
156 | 124 NULL); |
| 125 processor.CodeCreateEvent(i::Logger::BUILTIN_TAG, |
| 126 "bbb", |
| 127 ToAddress(0x1200), |
| 128 0x80); |
| 129 processor.CodeCreateEvent(i::Logger::STUB_TAG, 5, ToAddress(0x1300), 0x10); |
| 130 processor.CodeCreateEvent(i::Logger::BUILTIN_TAG, |
| 131 "ddd", |
| 132 ToAddress(0x1400), |
| 133 0x80); |
| 134 processor.CodeMoveEvent(ToAddress(0x1400), ToAddress(0x1500)); |
| 135 processor.CodeCreateEvent(i::Logger::STUB_TAG, 3, ToAddress(0x1600), 0x10); |
| 136 processor.CodeCreateEvent(i::Logger::STUB_TAG, 4, ToAddress(0x1605), 0x10); |
157 // Enqueue a tick event to enable code events processing. | 137 // Enqueue a tick event to enable code events processing. |
158 EnqueueTickSampleEvent(&processor, aaa_code->address()); | 138 EnqueueTickSampleEvent(&processor, ToAddress(0x1000)); |
159 | 139 |
160 processor.Stop(); | 140 processor.Stop(); |
161 processor.Join(); | 141 processor.Join(); |
162 | 142 |
163 // Check the state of profile generator. | 143 // Check the state of profile generator. |
164 CodeEntry* aaa = generator.code_map()->FindEntry(aaa_code->address()); | 144 CodeEntry* entry1 = generator.code_map()->FindEntry(ToAddress(0x1000)); |
165 CHECK_NE(NULL, aaa); | 145 CHECK_NE(NULL, entry1); |
166 CHECK_EQ(aaa_str, aaa->name()); | 146 CHECK_EQ(aaa_str, entry1->name()); |
167 | 147 CodeEntry* entry2 = generator.code_map()->FindEntry(ToAddress(0x1200)); |
168 CodeEntry* comment = generator.code_map()->FindEntry(comment_code->address()); | 148 CHECK_NE(NULL, entry2); |
169 CHECK_NE(NULL, comment); | 149 CHECK_EQ("bbb", entry2->name()); |
170 CHECK_EQ("comment", comment->name()); | 150 CodeEntry* entry3 = generator.code_map()->FindEntry(ToAddress(0x1300)); |
171 | 151 CHECK_NE(NULL, entry3); |
172 CodeEntry* args5 = generator.code_map()->FindEntry(args5_code->address()); | 152 CHECK_EQ("5", entry3->name()); |
173 CHECK_NE(NULL, args5); | 153 CHECK_EQ(NULL, generator.code_map()->FindEntry(ToAddress(0x1400))); |
174 CHECK_EQ("5", args5->name()); | 154 CodeEntry* entry4 = generator.code_map()->FindEntry(ToAddress(0x1500)); |
175 | 155 CHECK_NE(NULL, entry4); |
176 CHECK_EQ(NULL, generator.code_map()->FindEntry(comment2_code->address())); | 156 CHECK_EQ("ddd", entry4->name()); |
177 | 157 CHECK_EQ(NULL, generator.code_map()->FindEntry(ToAddress(0x1600))); |
178 CodeEntry* comment2 = generator.code_map()->FindEntry(moved_code->address()); | |
179 CHECK_NE(NULL, comment2); | |
180 CHECK_EQ("comment2", comment2->name()); | |
181 } | 158 } |
182 | 159 |
183 | 160 |
184 template<typename T> | 161 template<typename T> |
185 static int CompareProfileNodes(const T* p1, const T* p2) { | 162 static int CompareProfileNodes(const T* p1, const T* p2) { |
186 return strcmp((*p1)->entry()->name(), (*p2)->entry()->name()); | 163 return strcmp((*p1)->entry()->name(), (*p2)->entry()->name()); |
187 } | 164 } |
188 | 165 |
189 TEST(TickEvents) { | 166 TEST(TickEvents) { |
190 TestSetup test_setup; | 167 TestSetup test_setup; |
191 LocalContext env; | 168 CpuProfilesCollection profiles; |
192 i::Isolate* isolate = i::Isolate::Current(); | 169 profiles.StartProfiling("", 1, false); |
193 i::HandleScope scope(isolate); | 170 ProfileGenerator generator(&profiles); |
| 171 ProfilerEventsProcessor processor(&generator, &profiles); |
| 172 processor.Start(); |
194 | 173 |
195 i::Code* frame1_code = CreateCode(&env); | 174 processor.CodeCreateEvent(i::Logger::BUILTIN_TAG, |
196 i::Code* frame2_code = CreateCode(&env); | 175 "bbb", |
197 i::Code* frame3_code = CreateCode(&env); | 176 ToAddress(0x1200), |
198 | 177 0x80); |
199 CpuProfilesCollection* profiles = new CpuProfilesCollection; | 178 processor.CodeCreateEvent(i::Logger::STUB_TAG, 5, ToAddress(0x1300), 0x10); |
200 profiles->StartProfiling("", 1, false); | 179 processor.CodeCreateEvent(i::Logger::BUILTIN_TAG, |
201 ProfileGenerator generator(profiles); | 180 "ddd", |
202 ProfilerEventsProcessor processor(&generator, profiles); | 181 ToAddress(0x1400), |
203 processor.Start(); | 182 0x80); |
204 CpuProfiler profiler(isolate, profiles, &generator, &processor); | 183 EnqueueTickSampleEvent(&processor, ToAddress(0x1210)); |
205 | 184 EnqueueTickSampleEvent(&processor, ToAddress(0x1305), ToAddress(0x1220)); |
206 profiler.CodeCreateEvent(i::Logger::BUILTIN_TAG, frame1_code, "bbb"); | 185 EnqueueTickSampleEvent(&processor, |
207 profiler.CodeCreateEvent(i::Logger::STUB_TAG, frame2_code, 5); | 186 ToAddress(0x1404), |
208 profiler.CodeCreateEvent(i::Logger::BUILTIN_TAG, frame3_code, "ddd"); | 187 ToAddress(0x1305), |
209 | 188 ToAddress(0x1230)); |
210 EnqueueTickSampleEvent(&processor, frame1_code->instruction_start()); | |
211 EnqueueTickSampleEvent( | |
212 &processor, | |
213 frame2_code->instruction_start() + frame2_code->ExecutableSize() / 2, | |
214 frame1_code->instruction_start() + frame2_code->ExecutableSize() / 2); | |
215 EnqueueTickSampleEvent( | |
216 &processor, | |
217 frame3_code->instruction_end() - 1, | |
218 frame2_code->instruction_end() - 1, | |
219 frame1_code->instruction_end() - 1); | |
220 | 189 |
221 processor.Stop(); | 190 processor.Stop(); |
222 processor.Join(); | 191 processor.Join(); |
223 CpuProfile* profile = | 192 CpuProfile* profile = |
224 profiles->StopProfiling(TokenEnumerator::kNoSecurityToken, "", 1); | 193 profiles.StopProfiling(TokenEnumerator::kNoSecurityToken, "", 1); |
225 CHECK_NE(NULL, profile); | 194 CHECK_NE(NULL, profile); |
226 | 195 |
227 // Check call trees. | 196 // Check call trees. |
228 const i::List<ProfileNode*>* top_down_root_children = | 197 const i::List<ProfileNode*>* top_down_root_children = |
229 profile->top_down()->root()->children(); | 198 profile->top_down()->root()->children(); |
230 CHECK_EQ(1, top_down_root_children->length()); | 199 CHECK_EQ(1, top_down_root_children->length()); |
231 CHECK_EQ("bbb", top_down_root_children->last()->entry()->name()); | 200 CHECK_EQ("bbb", top_down_root_children->last()->entry()->name()); |
232 const i::List<ProfileNode*>* top_down_bbb_children = | 201 const i::List<ProfileNode*>* top_down_bbb_children = |
233 top_down_root_children->last()->children(); | 202 top_down_root_children->last()->children(); |
234 CHECK_EQ(1, top_down_bbb_children->length()); | 203 CHECK_EQ(1, top_down_bbb_children->length()); |
(...skipping 18 matching lines...) Expand all Loading... |
253 profiler->StopProfiling("2"); | 222 profiler->StopProfiling("2"); |
254 profiler->StartProfiling("1"); | 223 profiler->StartProfiling("1"); |
255 profiler->StopProfiling(""); | 224 profiler->StopProfiling(""); |
256 } | 225 } |
257 | 226 |
258 | 227 |
259 // http://code.google.com/p/v8/issues/detail?id=1398 | 228 // http://code.google.com/p/v8/issues/detail?id=1398 |
260 // Long stacks (exceeding max frames limit) must not be erased. | 229 // Long stacks (exceeding max frames limit) must not be erased. |
261 TEST(Issue1398) { | 230 TEST(Issue1398) { |
262 TestSetup test_setup; | 231 TestSetup test_setup; |
263 LocalContext env; | 232 CpuProfilesCollection profiles; |
264 i::Isolate* isolate = i::Isolate::Current(); | 233 profiles.StartProfiling("", 1, false); |
265 i::HandleScope scope(isolate); | 234 ProfileGenerator generator(&profiles); |
| 235 ProfilerEventsProcessor processor(&generator, &profiles); |
| 236 processor.Start(); |
266 | 237 |
267 i::Code* code = CreateCode(&env); | 238 processor.CodeCreateEvent(i::Logger::BUILTIN_TAG, |
268 | 239 "bbb", |
269 CpuProfilesCollection* profiles = new CpuProfilesCollection; | 240 ToAddress(0x1200), |
270 profiles->StartProfiling("", 1, false); | 241 0x80); |
271 ProfileGenerator generator(profiles); | |
272 ProfilerEventsProcessor processor(&generator, profiles); | |
273 processor.Start(); | |
274 CpuProfiler profiler(isolate, profiles, &generator, &processor); | |
275 | |
276 profiler.CodeCreateEvent(i::Logger::BUILTIN_TAG, code, "bbb"); | |
277 | 242 |
278 i::TickSample* sample = processor.TickSampleEvent(); | 243 i::TickSample* sample = processor.TickSampleEvent(); |
279 sample->pc = code->address(); | 244 sample->pc = ToAddress(0x1200); |
280 sample->tos = 0; | 245 sample->tos = 0; |
281 sample->frames_count = i::TickSample::kMaxFramesCount; | 246 sample->frames_count = i::TickSample::kMaxFramesCount; |
282 for (int i = 0; i < sample->frames_count; ++i) { | 247 for (int i = 0; i < sample->frames_count; ++i) { |
283 sample->stack[i] = code->address(); | 248 sample->stack[i] = ToAddress(0x1200); |
284 } | 249 } |
285 | 250 |
286 processor.Stop(); | 251 processor.Stop(); |
287 processor.Join(); | 252 processor.Join(); |
288 CpuProfile* profile = | 253 CpuProfile* profile = |
289 profiles->StopProfiling(TokenEnumerator::kNoSecurityToken, "", 1); | 254 profiles.StopProfiling(TokenEnumerator::kNoSecurityToken, "", 1); |
290 CHECK_NE(NULL, profile); | 255 CHECK_NE(NULL, profile); |
291 | 256 |
292 int actual_depth = 0; | 257 int actual_depth = 0; |
293 const ProfileNode* node = profile->top_down()->root(); | 258 const ProfileNode* node = profile->top_down()->root(); |
294 while (node->children()->length() > 0) { | 259 while (node->children()->length() > 0) { |
295 node = node->children()->last(); | 260 node = node->children()->last(); |
296 ++actual_depth; | 261 ++actual_depth; |
297 } | 262 } |
298 | 263 |
299 CHECK_EQ(1 + i::TickSample::kMaxFramesCount, actual_depth); // +1 for PC. | 264 CHECK_EQ(1 + i::TickSample::kMaxFramesCount, actual_depth); // +1 for PC. |
(...skipping 693 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
993 names[1] = v8::String::New(ProfileGenerator::kProgramEntryName); | 958 names[1] = v8::String::New(ProfileGenerator::kProgramEntryName); |
994 names[2] = v8::String::New("start"); | 959 names[2] = v8::String::New("start"); |
995 // Don't allow |foo| node to be at the top level. | 960 // Don't allow |foo| node to be at the top level. |
996 CheckChildrenNames(root, names); | 961 CheckChildrenNames(root, names); |
997 | 962 |
998 const v8::CpuProfileNode* startNode = GetChild(root, "start"); | 963 const v8::CpuProfileNode* startNode = GetChild(root, "start"); |
999 GetChild(startNode, "foo"); | 964 GetChild(startNode, "foo"); |
1000 | 965 |
1001 cpu_profiler->DeleteAllCpuProfiles(); | 966 cpu_profiler->DeleteAllCpuProfiles(); |
1002 } | 967 } |
OLD | NEW |