| 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 |