Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(224)

Side by Side Diff: src/profiler/cpu-profiler.cc

Issue 1740073002: Make CPU profiler unwind the inlined functions stack. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698