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

Side by Side Diff: runtime/vm/profiler.cc

Issue 1919743003: Add Profiler::DumpStackTrace (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 7 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 | « runtime/vm/profiler.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "platform/address_sanitizer.h" 5 #include "platform/address_sanitizer.h"
6 #include "platform/memory_sanitizer.h" 6 #include "platform/memory_sanitizer.h"
7 #include "platform/utils.h" 7 #include "platform/utils.h"
8 8
9 #include "vm/allocation.h" 9 #include "vm/allocation.h"
10 #include "vm/atomic.h" 10 #include "vm/atomic.h"
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
321 ClearProfileVisitor::ClearProfileVisitor(Isolate* isolate) 321 ClearProfileVisitor::ClearProfileVisitor(Isolate* isolate)
322 : SampleVisitor(isolate) { 322 : SampleVisitor(isolate) {
323 } 323 }
324 324
325 325
326 void ClearProfileVisitor::VisitSample(Sample* sample) { 326 void ClearProfileVisitor::VisitSample(Sample* sample) {
327 sample->Clear(); 327 sample->Clear();
328 } 328 }
329 329
330 330
331 static void DumpStackFrame(intptr_t frame, uword pc) {
srdjan 2016/04/25 20:05:55 maybe s/frame/frame_index/ ... also below
Cutch 2016/04/25 20:14:54 Done.
332 uintptr_t start = 0;
333 char* native_symbol_name =
334 NativeSymbolResolver::LookupSymbolName(pc, &start);
335 if (native_symbol_name == NULL) {
336 OS::Print("Frame[%" Pd "] = `unknown symbol` [0x%" Px "]\n", frame, pc);
337 } else {
338 OS::Print("Frame[%" Pd "] = `%s` [0x%" Px "]\n",
339 frame, native_symbol_name, pc);
340 free(native_symbol_name);
341 }
342 }
343
344
345 static void DumpStackFrame(intptr_t frame,
346 uword pc,
347 const Code& code) {
348 if (code.IsNull()) {
349 DumpStackFrame(frame, pc);
350 } else {
351 OS::Print("Frame[%" Pd "] = Dart:`%s` [0x%" Px "]\n",
352 frame, code.ToCString(), pc);
353 }
354 }
355
356
331 class ProfilerStackWalker : public ValueObject { 357 class ProfilerStackWalker : public ValueObject {
332 public: 358 public:
333 ProfilerStackWalker(Isolate* isolate, 359 ProfilerStackWalker(Isolate* isolate,
334 Sample* head_sample, 360 Sample* head_sample,
335 SampleBuffer* sample_buffer) 361 SampleBuffer* sample_buffer)
336 : isolate_(isolate), 362 : isolate_(isolate),
337 sample_(head_sample), 363 sample_(head_sample),
338 sample_buffer_(sample_buffer), 364 sample_buffer_(sample_buffer),
339 frame_index_(0), 365 frame_index_(0),
340 total_frames_(0) { 366 total_frames_(0) {
341 ASSERT(isolate_ != NULL); 367 ASSERT(isolate_ != NULL);
342 ASSERT(sample_ != NULL); 368 if (sample_ != NULL) {
srdjan 2016/04/25 20:05:55 I find using positive test (in most cases) to be m
Cutch 2016/04/25 20:14:54 Done.
343 ASSERT(sample_buffer_ != NULL); 369 ASSERT(sample_buffer_ != NULL);
344 ASSERT(sample_->head_sample()); 370 ASSERT(sample_->head_sample());
371 } else {
372 ASSERT(sample_buffer_ == NULL);
373 }
374 }
375
376 bool Append(uword pc, const Code& code) {
377 if (sample_ == NULL) {
378 DumpStackFrame(frame_index_, pc, code);
379 frame_index_++;
380 total_frames_++;
381 return true;
382 }
383 return Append(pc);
345 } 384 }
346 385
347 bool Append(uword pc) { 386 bool Append(uword pc) {
387 if (sample_ == NULL) {
388 DumpStackFrame(frame_index_, pc);
389 frame_index_++;
390 total_frames_++;
391 return true;
392 }
348 if (total_frames_ >= FLAG_max_profile_depth) { 393 if (total_frames_ >= FLAG_max_profile_depth) {
349 sample_->set_truncated_trace(true); 394 sample_->set_truncated_trace(true);
350 return false; 395 return false;
351 } 396 }
352 ASSERT(sample_ != NULL); 397 ASSERT(sample_ != NULL);
353 if (frame_index_ == kSampleSize) { 398 if (frame_index_ == kSampleSize) {
354 Sample* new_sample = sample_buffer_->ReserveSampleAndLink(sample_); 399 Sample* new_sample = sample_buffer_->ReserveSampleAndLink(sample_);
355 if (new_sample == NULL) { 400 if (new_sample == NULL) {
356 // Could not reserve new sample- mark this as truncated. 401 // Could not reserve new sample- mark this as truncated.
357 sample_->set_truncated_trace(true); 402 sample_->set_truncated_trace(true);
(...skipping 27 matching lines...) Expand all
385 SampleBuffer* sample_buffer) 430 SampleBuffer* sample_buffer)
386 : ProfilerStackWalker(isolate, sample, sample_buffer), 431 : ProfilerStackWalker(isolate, sample, sample_buffer),
387 frame_iterator_(thread) { 432 frame_iterator_(thread) {
388 } 433 }
389 434
390 void walk() { 435 void walk() {
391 // Mark that this sample was collected from an exit frame. 436 // Mark that this sample was collected from an exit frame.
392 sample_->set_exit_frame_sample(true); 437 sample_->set_exit_frame_sample(true);
393 438
394 StackFrame* frame = frame_iterator_.NextFrame(); 439 StackFrame* frame = frame_iterator_.NextFrame();
440 Code& code = Code::Handle();
srdjan 2016/04/25 20:05:55 Can you use zone here (from frame_iterator_ or Pro
Cutch 2016/04/25 20:14:54 I've actually re-worked this code here. It was uns
395 while (frame != NULL) { 441 while (frame != NULL) {
396 if (!Append(frame->pc())) { 442 code ^= frame->LookupDartCode();
443 if (!Append(frame->pc(), code)) {
397 return; 444 return;
398 } 445 }
399 frame = frame_iterator_.NextFrame(); 446 frame = frame_iterator_.NextFrame();
400 } 447 }
401 } 448 }
402 449
403 private: 450 private:
404 DartFrameIterator frame_iterator_; 451 DartFrameIterator frame_iterator_;
405 }; 452 };
406 453
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
574 : ProfilerStackWalker(isolate, sample, sample_buffer), 621 : ProfilerStackWalker(isolate, sample, sample_buffer),
575 stack_upper_(stack_upper), 622 stack_upper_(stack_upper),
576 original_pc_(pc), 623 original_pc_(pc),
577 original_fp_(fp), 624 original_fp_(fp),
578 original_sp_(sp), 625 original_sp_(sp),
579 lower_bound_(stack_lower) { 626 lower_bound_(stack_lower) {
580 } 627 }
581 628
582 void walk() { 629 void walk() {
583 const uword kMaxStep = VirtualMemory::PageSize(); 630 const uword kMaxStep = VirtualMemory::PageSize();
584
585 Append(original_pc_); 631 Append(original_pc_);
586 632
587 uword* pc = reinterpret_cast<uword*>(original_pc_); 633 uword* pc = reinterpret_cast<uword*>(original_pc_);
588 uword* fp = reinterpret_cast<uword*>(original_fp_); 634 uword* fp = reinterpret_cast<uword*>(original_fp_);
589 uword* previous_fp = fp; 635 uword* previous_fp = fp;
590 636
591 uword gap = original_fp_ - original_sp_; 637 uword gap = original_fp_ - original_sp_;
592 if (gap >= kMaxStep) { 638 if (gap >= kMaxStep) {
593 // Gap between frame pointer and stack pointer is 639 // Gap between frame pointer and stack pointer is
594 // too large. 640 // too large.
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
874 static uintptr_t GetProgramCounter() { 920 static uintptr_t GetProgramCounter() {
875 return reinterpret_cast<uintptr_t>(_ReturnAddress()); 921 return reinterpret_cast<uintptr_t>(_ReturnAddress());
876 } 922 }
877 #else 923 #else
878 static uintptr_t __attribute__((noinline)) GetProgramCounter() { 924 static uintptr_t __attribute__((noinline)) GetProgramCounter() {
879 return reinterpret_cast<uintptr_t>( 925 return reinterpret_cast<uintptr_t>(
880 __builtin_extract_return_addr(__builtin_return_address(0))); 926 __builtin_extract_return_addr(__builtin_return_address(0)));
881 } 927 }
882 #endif 928 #endif
883 929
930
931 void Profiler::DumpStackTrace(bool native_stack_trace) {
932 Thread* thread = Thread::Current();
933 ASSERT(thread != NULL);
934 OSThread* os_thread = thread->os_thread();
935 ASSERT(os_thread != NULL);
936 Isolate* isolate = thread->isolate();
937 if (!CheckIsolate(isolate)) {
938 return;
939 }
940
941 const bool exited_dart_code = thread->HasExitedDartCode();
942
943 OS::Print("Dumping %s stack trace for thread %" Px "\n",
944 native_stack_trace ? "native" : "dart-only",
945 static_cast<uintptr_t>(os_thread->trace_id()));
946
947 uintptr_t sp = Thread::GetCurrentStackPointer();
948 uintptr_t fp = 0;
949 uintptr_t pc = GetProgramCounter();
950
951 COPY_FP_REGISTER(fp);
952
953 uword stack_lower = 0;
954 uword stack_upper = 0;
955
956 if (!InitialRegisterCheck(pc, fp, sp)) {
957 OS::Print(
958 "Stack dump aborted because InitialRegisterCheck.\n");
959 return;
960 }
961
962 if (!GetAndValidateIsolateStackBounds(thread,
963 fp,
964 sp,
965 &stack_lower,
966 &stack_upper)) {
967 OS::Print(
968 "Stack dump aborted because GetAndValidateIsolateStackBounds.\n");
969 return;
970 }
971
972 if (native_stack_trace) {
973 ProfilerNativeStackWalker native_stack_walker(isolate,
974 NULL,
975 NULL,
976 stack_lower,
977 stack_upper,
978 pc,
979 fp,
980 sp);
981 native_stack_walker.walk();
982 } else if (exited_dart_code) {
983 ProfilerDartExitStackWalker dart_exit_stack_walker(thread,
984 isolate,
985 NULL,
986 NULL);
987 dart_exit_stack_walker.walk();
988 } else {
989 ProfilerDartStackWalker dart_stack_walker(isolate,
990 NULL,
991 NULL,
992 stack_lower,
993 stack_upper,
994 pc,
995 fp,
996 sp);
997 }
998 }
999
1000
884 void Profiler::SampleAllocation(Thread* thread, intptr_t cid) { 1001 void Profiler::SampleAllocation(Thread* thread, intptr_t cid) {
885 ASSERT(thread != NULL); 1002 ASSERT(thread != NULL);
886 OSThread* os_thread = thread->os_thread(); 1003 OSThread* os_thread = thread->os_thread();
887 ASSERT(os_thread != NULL); 1004 ASSERT(os_thread != NULL);
888 Isolate* isolate = thread->isolate(); 1005 Isolate* isolate = thread->isolate();
889 if (!CheckIsolate(isolate)) { 1006 if (!CheckIsolate(isolate)) {
890 return; 1007 return;
891 } 1008 }
892 1009
893 const bool exited_dart_code = thread->HasExitedDartCode(); 1010 const bool exited_dart_code = thread->HasExitedDartCode();
(...skipping 541 matching lines...) Expand 10 before | Expand all | Expand 10 after
1435 1552
1436 1553
1437 ProcessedSampleBuffer::ProcessedSampleBuffer() 1554 ProcessedSampleBuffer::ProcessedSampleBuffer()
1438 : code_lookup_table_(new CodeLookupTable(Thread::Current())) { 1555 : code_lookup_table_(new CodeLookupTable(Thread::Current())) {
1439 ASSERT(code_lookup_table_ != NULL); 1556 ASSERT(code_lookup_table_ != NULL);
1440 } 1557 }
1441 1558
1442 #endif // !PRODUCT 1559 #endif // !PRODUCT
1443 1560
1444 } // namespace dart 1561 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/profiler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698