OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 generator_(generator), | 51 generator_(generator), |
52 profiles_(profiles), | 52 profiles_(profiles), |
53 running_(true), | 53 running_(true), |
54 ticks_buffer_(sizeof(TickSampleEventRecord), | 54 ticks_buffer_(sizeof(TickSampleEventRecord), |
55 kTickSamplesBufferChunkSize, | 55 kTickSamplesBufferChunkSize, |
56 kTickSamplesBufferChunksCount), | 56 kTickSamplesBufferChunksCount), |
57 enqueue_order_(0) { | 57 enqueue_order_(0) { |
58 } | 58 } |
59 | 59 |
60 | 60 |
61 void ProfilerEventsProcessor::Enqueue(const CodeEventsContainer& event) { | 61 void ProfilerEventsProcessor::CallbackCreateEvent(Logger::LogEventsAndTags tag, |
62 event.generic.order = ++enqueue_order_; | 62 const char* prefix, |
63 events_buffer_.Enqueue(event); | 63 Name* name, |
| 64 Address start) { |
| 65 if (FilterOutCodeCreateEvent(tag)) return; |
| 66 CodeEventsContainer evt_rec; |
| 67 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; |
| 68 rec->type = CodeEventRecord::CODE_CREATION; |
| 69 rec->order = ++enqueue_order_; |
| 70 rec->start = start; |
| 71 rec->entry = profiles_->NewCodeEntry(tag, prefix, name); |
| 72 rec->size = 1; |
| 73 rec->shared = NULL; |
| 74 events_buffer_.Enqueue(evt_rec); |
64 } | 75 } |
65 | 76 |
66 | 77 |
| 78 void ProfilerEventsProcessor::CodeCreateEvent(Logger::LogEventsAndTags tag, |
| 79 Name* name, |
| 80 String* resource_name, |
| 81 int line_number, |
| 82 Address start, |
| 83 unsigned size, |
| 84 Address shared, |
| 85 CompilationInfo* info) { |
| 86 if (FilterOutCodeCreateEvent(tag)) return; |
| 87 CodeEventsContainer evt_rec; |
| 88 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; |
| 89 rec->type = CodeEventRecord::CODE_CREATION; |
| 90 rec->order = ++enqueue_order_; |
| 91 rec->start = start; |
| 92 rec->entry = profiles_->NewCodeEntry(tag, name, resource_name, line_number); |
| 93 if (info) { |
| 94 rec->entry->set_no_frame_ranges(info->ReleaseNoFrameRanges()); |
| 95 } |
| 96 rec->size = size; |
| 97 rec->shared = shared; |
| 98 events_buffer_.Enqueue(evt_rec); |
| 99 } |
| 100 |
| 101 |
| 102 void ProfilerEventsProcessor::CodeCreateEvent(Logger::LogEventsAndTags tag, |
| 103 const char* name, |
| 104 Address start, |
| 105 unsigned size) { |
| 106 if (FilterOutCodeCreateEvent(tag)) return; |
| 107 CodeEventsContainer evt_rec; |
| 108 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; |
| 109 rec->type = CodeEventRecord::CODE_CREATION; |
| 110 rec->order = ++enqueue_order_; |
| 111 rec->start = start; |
| 112 rec->entry = profiles_->NewCodeEntry(tag, name); |
| 113 rec->size = size; |
| 114 rec->shared = NULL; |
| 115 events_buffer_.Enqueue(evt_rec); |
| 116 } |
| 117 |
| 118 |
| 119 void ProfilerEventsProcessor::CodeCreateEvent(Logger::LogEventsAndTags tag, |
| 120 int args_count, |
| 121 Address start, |
| 122 unsigned size) { |
| 123 if (FilterOutCodeCreateEvent(tag)) return; |
| 124 CodeEventsContainer evt_rec; |
| 125 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; |
| 126 rec->type = CodeEventRecord::CODE_CREATION; |
| 127 rec->order = ++enqueue_order_; |
| 128 rec->start = start; |
| 129 rec->entry = profiles_->NewCodeEntry(tag, args_count); |
| 130 rec->size = size; |
| 131 rec->shared = NULL; |
| 132 events_buffer_.Enqueue(evt_rec); |
| 133 } |
| 134 |
| 135 |
| 136 void ProfilerEventsProcessor::CodeMoveEvent(Address from, Address to) { |
| 137 CodeEventsContainer evt_rec; |
| 138 CodeMoveEventRecord* rec = &evt_rec.CodeMoveEventRecord_; |
| 139 rec->type = CodeEventRecord::CODE_MOVE; |
| 140 rec->order = ++enqueue_order_; |
| 141 rec->from = from; |
| 142 rec->to = to; |
| 143 events_buffer_.Enqueue(evt_rec); |
| 144 } |
| 145 |
| 146 |
| 147 void ProfilerEventsProcessor::SharedFunctionInfoMoveEvent(Address from, |
| 148 Address to) { |
| 149 CodeEventsContainer evt_rec; |
| 150 SharedFunctionInfoMoveEventRecord* rec = |
| 151 &evt_rec.SharedFunctionInfoMoveEventRecord_; |
| 152 rec->type = CodeEventRecord::SHARED_FUNC_MOVE; |
| 153 rec->order = ++enqueue_order_; |
| 154 rec->from = from; |
| 155 rec->to = to; |
| 156 events_buffer_.Enqueue(evt_rec); |
| 157 } |
| 158 |
| 159 |
| 160 void ProfilerEventsProcessor::RegExpCodeCreateEvent( |
| 161 Logger::LogEventsAndTags tag, |
| 162 const char* prefix, |
| 163 String* name, |
| 164 Address start, |
| 165 unsigned size) { |
| 166 if (FilterOutCodeCreateEvent(tag)) return; |
| 167 CodeEventsContainer evt_rec; |
| 168 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; |
| 169 rec->type = CodeEventRecord::CODE_CREATION; |
| 170 rec->order = ++enqueue_order_; |
| 171 rec->start = start; |
| 172 rec->entry = profiles_->NewCodeEntry(tag, prefix, name); |
| 173 rec->size = size; |
| 174 events_buffer_.Enqueue(evt_rec); |
| 175 } |
| 176 |
| 177 |
67 void ProfilerEventsProcessor::AddCurrentStack() { | 178 void ProfilerEventsProcessor::AddCurrentStack() { |
68 TickSampleEventRecord record(enqueue_order_); | 179 TickSampleEventRecord record(enqueue_order_); |
69 TickSample* sample = &record.sample; | 180 TickSample* sample = &record.sample; |
70 Isolate* isolate = Isolate::Current(); | 181 Isolate* isolate = Isolate::Current(); |
71 sample->state = isolate->current_vm_state(); | 182 sample->state = isolate->current_vm_state(); |
72 sample->pc = reinterpret_cast<Address>(sample); // Not NULL. | 183 sample->pc = reinterpret_cast<Address>(sample); // Not NULL. |
73 for (StackTraceFrameIterator it(isolate); | 184 for (StackTraceFrameIterator it(isolate); |
74 !it.done() && sample->frames_count < TickSample::kMaxFramesCount; | 185 !it.done() && sample->frames_count < TickSample::kMaxFramesCount; |
75 it.Advance()) { | 186 it.Advance()) { |
76 sample->stack[sample->frames_count++] = it.frame()->pc(); | 187 sample->stack[sample->frames_count++] = it.frame()->pc(); |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 profiles_->RemoveProfile(profile); | 298 profiles_->RemoveProfile(profile); |
188 delete profile; | 299 delete profile; |
189 } | 300 } |
190 | 301 |
191 | 302 |
192 bool CpuProfiler::HasDetachedProfiles() { | 303 bool CpuProfiler::HasDetachedProfiles() { |
193 return profiles_->HasDetachedProfiles(); | 304 return profiles_->HasDetachedProfiles(); |
194 } | 305 } |
195 | 306 |
196 | 307 |
197 static bool FilterOutCodeCreateEvent(Logger::LogEventsAndTags tag) { | |
198 return FLAG_prof_browser_mode | |
199 && (tag != Logger::CALLBACK_TAG | |
200 && tag != Logger::FUNCTION_TAG | |
201 && tag != Logger::LAZY_COMPILE_TAG | |
202 && tag != Logger::REG_EXP_TAG | |
203 && tag != Logger::SCRIPT_TAG); | |
204 } | |
205 | |
206 | |
207 void CpuProfiler::CallbackEvent(Name* name, Address entry_point) { | 308 void CpuProfiler::CallbackEvent(Name* name, Address entry_point) { |
208 if (FilterOutCodeCreateEvent(Logger::CALLBACK_TAG)) return; | 309 processor_->CallbackCreateEvent( |
209 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); | 310 Logger::CALLBACK_TAG, CodeEntry::kEmptyNamePrefix, name, entry_point); |
210 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; | |
211 rec->start = entry_point; | |
212 rec->entry = profiles_->NewCodeEntry( | |
213 Logger::CALLBACK_TAG, | |
214 profiles_->GetName(name), | |
215 TokenEnumerator::kInheritsSecurityToken); | |
216 rec->size = 1; | |
217 rec->shared = NULL; | |
218 processor_->Enqueue(evt_rec); | |
219 } | 311 } |
220 | 312 |
221 | 313 |
222 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, | 314 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, |
223 Code* code, | 315 Code* code, const char* comment) { |
224 const char* name) { | 316 processor_->CodeCreateEvent( |
225 if (FilterOutCodeCreateEvent(tag)) return; | 317 tag, comment, code->address(), code->ExecutableSize()); |
226 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); | |
227 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; | |
228 rec->start = code->address(); | |
229 rec->entry = profiles_->NewCodeEntry(tag, profiles_->GetFunctionName(name)); | |
230 rec->size = code->ExecutableSize(); | |
231 rec->shared = NULL; | |
232 processor_->Enqueue(evt_rec); | |
233 } | 318 } |
234 | 319 |
235 | 320 |
236 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, | 321 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, |
237 Code* code, | 322 Code* code, Name* name) { |
238 Name* name) { | 323 processor_->CodeCreateEvent( |
239 if (FilterOutCodeCreateEvent(tag)) return; | 324 tag, |
240 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); | 325 name, |
241 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; | 326 isolate_->heap()->empty_string(), |
242 rec->start = code->address(); | 327 v8::CpuProfileNode::kNoLineNumberInfo, |
243 rec->entry = profiles_->NewCodeEntry(tag, profiles_->GetFunctionName(name)); | 328 code->address(), |
244 rec->size = code->ExecutableSize(); | 329 code->ExecutableSize(), |
245 rec->shared = NULL; | 330 NULL, |
246 processor_->Enqueue(evt_rec); | 331 NULL); |
247 } | 332 } |
248 | 333 |
249 | 334 |
250 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, | 335 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, |
251 Code* code, | 336 Code* code, |
252 SharedFunctionInfo* shared, | 337 SharedFunctionInfo* shared, |
253 CompilationInfo* info, | 338 CompilationInfo* info, |
254 Name* name) { | 339 Name* name) { |
255 if (FilterOutCodeCreateEvent(tag)) return; | 340 processor_->CodeCreateEvent( |
256 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); | 341 tag, |
257 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; | 342 name, |
258 rec->start = code->address(); | 343 isolate_->heap()->empty_string(), |
259 rec->entry = profiles_->NewCodeEntry(tag, profiles_->GetFunctionName(name)); | 344 v8::CpuProfileNode::kNoLineNumberInfo, |
260 rec->entry->set_no_frame_ranges(info ? | 345 code->address(), |
261 info->ReleaseNoFrameRanges() : | 346 code->ExecutableSize(), |
262 NULL); | 347 shared->address(), |
263 rec->size = code->ExecutableSize(); | 348 info); |
264 rec->shared = shared->address(); | |
265 processor_->Enqueue(evt_rec); | |
266 } | 349 } |
267 | 350 |
268 | 351 |
269 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, | 352 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, |
270 Code* code, | 353 Code* code, |
271 SharedFunctionInfo* shared, | 354 SharedFunctionInfo* shared, |
272 CompilationInfo* info, | 355 CompilationInfo* info, |
273 String* source, int line) { | 356 String* source, int line) { |
274 if (FilterOutCodeCreateEvent(tag)) return; | 357 processor_->CodeCreateEvent( |
275 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); | |
276 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; | |
277 rec->start = code->address(); | |
278 rec->entry = profiles_->NewCodeEntry( | |
279 tag, | 358 tag, |
280 profiles_->GetFunctionName(shared->DebugName()), | 359 shared->DebugName(), |
281 TokenEnumerator::kNoSecurityToken, | 360 source, |
282 CodeEntry::kEmptyNamePrefix, | 361 line, |
283 profiles_->GetName(source), | 362 code->address(), |
284 line); | 363 code->ExecutableSize(), |
285 rec->entry->set_no_frame_ranges(info ? | 364 shared->address(), |
286 info->ReleaseNoFrameRanges() : | 365 info); |
287 NULL); | |
288 rec->size = code->ExecutableSize(); | |
289 rec->shared = shared->address(); | |
290 processor_->Enqueue(evt_rec); | |
291 } | 366 } |
292 | 367 |
293 | 368 |
294 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, | 369 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, |
295 Code* code, | 370 Code* code, int args_count) { |
296 int args_count) { | 371 processor_->CodeCreateEvent( |
297 if (FilterOutCodeCreateEvent(tag)) return; | |
298 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); | |
299 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; | |
300 rec->start = code->address(); | |
301 rec->entry = profiles_->NewCodeEntry( | |
302 tag, | 372 tag, |
303 profiles_->GetName(args_count), | 373 args_count, |
304 TokenEnumerator::kInheritsSecurityToken, | 374 code->address(), |
305 "args_count: "); | 375 code->ExecutableSize()); |
306 rec->size = code->ExecutableSize(); | |
307 rec->shared = NULL; | |
308 processor_->Enqueue(evt_rec); | |
309 } | 376 } |
310 | 377 |
311 | 378 |
312 void CpuProfiler::CodeMoveEvent(Address from, Address to) { | 379 void CpuProfiler::CodeMoveEvent(Address from, Address to) { |
313 CodeEventsContainer evt_rec(CodeEventRecord::CODE_MOVE); | 380 processor_->CodeMoveEvent(from, to); |
314 CodeMoveEventRecord* rec = &evt_rec.CodeMoveEventRecord_; | |
315 rec->from = from; | |
316 rec->to = to; | |
317 processor_->Enqueue(evt_rec); | |
318 } | 381 } |
319 | 382 |
320 | 383 |
321 void CpuProfiler::CodeDeleteEvent(Address from) { | 384 void CpuProfiler::CodeDeleteEvent(Address from) { |
322 } | 385 } |
323 | 386 |
324 | 387 |
325 void CpuProfiler::SharedFunctionInfoMoveEvent(Address from, Address to) { | 388 void CpuProfiler::SharedFunctionInfoMoveEvent(Address from, Address to) { |
326 CodeEventsContainer evt_rec(CodeEventRecord::SHARED_FUNC_MOVE); | 389 processor_->SharedFunctionInfoMoveEvent(from, to); |
327 SharedFunctionInfoMoveEventRecord* rec = | |
328 &evt_rec.SharedFunctionInfoMoveEventRecord_; | |
329 rec->from = from; | |
330 rec->to = to; | |
331 processor_->Enqueue(evt_rec); | |
332 } | 390 } |
333 | 391 |
334 | 392 |
335 void CpuProfiler::GetterCallbackEvent(Name* name, Address entry_point) { | 393 void CpuProfiler::GetterCallbackEvent(Name* name, Address entry_point) { |
336 if (FilterOutCodeCreateEvent(Logger::CALLBACK_TAG)) return; | 394 processor_->CallbackCreateEvent( |
337 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); | 395 Logger::CALLBACK_TAG, "get ", name, entry_point); |
338 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; | |
339 rec->start = entry_point; | |
340 rec->entry = profiles_->NewCodeEntry( | |
341 Logger::CALLBACK_TAG, | |
342 profiles_->GetName(name), | |
343 TokenEnumerator::kInheritsSecurityToken, | |
344 "get "); | |
345 rec->size = 1; | |
346 rec->shared = NULL; | |
347 processor_->Enqueue(evt_rec); | |
348 } | 396 } |
349 | 397 |
350 | 398 |
351 void CpuProfiler::RegExpCodeCreateEvent(Code* code, String* source) { | 399 void CpuProfiler::RegExpCodeCreateEvent(Code* code, String* source) { |
352 if (FilterOutCodeCreateEvent(Logger::REG_EXP_TAG)) return; | 400 processor_->RegExpCodeCreateEvent( |
353 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); | |
354 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; | |
355 rec->start = code->address(); | |
356 rec->entry = profiles_->NewCodeEntry( | |
357 Logger::REG_EXP_TAG, | 401 Logger::REG_EXP_TAG, |
358 profiles_->GetName(source), | 402 "RegExp: ", |
359 TokenEnumerator::kInheritsSecurityToken, | 403 source, |
360 "RegExp: "); | 404 code->address(), |
361 rec->size = code->ExecutableSize(); | 405 code->ExecutableSize()); |
362 processor_->Enqueue(evt_rec); | |
363 } | 406 } |
364 | 407 |
365 | 408 |
366 void CpuProfiler::SetterCallbackEvent(Name* name, Address entry_point) { | 409 void CpuProfiler::SetterCallbackEvent(Name* name, Address entry_point) { |
367 if (FilterOutCodeCreateEvent(Logger::CALLBACK_TAG)) return; | 410 processor_->CallbackCreateEvent( |
368 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); | 411 Logger::CALLBACK_TAG, "set ", name, entry_point); |
369 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; | |
370 rec->start = entry_point; | |
371 rec->entry = profiles_->NewCodeEntry( | |
372 Logger::CALLBACK_TAG, | |
373 profiles_->GetName(name), | |
374 TokenEnumerator::kInheritsSecurityToken, | |
375 "set "); | |
376 rec->size = 1; | |
377 rec->shared = NULL; | |
378 processor_->Enqueue(evt_rec); | |
379 } | 412 } |
380 | 413 |
381 | 414 |
382 CpuProfiler::CpuProfiler(Isolate* isolate) | 415 CpuProfiler::CpuProfiler(Isolate* isolate) |
383 : isolate_(isolate), | 416 : isolate_(isolate), |
384 profiles_(new CpuProfilesCollection()), | 417 profiles_(new CpuProfilesCollection()), |
385 next_profile_uid_(1), | 418 next_profile_uid_(1), |
386 token_enumerator_(new TokenEnumerator()), | 419 token_enumerator_(new TokenEnumerator()), |
387 generator_(NULL), | 420 generator_(NULL), |
388 processor_(NULL), | 421 processor_(NULL), |
389 need_to_stop_sampler_(false), | 422 need_to_stop_sampler_(false), |
390 is_profiling_(false) { | 423 is_profiling_(false) { |
391 } | 424 } |
392 | 425 |
393 | 426 |
394 CpuProfiler::CpuProfiler(Isolate* isolate, | |
395 CpuProfilesCollection* test_profiles, | |
396 ProfileGenerator* test_generator, | |
397 ProfilerEventsProcessor* test_processor) | |
398 : isolate_(isolate), | |
399 profiles_(test_profiles), | |
400 next_profile_uid_(1), | |
401 token_enumerator_(new TokenEnumerator()), | |
402 generator_(test_generator), | |
403 processor_(test_processor), | |
404 need_to_stop_sampler_(false), | |
405 is_profiling_(false) { | |
406 } | |
407 | |
408 | |
409 CpuProfiler::~CpuProfiler() { | 427 CpuProfiler::~CpuProfiler() { |
410 delete token_enumerator_; | 428 delete token_enumerator_; |
411 delete profiles_; | 429 delete profiles_; |
412 } | 430 } |
413 | 431 |
414 | 432 |
415 void CpuProfiler::ResetProfiles() { | 433 void CpuProfiler::ResetProfiles() { |
416 delete profiles_; | 434 delete profiles_; |
417 profiles_ = new CpuProfilesCollection(); | 435 profiles_ = new CpuProfilesCollection(); |
418 } | 436 } |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
501 processor_->Join(); | 519 processor_->Join(); |
502 delete processor_; | 520 delete processor_; |
503 delete generator_; | 521 delete generator_; |
504 processor_ = NULL; | 522 processor_ = NULL; |
505 generator_ = NULL; | 523 generator_ = NULL; |
506 logger->logging_nesting_ = saved_logging_nesting_; | 524 logger->logging_nesting_ = saved_logging_nesting_; |
507 } | 525 } |
508 | 526 |
509 | 527 |
510 } } // namespace v8::internal | 528 } } // namespace v8::internal |
OLD | NEW |