| 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 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 215 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, | 215 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, |
| 216 Code* code, | 216 Code* code, |
| 217 const char* name) { | 217 const char* name) { |
| 218 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); | 218 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); |
| 219 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; | 219 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; |
| 220 rec->start = code->address(); | 220 rec->start = code->address(); |
| 221 rec->entry = profiles_->NewCodeEntry( | 221 rec->entry = profiles_->NewCodeEntry( |
| 222 tag, profiles_->GetFunctionName(name), CodeEntry::kEmptyNamePrefix, | 222 tag, profiles_->GetFunctionName(name), CodeEntry::kEmptyNamePrefix, |
| 223 CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo, | 223 CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo, |
| 224 CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start()); | 224 CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start()); |
| 225 RecordInliningInfo(rec->entry, code); |
| 225 rec->size = code->ExecutableSize(); | 226 rec->size = code->ExecutableSize(); |
| 226 processor_->Enqueue(evt_rec); | 227 processor_->Enqueue(evt_rec); |
| 227 } | 228 } |
| 228 | 229 |
| 229 | 230 |
| 230 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, | 231 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, |
| 231 Code* code, | 232 Code* code, |
| 232 Name* name) { | 233 Name* name) { |
| 233 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); | 234 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); |
| 234 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; | 235 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; |
| 235 rec->start = code->address(); | 236 rec->start = code->address(); |
| 236 rec->entry = profiles_->NewCodeEntry( | 237 rec->entry = profiles_->NewCodeEntry( |
| 237 tag, profiles_->GetFunctionName(name), CodeEntry::kEmptyNamePrefix, | 238 tag, profiles_->GetFunctionName(name), CodeEntry::kEmptyNamePrefix, |
| 238 CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo, | 239 CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo, |
| 239 CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start()); | 240 CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start()); |
| 241 RecordInliningInfo(rec->entry, code); |
| 240 rec->size = code->ExecutableSize(); | 242 rec->size = code->ExecutableSize(); |
| 241 processor_->Enqueue(evt_rec); | 243 processor_->Enqueue(evt_rec); |
| 242 } | 244 } |
| 243 | 245 |
| 244 | |
| 245 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, Code* code, | 246 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, Code* code, |
| 246 SharedFunctionInfo* shared, | 247 SharedFunctionInfo* shared, |
| 247 CompilationInfo* info, Name* script_name) { | 248 CompilationInfo* info, Name* script_name) { |
| 248 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); | 249 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); |
| 249 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; | 250 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; |
| 250 rec->start = code->address(); | 251 rec->start = code->address(); |
| 251 rec->entry = profiles_->NewCodeEntry( | 252 rec->entry = profiles_->NewCodeEntry( |
| 252 tag, profiles_->GetFunctionName(shared->DebugName()), | 253 tag, profiles_->GetFunctionName(shared->DebugName()), |
| 253 CodeEntry::kEmptyNamePrefix, profiles_->GetName(script_name), | 254 CodeEntry::kEmptyNamePrefix, profiles_->GetName(script_name), |
| 254 CpuProfileNode::kNoLineNumberInfo, CpuProfileNode::kNoColumnNumberInfo, | 255 CpuProfileNode::kNoLineNumberInfo, CpuProfileNode::kNoColumnNumberInfo, |
| 255 NULL, code->instruction_start()); | 256 NULL, code->instruction_start()); |
| 257 RecordInliningInfo(rec->entry, code); |
| 256 if (info) { | 258 if (info) { |
| 257 rec->entry->set_inlined_function_infos(info->inlined_function_infos()); | 259 rec->entry->set_inlined_function_infos(info->inlined_function_infos()); |
| 258 } | 260 } |
| 259 rec->entry->FillFunctionInfo(shared); | 261 rec->entry->FillFunctionInfo(shared); |
| 260 rec->size = code->ExecutableSize(); | 262 rec->size = code->ExecutableSize(); |
| 261 processor_->Enqueue(evt_rec); | 263 processor_->Enqueue(evt_rec); |
| 262 } | 264 } |
| 263 | 265 |
| 264 | 266 |
| 265 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, Code* code, | 267 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, Code* code, |
| (...skipping 16 matching lines...) Expand all Loading... |
| 282 int line_number = script->GetLineNumber(position) + 1; | 284 int line_number = script->GetLineNumber(position) + 1; |
| 283 line_table->SetPosition(pc_offset, line_number); | 285 line_table->SetPosition(pc_offset, line_number); |
| 284 } | 286 } |
| 285 } | 287 } |
| 286 } | 288 } |
| 287 } | 289 } |
| 288 rec->entry = profiles_->NewCodeEntry( | 290 rec->entry = profiles_->NewCodeEntry( |
| 289 tag, profiles_->GetFunctionName(shared->DebugName()), | 291 tag, profiles_->GetFunctionName(shared->DebugName()), |
| 290 CodeEntry::kEmptyNamePrefix, profiles_->GetName(script_name), line, | 292 CodeEntry::kEmptyNamePrefix, profiles_->GetName(script_name), line, |
| 291 column, line_table, code->instruction_start()); | 293 column, line_table, code->instruction_start()); |
| 294 RecordInliningInfo(rec->entry, code); |
| 292 if (info) { | 295 if (info) { |
| 293 rec->entry->set_inlined_function_infos(info->inlined_function_infos()); | 296 rec->entry->set_inlined_function_infos(info->inlined_function_infos()); |
| 294 } | 297 } |
| 295 rec->entry->FillFunctionInfo(shared); | 298 rec->entry->FillFunctionInfo(shared); |
| 296 rec->size = code->ExecutableSize(); | 299 rec->size = code->ExecutableSize(); |
| 297 processor_->Enqueue(evt_rec); | 300 processor_->Enqueue(evt_rec); |
| 298 } | 301 } |
| 299 | 302 |
| 300 | 303 |
| 301 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, | 304 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, |
| 302 Code* code, | 305 Code* code, |
| 303 int args_count) { | 306 int args_count) { |
| 304 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); | 307 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); |
| 305 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; | 308 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; |
| 306 rec->start = code->address(); | 309 rec->start = code->address(); |
| 307 rec->entry = profiles_->NewCodeEntry( | 310 rec->entry = profiles_->NewCodeEntry( |
| 308 tag, profiles_->GetName(args_count), "args_count: ", | 311 tag, profiles_->GetName(args_count), "args_count: ", |
| 309 CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo, | 312 CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo, |
| 310 CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start()); | 313 CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start()); |
| 314 RecordInliningInfo(rec->entry, code); |
| 311 rec->size = code->ExecutableSize(); | 315 rec->size = code->ExecutableSize(); |
| 312 processor_->Enqueue(evt_rec); | 316 processor_->Enqueue(evt_rec); |
| 313 } | 317 } |
| 314 | 318 |
| 315 | 319 |
| 316 void CpuProfiler::CodeMoveEvent(Address from, Address to) { | 320 void CpuProfiler::CodeMoveEvent(Address from, Address to) { |
| 317 CodeEventsContainer evt_rec(CodeEventRecord::CODE_MOVE); | 321 CodeEventsContainer evt_rec(CodeEventRecord::CODE_MOVE); |
| 318 CodeMoveEventRecord* rec = &evt_rec.CodeMoveEventRecord_; | 322 CodeMoveEventRecord* rec = &evt_rec.CodeMoveEventRecord_; |
| 319 rec->from = from; | 323 rec->from = from; |
| 320 rec->to = to; | 324 rec->to = to; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 379 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; | 383 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; |
| 380 rec->start = entry_point; | 384 rec->start = entry_point; |
| 381 rec->entry = profiles_->NewCodeEntry( | 385 rec->entry = profiles_->NewCodeEntry( |
| 382 Logger::CALLBACK_TAG, | 386 Logger::CALLBACK_TAG, |
| 383 profiles_->GetName(name), | 387 profiles_->GetName(name), |
| 384 "set "); | 388 "set "); |
| 385 rec->size = 1; | 389 rec->size = 1; |
| 386 processor_->Enqueue(evt_rec); | 390 processor_->Enqueue(evt_rec); |
| 387 } | 391 } |
| 388 | 392 |
| 393 void CpuProfiler::RecordInliningInfo(CodeEntry* entry, Code* code) { |
| 394 if (code->kind() != Code::OPTIMIZED_FUNCTION) return; |
| 395 DeoptimizationInputData* deopt_input_data = |
| 396 DeoptimizationInputData::cast(code->deoptimization_data()); |
| 397 int deopt_count = deopt_input_data->DeoptCount(); |
| 398 for (int i = 0; i < deopt_count; i++) { |
| 399 int pc_offset = deopt_input_data->Pc(i)->value(); |
| 400 if (pc_offset == -1) continue; |
| 401 int translation_index = deopt_input_data->TranslationIndex(i)->value(); |
| 402 TranslationIterator it(deopt_input_data->TranslationByteArray(), |
| 403 translation_index); |
| 404 Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next()); |
| 405 DCHECK_EQ(Translation::BEGIN, opcode); |
| 406 it.Skip(Translation::NumberOfOperandsFor(opcode)); |
| 407 int depth = 0; |
| 408 std::vector<CodeEntry*> inline_stack; |
| 409 while (it.HasNext() && |
| 410 Translation::BEGIN != |
| 411 (opcode = static_cast<Translation::Opcode>(it.Next()))) { |
| 412 if (opcode != Translation::JS_FRAME && |
| 413 opcode != Translation::INTERPRETED_FRAME) { |
| 414 it.Skip(Translation::NumberOfOperandsFor(opcode)); |
| 415 continue; |
| 416 } |
| 417 it.Next(); // Skip ast_id |
| 418 int shared_info_id = it.Next(); |
| 419 it.Next(); // Skip height |
| 420 SharedFunctionInfo* shared_info = SharedFunctionInfo::cast( |
| 421 deopt_input_data->LiteralArray()->get(shared_info_id)); |
| 422 if (!depth++) continue; // Skip the current function itself. |
| 423 CodeEntry* inline_entry = new CodeEntry( |
| 424 entry->tag(), profiles_->GetFunctionName(shared_info->DebugName()), |
| 425 CodeEntry::kEmptyNamePrefix, entry->resource_name(), |
| 426 CpuProfileNode::kNoLineNumberInfo, |
| 427 CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start()); |
| 428 inline_entry->FillFunctionInfo(shared_info); |
| 429 inline_stack.push_back(inline_entry); |
| 430 } |
| 431 if (!inline_stack.empty()) { |
| 432 entry->AddInlineStack(pc_offset, inline_stack); |
| 433 DCHECK(inline_stack.empty()); |
| 434 } |
| 435 } |
| 436 } |
| 389 | 437 |
| 390 CpuProfiler::CpuProfiler(Isolate* isolate) | 438 CpuProfiler::CpuProfiler(Isolate* isolate) |
| 391 : isolate_(isolate), | 439 : isolate_(isolate), |
| 392 sampling_interval_(base::TimeDelta::FromMicroseconds( | 440 sampling_interval_(base::TimeDelta::FromMicroseconds( |
| 393 FLAG_cpu_profiler_sampling_interval)), | 441 FLAG_cpu_profiler_sampling_interval)), |
| 394 profiles_(new CpuProfilesCollection(isolate->heap())), | 442 profiles_(new CpuProfilesCollection(isolate->heap())), |
| 395 generator_(NULL), | 443 generator_(NULL), |
| 396 processor_(NULL), | 444 processor_(NULL), |
| 397 is_profiling_(false) { | 445 is_profiling_(false) { |
| 398 } | 446 } |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 526 Builtins::Name id = static_cast<Builtins::Name>(i); | 574 Builtins::Name id = static_cast<Builtins::Name>(i); |
| 527 rec->start = builtins->builtin(id)->address(); | 575 rec->start = builtins->builtin(id)->address(); |
| 528 rec->builtin_id = id; | 576 rec->builtin_id = id; |
| 529 processor_->Enqueue(evt_rec); | 577 processor_->Enqueue(evt_rec); |
| 530 } | 578 } |
| 531 } | 579 } |
| 532 | 580 |
| 533 | 581 |
| 534 } // namespace internal | 582 } // namespace internal |
| 535 } // namespace v8 | 583 } // namespace v8 |
| OLD | NEW |