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 | |
100 TEST(CodeEvents) { | 121 TEST(CodeEvents) { |
101 CcTest::InitializeVM(); | 122 CcTest::InitializeVM(); |
123 LocalContext env; | |
102 i::Isolate* isolate = i::Isolate::Current(); | 124 i::Isolate* isolate = i::Isolate::Current(); |
103 i::Heap* heap = isolate->heap(); | |
104 i::Factory* factory = isolate->factory(); | 125 i::Factory* factory = isolate->factory(); |
105 TestSetup test_setup; | 126 TestSetup test_setup; |
106 CpuProfilesCollection profiles; | 127 |
107 profiles.StartProfiling("", 1, false); | 128 i::HandleScope scope(isolate); |
108 ProfileGenerator generator(&profiles); | 129 |
109 ProfilerEventsProcessor processor(&generator, &profiles); | 130 i::Code* aaa_code = CreateCode(&env); |
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); | |
110 processor.Start(); | 142 processor.Start(); |
143 CpuProfiler profiler(isolate, profiles, &generator, &processor); | |
111 | 144 |
112 // Enqueue code creation events. | 145 // Enqueue code creation events. |
113 i::HandleScope scope(isolate); | |
114 const char* aaa_str = "aaa"; | 146 const char* aaa_str = "aaa"; |
115 i::Handle<i::String> aaa_name = factory->NewStringFromAscii( | 147 i::Handle<i::String> aaa_name = factory->NewStringFromAscii( |
116 i::Vector<const char>(aaa_str, i::StrLength(aaa_str))); | 148 i::Vector<const char>(aaa_str, i::StrLength(aaa_str))); |
117 processor.CodeCreateEvent(i::Logger::FUNCTION_TAG, | 149 profiler.CodeCreateEvent(i::Logger::FUNCTION_TAG, aaa_code, *aaa_name); |
118 *aaa_name, | 150 profiler.CodeCreateEvent(i::Logger::BUILTIN_TAG, comment_code, "comment"); |
119 heap->empty_string(), | 151 profiler.CodeCreateEvent(i::Logger::STUB_TAG, args5_code, 5); |
120 0, | 152 profiler.CodeCreateEvent(i::Logger::BUILTIN_TAG, comment2_code, "comment2"); |
121 ToAddress(0x1000), | 153 profiler.CodeMoveEvent(comment2_code->address(), moved_code->address()); |
122 0x100, | 154 profiler.CodeCreateEvent(i::Logger::STUB_TAG, args3_code, 3); |
123 ToAddress(0x10000), | 155 profiler.CodeCreateEvent(i::Logger::STUB_TAG, args4_code, 4); |
124 NULL); | 156 |
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); | |
137 // Enqueue a tick event to enable code events processing. | 157 // Enqueue a tick event to enable code events processing. |
138 EnqueueTickSampleEvent(&processor, ToAddress(0x1000)); | 158 EnqueueTickSampleEvent(&processor, aaa_code->address()); |
139 | 159 |
140 processor.Stop(); | 160 processor.Stop(); |
141 processor.Join(); | 161 processor.Join(); |
142 | 162 |
143 // Check the state of profile generator. | 163 // Check the state of profile generator. |
144 CodeEntry* entry1 = generator.code_map()->FindEntry(ToAddress(0x1000)); | 164 CodeEntry* aaa = generator.code_map()->FindEntry(aaa_code->address()); |
145 CHECK_NE(NULL, entry1); | 165 CHECK_NE(NULL, aaa); |
146 CHECK_EQ(aaa_str, entry1->name()); | 166 CHECK_EQ(aaa_str, aaa->name()); |
147 CodeEntry* entry2 = generator.code_map()->FindEntry(ToAddress(0x1200)); | 167 |
148 CHECK_NE(NULL, entry2); | 168 CodeEntry* comment = generator.code_map()->FindEntry(comment_code->address()); |
149 CHECK_EQ("bbb", entry2->name()); | 169 CHECK_NE(NULL, comment); |
150 CodeEntry* entry3 = generator.code_map()->FindEntry(ToAddress(0x1300)); | 170 CHECK_EQ("comment", comment->name()); |
151 CHECK_NE(NULL, entry3); | 171 |
152 CHECK_EQ("5", entry3->name()); | 172 CodeEntry* args5 = generator.code_map()->FindEntry(args5_code->address()); |
153 CHECK_EQ(NULL, generator.code_map()->FindEntry(ToAddress(0x1400))); | 173 CHECK_NE(NULL, args5); |
154 CodeEntry* entry4 = generator.code_map()->FindEntry(ToAddress(0x1500)); | 174 CHECK_EQ("5", args5->name()); |
155 CHECK_NE(NULL, entry4); | 175 |
156 CHECK_EQ("ddd", entry4->name()); | 176 CHECK_EQ(NULL, generator.code_map()->FindEntry(comment2_code->address())); |
157 CHECK_EQ(NULL, generator.code_map()->FindEntry(ToAddress(0x1600))); | 177 |
178 CodeEntry* comment2 = generator.code_map()->FindEntry(moved_code->address()); | |
179 CHECK_NE(NULL, comment2); | |
180 CHECK_EQ("comment2", comment2->name()); | |
158 } | 181 } |
159 | 182 |
160 | 183 |
161 template<typename T> | 184 template<typename T> |
162 static int CompareProfileNodes(const T* p1, const T* p2) { | 185 static int CompareProfileNodes(const T* p1, const T* p2) { |
163 return strcmp((*p1)->entry()->name(), (*p2)->entry()->name()); | 186 return strcmp((*p1)->entry()->name(), (*p2)->entry()->name()); |
164 } | 187 } |
165 | 188 |
166 TEST(TickEvents) { | 189 TEST(TickEvents) { |
167 TestSetup test_setup; | 190 TestSetup test_setup; |
168 CpuProfilesCollection profiles; | 191 LocalContext env; |
169 profiles.StartProfiling("", 1, false); | 192 i::Isolate* isolate = i::Isolate::Current(); |
yurys
2013/06/28 12:53:43
env->GetIsolate()
| |
170 ProfileGenerator generator(&profiles); | 193 i::HandleScope scope(isolate); |
171 ProfilerEventsProcessor processor(&generator, &profiles); | 194 |
195 i::Code* frame1_code = CreateCode(&env); | |
196 i::Code* frame2_code = CreateCode(&env); | |
197 i::Code* frame3_code = CreateCode(&env); | |
198 | |
199 CpuProfilesCollection* profiles = new CpuProfilesCollection; | |
200 profiles->StartProfiling("", 1, false); | |
201 ProfileGenerator generator(profiles); | |
202 ProfilerEventsProcessor processor(&generator, profiles); | |
172 processor.Start(); | 203 processor.Start(); |
204 CpuProfiler profiler(isolate, profiles, &generator, &processor); | |
173 | 205 |
174 processor.CodeCreateEvent(i::Logger::BUILTIN_TAG, | 206 profiler.CodeCreateEvent(i::Logger::BUILTIN_TAG, frame1_code, "bbb"); |
175 "bbb", | 207 profiler.CodeCreateEvent(i::Logger::STUB_TAG, frame2_code, 5); |
176 ToAddress(0x1200), | 208 profiler.CodeCreateEvent(i::Logger::BUILTIN_TAG, frame3_code, "ddd"); |
177 0x80); | 209 |
178 processor.CodeCreateEvent(i::Logger::STUB_TAG, 5, ToAddress(0x1300), 0x10); | 210 EnqueueTickSampleEvent(&processor, frame1_code->instruction_start()); |
179 processor.CodeCreateEvent(i::Logger::BUILTIN_TAG, | 211 EnqueueTickSampleEvent( |
180 "ddd", | 212 &processor, |
181 ToAddress(0x1400), | 213 frame2_code->instruction_start() + frame2_code->ExecutableSize() / 2, |
182 0x80); | 214 frame1_code->instruction_start() + frame2_code->ExecutableSize() / 2); |
183 EnqueueTickSampleEvent(&processor, ToAddress(0x1210)); | 215 EnqueueTickSampleEvent( |
184 EnqueueTickSampleEvent(&processor, ToAddress(0x1305), ToAddress(0x1220)); | 216 &processor, |
185 EnqueueTickSampleEvent(&processor, | 217 frame3_code->instruction_end() - 1, |
186 ToAddress(0x1404), | 218 frame2_code->instruction_end() - 1, |
187 ToAddress(0x1305), | 219 frame1_code->instruction_end() - 1); |
188 ToAddress(0x1230)); | |
189 | 220 |
190 processor.Stop(); | 221 processor.Stop(); |
191 processor.Join(); | 222 processor.Join(); |
192 CpuProfile* profile = | 223 CpuProfile* profile = |
193 profiles.StopProfiling(TokenEnumerator::kNoSecurityToken, "", 1); | 224 profiles->StopProfiling(TokenEnumerator::kNoSecurityToken, "", 1); |
194 CHECK_NE(NULL, profile); | 225 CHECK_NE(NULL, profile); |
195 | 226 |
196 // Check call trees. | 227 // Check call trees. |
197 const i::List<ProfileNode*>* top_down_root_children = | 228 const i::List<ProfileNode*>* top_down_root_children = |
198 profile->top_down()->root()->children(); | 229 profile->top_down()->root()->children(); |
199 CHECK_EQ(1, top_down_root_children->length()); | 230 CHECK_EQ(1, top_down_root_children->length()); |
200 CHECK_EQ("bbb", top_down_root_children->last()->entry()->name()); | 231 CHECK_EQ("bbb", top_down_root_children->last()->entry()->name()); |
201 const i::List<ProfileNode*>* top_down_bbb_children = | 232 const i::List<ProfileNode*>* top_down_bbb_children = |
202 top_down_root_children->last()->children(); | 233 top_down_root_children->last()->children(); |
203 CHECK_EQ(1, top_down_bbb_children->length()); | 234 CHECK_EQ(1, top_down_bbb_children->length()); |
(...skipping 18 matching lines...) Expand all Loading... | |
222 profiler->StopProfiling("2"); | 253 profiler->StopProfiling("2"); |
223 profiler->StartProfiling("1"); | 254 profiler->StartProfiling("1"); |
224 profiler->StopProfiling(""); | 255 profiler->StopProfiling(""); |
225 } | 256 } |
226 | 257 |
227 | 258 |
228 // http://code.google.com/p/v8/issues/detail?id=1398 | 259 // http://code.google.com/p/v8/issues/detail?id=1398 |
229 // Long stacks (exceeding max frames limit) must not be erased. | 260 // Long stacks (exceeding max frames limit) must not be erased. |
230 TEST(Issue1398) { | 261 TEST(Issue1398) { |
231 TestSetup test_setup; | 262 TestSetup test_setup; |
232 CpuProfilesCollection profiles; | 263 LocalContext env; |
233 profiles.StartProfiling("", 1, false); | 264 i::Isolate* isolate = i::Isolate::Current(); |
yurys
2013/06/28 12:53:43
env->GetIsolate()
| |
234 ProfileGenerator generator(&profiles); | 265 i::HandleScope scope(isolate); |
235 ProfilerEventsProcessor processor(&generator, &profiles); | 266 |
267 i::Code* code = CreateCode(&env); | |
268 | |
269 CpuProfilesCollection* profiles = new CpuProfilesCollection; | |
270 profiles->StartProfiling("", 1, false); | |
271 ProfileGenerator generator(profiles); | |
272 ProfilerEventsProcessor processor(&generator, profiles); | |
236 processor.Start(); | 273 processor.Start(); |
274 CpuProfiler profiler(isolate, profiles, &generator, &processor); | |
237 | 275 |
238 processor.CodeCreateEvent(i::Logger::BUILTIN_TAG, | 276 profiler.CodeCreateEvent(i::Logger::BUILTIN_TAG, code, "bbb"); |
239 "bbb", | |
240 ToAddress(0x1200), | |
241 0x80); | |
242 | 277 |
243 i::TickSample* sample = processor.TickSampleEvent(); | 278 i::TickSample* sample = processor.TickSampleEvent(); |
244 sample->pc = ToAddress(0x1200); | 279 sample->pc = code->address(); |
245 sample->tos = 0; | 280 sample->tos = 0; |
246 sample->frames_count = i::TickSample::kMaxFramesCount; | 281 sample->frames_count = i::TickSample::kMaxFramesCount; |
247 for (int i = 0; i < sample->frames_count; ++i) { | 282 for (int i = 0; i < sample->frames_count; ++i) { |
248 sample->stack[i] = ToAddress(0x1200); | 283 sample->stack[i] = code->address(); |
249 } | 284 } |
250 | 285 |
251 processor.Stop(); | 286 processor.Stop(); |
252 processor.Join(); | 287 processor.Join(); |
253 CpuProfile* profile = | 288 CpuProfile* profile = |
254 profiles.StopProfiling(TokenEnumerator::kNoSecurityToken, "", 1); | 289 profiles->StopProfiling(TokenEnumerator::kNoSecurityToken, "", 1); |
255 CHECK_NE(NULL, profile); | 290 CHECK_NE(NULL, profile); |
256 | 291 |
257 int actual_depth = 0; | 292 int actual_depth = 0; |
258 const ProfileNode* node = profile->top_down()->root(); | 293 const ProfileNode* node = profile->top_down()->root(); |
259 while (node->children()->length() > 0) { | 294 while (node->children()->length() > 0) { |
260 node = node->children()->last(); | 295 node = node->children()->last(); |
261 ++actual_depth; | 296 ++actual_depth; |
262 } | 297 } |
263 | 298 |
264 CHECK_EQ(1 + i::TickSample::kMaxFramesCount, actual_depth); // +1 for PC. | 299 CHECK_EQ(1 + i::TickSample::kMaxFramesCount, actual_depth); // +1 for PC. |
(...skipping 642 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
907 reinterpret_cast<i::CpuProfile*>( | 942 reinterpret_cast<i::CpuProfile*>( |
908 const_cast<v8::CpuProfile*>(profile))->Print(); | 943 const_cast<v8::CpuProfile*>(profile))->Print(); |
909 | 944 |
910 const v8::CpuProfileNode* root = profile->GetTopDownRoot(); | 945 const v8::CpuProfileNode* root = profile->GetTopDownRoot(); |
911 GetChild(root, "start"); | 946 GetChild(root, "start"); |
912 const v8::CpuProfileNode* startNode = GetChild(root, "start"); | 947 const v8::CpuProfileNode* startNode = GetChild(root, "start"); |
913 GetChild(startNode, "fooMethod"); | 948 GetChild(startNode, "fooMethod"); |
914 | 949 |
915 cpu_profiler->DeleteAllCpuProfiles(); | 950 cpu_profiler->DeleteAllCpuProfiles(); |
916 } | 951 } |
OLD | NEW |