OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/profiler/cpu-profiler.h" | 5 #include "src/profiler/cpu-profiler.h" |
6 | 6 |
7 #include "src/debug/debug.h" | 7 #include "src/debug/debug.h" |
8 #include "src/deoptimizer.h" | 8 #include "src/deoptimizer.h" |
9 #include "src/frames-inl.h" | 9 #include "src/frames-inl.h" |
10 #include "src/locked-queue-inl.h" | 10 #include "src/locked-queue-inl.h" |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
197 // If this was the last profile, clean up all accessory data as well. | 197 // If this was the last profile, clean up all accessory data as well. |
198 ResetProfiles(); | 198 ResetProfiles(); |
199 } | 199 } |
200 } | 200 } |
201 | 201 |
202 | 202 |
203 void CpuProfiler::CallbackEvent(Name* name, Address entry_point) { | 203 void CpuProfiler::CallbackEvent(Name* name, Address entry_point) { |
204 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); | 204 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); |
205 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; | 205 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; |
206 rec->start = entry_point; | 206 rec->start = entry_point; |
207 rec->entry = profiles_->NewCodeEntry( | 207 rec->entry = profiles_->NewCodeEntry(CodeEventListener::CALLBACK_TAG, |
208 Logger::CALLBACK_TAG, | 208 profiles_->GetName(name)); |
209 profiles_->GetName(name)); | |
210 rec->size = 1; | 209 rec->size = 1; |
211 processor_->Enqueue(evt_rec); | 210 processor_->Enqueue(evt_rec); |
212 } | 211 } |
213 | 212 |
214 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, | 213 void CpuProfiler::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag, |
215 AbstractCode* code, const char* name) { | 214 AbstractCode* code, const char* name) { |
216 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); | 215 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); |
217 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; | 216 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; |
218 rec->start = code->address(); | 217 rec->start = code->address(); |
219 rec->entry = profiles_->NewCodeEntry( | 218 rec->entry = profiles_->NewCodeEntry( |
220 tag, profiles_->GetFunctionName(name), CodeEntry::kEmptyNamePrefix, | 219 tag, profiles_->GetFunctionName(name), CodeEntry::kEmptyNamePrefix, |
221 CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo, | 220 CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo, |
222 CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start()); | 221 CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start()); |
223 RecordInliningInfo(rec->entry, code); | 222 RecordInliningInfo(rec->entry, code); |
224 rec->size = code->ExecutableSize(); | 223 rec->size = code->ExecutableSize(); |
225 processor_->Enqueue(evt_rec); | 224 processor_->Enqueue(evt_rec); |
226 } | 225 } |
227 | 226 |
228 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, | 227 void CpuProfiler::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag, |
229 AbstractCode* code, Name* name) { | 228 AbstractCode* code, Name* name) { |
230 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); | 229 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); |
231 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; | 230 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; |
232 rec->start = code->address(); | 231 rec->start = code->address(); |
233 rec->entry = profiles_->NewCodeEntry( | 232 rec->entry = profiles_->NewCodeEntry( |
234 tag, profiles_->GetFunctionName(name), CodeEntry::kEmptyNamePrefix, | 233 tag, profiles_->GetFunctionName(name), CodeEntry::kEmptyNamePrefix, |
235 CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo, | 234 CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo, |
236 CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start()); | 235 CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start()); |
237 RecordInliningInfo(rec->entry, code); | 236 RecordInliningInfo(rec->entry, code); |
238 rec->size = code->ExecutableSize(); | 237 rec->size = code->ExecutableSize(); |
239 processor_->Enqueue(evt_rec); | 238 processor_->Enqueue(evt_rec); |
240 } | 239 } |
241 | 240 |
242 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, | 241 void CpuProfiler::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag, |
243 AbstractCode* code, | 242 AbstractCode* code, |
244 SharedFunctionInfo* shared, | 243 SharedFunctionInfo* shared, |
245 Name* script_name) { | 244 Name* script_name) { |
246 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); | 245 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); |
247 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; | 246 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; |
248 rec->start = code->address(); | 247 rec->start = code->address(); |
249 rec->entry = profiles_->NewCodeEntry( | 248 rec->entry = profiles_->NewCodeEntry( |
250 tag, profiles_->GetFunctionName(shared->DebugName()), | 249 tag, profiles_->GetFunctionName(shared->DebugName()), |
251 CodeEntry::kEmptyNamePrefix, | 250 CodeEntry::kEmptyNamePrefix, |
252 profiles_->GetName(InferScriptName(script_name, shared)), | 251 profiles_->GetName(InferScriptName(script_name, shared)), |
253 CpuProfileNode::kNoLineNumberInfo, CpuProfileNode::kNoColumnNumberInfo, | 252 CpuProfileNode::kNoLineNumberInfo, CpuProfileNode::kNoColumnNumberInfo, |
254 NULL, code->instruction_start()); | 253 NULL, code->instruction_start()); |
255 RecordInliningInfo(rec->entry, code); | 254 RecordInliningInfo(rec->entry, code); |
256 rec->entry->FillFunctionInfo(shared); | 255 rec->entry->FillFunctionInfo(shared); |
257 rec->size = code->ExecutableSize(); | 256 rec->size = code->ExecutableSize(); |
258 processor_->Enqueue(evt_rec); | 257 processor_->Enqueue(evt_rec); |
259 } | 258 } |
260 | 259 |
261 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, | 260 void CpuProfiler::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag, |
262 AbstractCode* abstract_code, | 261 AbstractCode* abstract_code, |
263 SharedFunctionInfo* shared, Name* script_name, | 262 SharedFunctionInfo* shared, Name* script_name, |
264 int line, int column) { | 263 int line, int column) { |
265 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); | 264 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); |
266 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; | 265 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; |
267 rec->start = abstract_code->address(); | 266 rec->start = abstract_code->address(); |
268 Script* script = Script::cast(shared->script()); | 267 Script* script = Script::cast(shared->script()); |
269 JITLineInfoTable* line_table = NULL; | 268 JITLineInfoTable* line_table = NULL; |
270 if (script) { | 269 if (script) { |
271 if (abstract_code->IsCode()) { | 270 if (abstract_code->IsCode()) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
305 CodeEntry::kEmptyNamePrefix, | 304 CodeEntry::kEmptyNamePrefix, |
306 profiles_->GetName(InferScriptName(script_name, shared)), line, column, | 305 profiles_->GetName(InferScriptName(script_name, shared)), line, column, |
307 line_table, abstract_code->instruction_start()); | 306 line_table, abstract_code->instruction_start()); |
308 RecordInliningInfo(rec->entry, abstract_code); | 307 RecordInliningInfo(rec->entry, abstract_code); |
309 RecordDeoptInlinedFrames(rec->entry, abstract_code); | 308 RecordDeoptInlinedFrames(rec->entry, abstract_code); |
310 rec->entry->FillFunctionInfo(shared); | 309 rec->entry->FillFunctionInfo(shared); |
311 rec->size = abstract_code->ExecutableSize(); | 310 rec->size = abstract_code->ExecutableSize(); |
312 processor_->Enqueue(evt_rec); | 311 processor_->Enqueue(evt_rec); |
313 } | 312 } |
314 | 313 |
315 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, | 314 void CpuProfiler::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag, |
316 AbstractCode* code, int args_count) { | 315 AbstractCode* code, int args_count) { |
317 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); | 316 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); |
318 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; | 317 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; |
319 rec->start = code->address(); | 318 rec->start = code->address(); |
320 rec->entry = profiles_->NewCodeEntry( | 319 rec->entry = profiles_->NewCodeEntry( |
321 tag, profiles_->GetName(args_count), "args_count: ", | 320 tag, profiles_->GetName(args_count), "args_count: ", |
322 CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo, | 321 CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo, |
323 CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start()); | 322 CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start()); |
324 RecordInliningInfo(rec->entry, code); | 323 RecordInliningInfo(rec->entry, code); |
325 rec->size = code->ExecutableSize(); | 324 rec->size = code->ExecutableSize(); |
(...skipping 26 matching lines...) Expand all Loading... |
352 rec->position = info.position; | 351 rec->position = info.position; |
353 rec->deopt_id = info.deopt_id; | 352 rec->deopt_id = info.deopt_id; |
354 processor_->Enqueue(evt_rec); | 353 processor_->Enqueue(evt_rec); |
355 processor_->AddDeoptStack(isolate_, pc, fp_to_sp_delta); | 354 processor_->AddDeoptStack(isolate_, pc, fp_to_sp_delta); |
356 } | 355 } |
357 | 356 |
358 void CpuProfiler::GetterCallbackEvent(Name* name, Address entry_point) { | 357 void CpuProfiler::GetterCallbackEvent(Name* name, Address entry_point) { |
359 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); | 358 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); |
360 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; | 359 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; |
361 rec->start = entry_point; | 360 rec->start = entry_point; |
362 rec->entry = profiles_->NewCodeEntry( | 361 rec->entry = profiles_->NewCodeEntry(CodeEventListener::CALLBACK_TAG, |
363 Logger::CALLBACK_TAG, | 362 profiles_->GetName(name), "get "); |
364 profiles_->GetName(name), | |
365 "get "); | |
366 rec->size = 1; | 363 rec->size = 1; |
367 processor_->Enqueue(evt_rec); | 364 processor_->Enqueue(evt_rec); |
368 } | 365 } |
369 | 366 |
370 void CpuProfiler::RegExpCodeCreateEvent(AbstractCode* code, String* source) { | 367 void CpuProfiler::RegExpCodeCreateEvent(AbstractCode* code, String* source) { |
371 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); | 368 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); |
372 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; | 369 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; |
373 rec->start = code->address(); | 370 rec->start = code->address(); |
374 rec->entry = profiles_->NewCodeEntry( | 371 rec->entry = profiles_->NewCodeEntry( |
375 Logger::REG_EXP_TAG, profiles_->GetName(source), "RegExp: ", | 372 CodeEventListener::REG_EXP_TAG, profiles_->GetName(source), "RegExp: ", |
376 CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo, | 373 CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo, |
377 CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start()); | 374 CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start()); |
378 rec->size = code->ExecutableSize(); | 375 rec->size = code->ExecutableSize(); |
379 processor_->Enqueue(evt_rec); | 376 processor_->Enqueue(evt_rec); |
380 } | 377 } |
381 | 378 |
382 | 379 |
383 void CpuProfiler::SetterCallbackEvent(Name* name, Address entry_point) { | 380 void CpuProfiler::SetterCallbackEvent(Name* name, Address entry_point) { |
384 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); | 381 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); |
385 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; | 382 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; |
386 rec->start = entry_point; | 383 rec->start = entry_point; |
387 rec->entry = profiles_->NewCodeEntry( | 384 rec->entry = profiles_->NewCodeEntry(CodeEventListener::CALLBACK_TAG, |
388 Logger::CALLBACK_TAG, | 385 profiles_->GetName(name), "set "); |
389 profiles_->GetName(name), | |
390 "set "); | |
391 rec->size = 1; | 386 rec->size = 1; |
392 processor_->Enqueue(evt_rec); | 387 processor_->Enqueue(evt_rec); |
393 } | 388 } |
394 | 389 |
395 Name* CpuProfiler::InferScriptName(Name* name, SharedFunctionInfo* info) { | 390 Name* CpuProfiler::InferScriptName(Name* name, SharedFunctionInfo* info) { |
396 if (name->IsString() && String::cast(name)->length()) return name; | 391 if (name->IsString() && String::cast(name)->length()) return name; |
397 if (!info->script()->IsScript()) return name; | 392 if (!info->script()->IsScript()) return name; |
398 Object* source_url = Script::cast(info->script())->source_url(); | 393 Object* source_url = Script::cast(info->script())->source_url(); |
399 return source_url->IsName() ? Name::cast(source_url) : name; | 394 return source_url->IsName() ? Name::cast(source_url) : name; |
400 } | 395 } |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
566 saved_is_logging_ = logger->is_logging_; | 561 saved_is_logging_ = logger->is_logging_; |
567 logger->is_logging_ = false; | 562 logger->is_logging_ = false; |
568 generator_ = new ProfileGenerator(profiles_); | 563 generator_ = new ProfileGenerator(profiles_); |
569 sampler::Sampler* sampler = logger->sampler(); | 564 sampler::Sampler* sampler = logger->sampler(); |
570 processor_ = new ProfilerEventsProcessor( | 565 processor_ = new ProfilerEventsProcessor( |
571 generator_, sampler, sampling_interval_); | 566 generator_, sampler, sampling_interval_); |
572 is_profiling_ = true; | 567 is_profiling_ = true; |
573 isolate_->set_is_profiling(true); | 568 isolate_->set_is_profiling(true); |
574 // Enumerate stuff we already have in the heap. | 569 // Enumerate stuff we already have in the heap. |
575 DCHECK(isolate_->heap()->HasBeenSetUp()); | 570 DCHECK(isolate_->heap()->HasBeenSetUp()); |
| 571 isolate_->code_event_dispatcher()->AddListener(this); |
576 if (!FLAG_prof_browser_mode) { | 572 if (!FLAG_prof_browser_mode) { |
577 logger->LogCodeObjects(); | 573 logger->LogCodeObjects(); |
578 } | 574 } |
579 logger->LogCompiledFunctions(); | 575 logger->LogCompiledFunctions(); |
580 logger->LogAccessorCallbacks(); | 576 logger->LogAccessorCallbacks(); |
581 LogBuiltins(); | 577 LogBuiltins(); |
582 // Enable stack sampling. | 578 // Enable stack sampling. |
583 sampler->SetHasProcessingThread(true); | 579 sampler->SetHasProcessingThread(true); |
584 sampler->IncreaseProfilingDepth(); | 580 sampler->IncreaseProfilingDepth(); |
585 processor_->AddCurrentStack(isolate_); | 581 processor_->AddCurrentStack(isolate_); |
(...skipping 24 matching lines...) Expand all Loading... |
610 if (profiles_->IsLastProfile(title)) StopProcessor(); | 606 if (profiles_->IsLastProfile(title)) StopProcessor(); |
611 } | 607 } |
612 | 608 |
613 | 609 |
614 void CpuProfiler::StopProcessor() { | 610 void CpuProfiler::StopProcessor() { |
615 Logger* logger = isolate_->logger(); | 611 Logger* logger = isolate_->logger(); |
616 sampler::Sampler* sampler = | 612 sampler::Sampler* sampler = |
617 reinterpret_cast<sampler::Sampler*>(logger->ticker_); | 613 reinterpret_cast<sampler::Sampler*>(logger->ticker_); |
618 is_profiling_ = false; | 614 is_profiling_ = false; |
619 isolate_->set_is_profiling(false); | 615 isolate_->set_is_profiling(false); |
| 616 isolate_->code_event_dispatcher()->RemoveListener(this); |
620 processor_->StopSynchronously(); | 617 processor_->StopSynchronously(); |
621 delete processor_; | 618 delete processor_; |
622 delete generator_; | 619 delete generator_; |
623 processor_ = NULL; | 620 processor_ = NULL; |
624 generator_ = NULL; | 621 generator_ = NULL; |
625 sampler->SetHasProcessingThread(false); | 622 sampler->SetHasProcessingThread(false); |
626 sampler->DecreaseProfilingDepth(); | 623 sampler->DecreaseProfilingDepth(); |
627 logger->is_logging_ = saved_is_logging_; | 624 logger->is_logging_ = saved_is_logging_; |
628 } | 625 } |
629 | 626 |
630 | 627 |
631 void CpuProfiler::LogBuiltins() { | 628 void CpuProfiler::LogBuiltins() { |
632 Builtins* builtins = isolate_->builtins(); | 629 Builtins* builtins = isolate_->builtins(); |
633 DCHECK(builtins->is_initialized()); | 630 DCHECK(builtins->is_initialized()); |
634 for (int i = 0; i < Builtins::builtin_count; i++) { | 631 for (int i = 0; i < Builtins::builtin_count; i++) { |
635 CodeEventsContainer evt_rec(CodeEventRecord::REPORT_BUILTIN); | 632 CodeEventsContainer evt_rec(CodeEventRecord::REPORT_BUILTIN); |
636 ReportBuiltinEventRecord* rec = &evt_rec.ReportBuiltinEventRecord_; | 633 ReportBuiltinEventRecord* rec = &evt_rec.ReportBuiltinEventRecord_; |
637 Builtins::Name id = static_cast<Builtins::Name>(i); | 634 Builtins::Name id = static_cast<Builtins::Name>(i); |
638 rec->start = builtins->builtin(id)->address(); | 635 rec->start = builtins->builtin(id)->address(); |
639 rec->builtin_id = id; | 636 rec->builtin_id = id; |
640 processor_->Enqueue(evt_rec); | 637 processor_->Enqueue(evt_rec); |
641 } | 638 } |
642 } | 639 } |
643 | 640 |
644 | 641 |
645 } // namespace internal | 642 } // namespace internal |
646 } // namespace v8 | 643 } // namespace v8 |
OLD | NEW |