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

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: rebaseline Created 4 years, 9 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
« no previous file with comments | « src/profiler/cpu-profiler.h ('k') | src/profiler/profile-generator.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 213
214 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, 214 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
215 AbstractCode* code, const char* name) { 215 AbstractCode* code, const char* name) {
216 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); 216 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
217 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; 217 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
218 rec->start = code->address(); 218 rec->start = code->address();
219 rec->entry = profiles_->NewCodeEntry( 219 rec->entry = profiles_->NewCodeEntry(
220 tag, profiles_->GetFunctionName(name), CodeEntry::kEmptyNamePrefix, 220 tag, profiles_->GetFunctionName(name), CodeEntry::kEmptyNamePrefix,
221 CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo, 221 CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo,
222 CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start()); 222 CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start());
223 RecordInliningInfo(rec->entry, code);
223 rec->size = code->ExecutableSize(); 224 rec->size = code->ExecutableSize();
224 processor_->Enqueue(evt_rec); 225 processor_->Enqueue(evt_rec);
225 } 226 }
226 227
227 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, 228 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
228 AbstractCode* code, Name* name) { 229 AbstractCode* code, Name* name) {
229 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); 230 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
230 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; 231 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
231 rec->start = code->address(); 232 rec->start = code->address();
232 rec->entry = profiles_->NewCodeEntry( 233 rec->entry = profiles_->NewCodeEntry(
233 tag, profiles_->GetFunctionName(name), CodeEntry::kEmptyNamePrefix, 234 tag, profiles_->GetFunctionName(name), CodeEntry::kEmptyNamePrefix,
234 CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo, 235 CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo,
235 CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start()); 236 CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start());
237 RecordInliningInfo(rec->entry, code);
236 rec->size = code->ExecutableSize(); 238 rec->size = code->ExecutableSize();
237 processor_->Enqueue(evt_rec); 239 processor_->Enqueue(evt_rec);
238 } 240 }
239 241
240 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, 242 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
241 AbstractCode* code, 243 AbstractCode* code,
242 SharedFunctionInfo* shared, 244 SharedFunctionInfo* shared,
243 CompilationInfo* info, Name* script_name) { 245 CompilationInfo* info, Name* script_name) {
244 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); 246 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
245 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; 247 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
246 rec->start = code->address(); 248 rec->start = code->address();
247 rec->entry = profiles_->NewCodeEntry( 249 rec->entry = profiles_->NewCodeEntry(
248 tag, profiles_->GetFunctionName(shared->DebugName()), 250 tag, profiles_->GetFunctionName(shared->DebugName()),
249 CodeEntry::kEmptyNamePrefix, profiles_->GetName(script_name), 251 CodeEntry::kEmptyNamePrefix, profiles_->GetName(script_name),
250 CpuProfileNode::kNoLineNumberInfo, CpuProfileNode::kNoColumnNumberInfo, 252 CpuProfileNode::kNoLineNumberInfo, CpuProfileNode::kNoColumnNumberInfo,
251 NULL, code->instruction_start()); 253 NULL, code->instruction_start());
254 RecordInliningInfo(rec->entry, code);
252 if (info) { 255 if (info) {
253 rec->entry->set_inlined_function_infos(info->inlined_function_infos()); 256 rec->entry->set_inlined_function_infos(info->inlined_function_infos());
254 } 257 }
255 rec->entry->FillFunctionInfo(shared); 258 rec->entry->FillFunctionInfo(shared);
256 rec->size = code->ExecutableSize(); 259 rec->size = code->ExecutableSize();
257 processor_->Enqueue(evt_rec); 260 processor_->Enqueue(evt_rec);
258 } 261 }
259 262
260 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, 263 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
261 AbstractCode* abstract_code, 264 AbstractCode* abstract_code,
(...skipping 23 matching lines...) Expand all
285 } 288 }
286 } else { 289 } else {
287 DCHECK(abstract_code->IsBytecodeArray()); 290 DCHECK(abstract_code->IsBytecodeArray());
288 // TODO(rmcilroy): source position tracking for bytecode arrays. 291 // TODO(rmcilroy): source position tracking for bytecode arrays.
289 } 292 }
290 } 293 }
291 rec->entry = profiles_->NewCodeEntry( 294 rec->entry = profiles_->NewCodeEntry(
292 tag, profiles_->GetFunctionName(shared->DebugName()), 295 tag, profiles_->GetFunctionName(shared->DebugName()),
293 CodeEntry::kEmptyNamePrefix, profiles_->GetName(script_name), line, 296 CodeEntry::kEmptyNamePrefix, profiles_->GetName(script_name), line,
294 column, line_table, abstract_code->instruction_start()); 297 column, line_table, abstract_code->instruction_start());
298 RecordInliningInfo(rec->entry, abstract_code);
295 if (info) { 299 if (info) {
296 rec->entry->set_inlined_function_infos(info->inlined_function_infos()); 300 rec->entry->set_inlined_function_infos(info->inlined_function_infos());
297 } 301 }
298 rec->entry->FillFunctionInfo(shared); 302 rec->entry->FillFunctionInfo(shared);
299 rec->size = abstract_code->ExecutableSize(); 303 rec->size = abstract_code->ExecutableSize();
300 processor_->Enqueue(evt_rec); 304 processor_->Enqueue(evt_rec);
301 } 305 }
302 306
303 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, 307 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
304 AbstractCode* code, int args_count) { 308 AbstractCode* code, int args_count) {
305 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); 309 CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
306 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; 310 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
307 rec->start = code->address(); 311 rec->start = code->address();
308 rec->entry = profiles_->NewCodeEntry( 312 rec->entry = profiles_->NewCodeEntry(
309 tag, profiles_->GetName(args_count), "args_count: ", 313 tag, profiles_->GetName(args_count), "args_count: ",
310 CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo, 314 CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo,
311 CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start()); 315 CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start());
316 RecordInliningInfo(rec->entry, code);
312 rec->size = code->ExecutableSize(); 317 rec->size = code->ExecutableSize();
313 processor_->Enqueue(evt_rec); 318 processor_->Enqueue(evt_rec);
314 } 319 }
315 320
316 void CpuProfiler::CodeMoveEvent(AbstractCode* from, Address to) { 321 void CpuProfiler::CodeMoveEvent(AbstractCode* from, Address to) {
317 CodeEventsContainer evt_rec(CodeEventRecord::CODE_MOVE); 322 CodeEventsContainer evt_rec(CodeEventRecord::CODE_MOVE);
318 CodeMoveEventRecord* rec = &evt_rec.CodeMoveEventRecord_; 323 CodeMoveEventRecord* rec = &evt_rec.CodeMoveEventRecord_;
319 rec->from = from->address(); 324 rec->from = from->address();
320 rec->to = to; 325 rec->to = to;
321 processor_->Enqueue(evt_rec); 326 processor_->Enqueue(evt_rec);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; 377 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
373 rec->start = entry_point; 378 rec->start = entry_point;
374 rec->entry = profiles_->NewCodeEntry( 379 rec->entry = profiles_->NewCodeEntry(
375 Logger::CALLBACK_TAG, 380 Logger::CALLBACK_TAG,
376 profiles_->GetName(name), 381 profiles_->GetName(name),
377 "set "); 382 "set ");
378 rec->size = 1; 383 rec->size = 1;
379 processor_->Enqueue(evt_rec); 384 processor_->Enqueue(evt_rec);
380 } 385 }
381 386
387 void CpuProfiler::RecordInliningInfo(CodeEntry* entry,
388 AbstractCode* abstract_code) {
389 if (!abstract_code->IsCode()) return;
390 Code* code = abstract_code->GetCode();
391 if (code->kind() != Code::OPTIMIZED_FUNCTION) return;
392 DeoptimizationInputData* deopt_input_data =
393 DeoptimizationInputData::cast(code->deoptimization_data());
394 int deopt_count = deopt_input_data->DeoptCount();
395 for (int i = 0; i < deopt_count; i++) {
396 int pc_offset = deopt_input_data->Pc(i)->value();
397 if (pc_offset == -1) continue;
398 int translation_index = deopt_input_data->TranslationIndex(i)->value();
399 TranslationIterator it(deopt_input_data->TranslationByteArray(),
400 translation_index);
401 Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next());
402 DCHECK_EQ(Translation::BEGIN, opcode);
403 it.Skip(Translation::NumberOfOperandsFor(opcode));
404 int depth = 0;
405 std::vector<CodeEntry*> inline_stack;
406 while (it.HasNext() &&
407 Translation::BEGIN !=
408 (opcode = static_cast<Translation::Opcode>(it.Next()))) {
409 if (opcode != Translation::JS_FRAME &&
410 opcode != Translation::INTERPRETED_FRAME) {
411 it.Skip(Translation::NumberOfOperandsFor(opcode));
412 continue;
413 }
414 it.Next(); // Skip ast_id
415 int shared_info_id = it.Next();
416 it.Next(); // Skip height
417 SharedFunctionInfo* shared_info = SharedFunctionInfo::cast(
418 deopt_input_data->LiteralArray()->get(shared_info_id));
419 if (!depth++) continue; // Skip the current function itself.
420 CodeEntry* inline_entry = new CodeEntry(
421 entry->tag(), profiles_->GetFunctionName(shared_info->DebugName()),
422 CodeEntry::kEmptyNamePrefix, entry->resource_name(),
423 CpuProfileNode::kNoLineNumberInfo,
424 CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start());
425 inline_entry->FillFunctionInfo(shared_info);
426 inline_stack.push_back(inline_entry);
427 }
428 if (!inline_stack.empty()) {
429 entry->AddInlineStack(pc_offset, inline_stack);
430 DCHECK(inline_stack.empty());
431 }
432 }
433 }
382 434
383 CpuProfiler::CpuProfiler(Isolate* isolate) 435 CpuProfiler::CpuProfiler(Isolate* isolate)
384 : isolate_(isolate), 436 : isolate_(isolate),
385 sampling_interval_(base::TimeDelta::FromMicroseconds( 437 sampling_interval_(base::TimeDelta::FromMicroseconds(
386 FLAG_cpu_profiler_sampling_interval)), 438 FLAG_cpu_profiler_sampling_interval)),
387 profiles_(new CpuProfilesCollection(isolate->heap())), 439 profiles_(new CpuProfilesCollection(isolate->heap())),
388 generator_(NULL), 440 generator_(NULL),
389 processor_(NULL), 441 processor_(NULL),
390 is_profiling_(false) { 442 is_profiling_(false) {
391 } 443 }
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
519 Builtins::Name id = static_cast<Builtins::Name>(i); 571 Builtins::Name id = static_cast<Builtins::Name>(i);
520 rec->start = builtins->builtin(id)->address(); 572 rec->start = builtins->builtin(id)->address();
521 rec->builtin_id = id; 573 rec->builtin_id = id;
522 processor_->Enqueue(evt_rec); 574 processor_->Enqueue(evt_rec);
523 } 575 }
524 } 576 }
525 577
526 578
527 } // namespace internal 579 } // namespace internal
528 } // namespace v8 580 } // namespace v8
OLDNEW
« no previous file with comments | « src/profiler/cpu-profiler.h ('k') | src/profiler/profile-generator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698