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 |