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

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

Issue 230863005: Initial UserTag and dart:profiler library (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 8 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/profiler.h ('k') | runtime/vm/raw_object.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 (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/utils.h" 5 #include "platform/utils.h"
6 6
7 #include "vm/allocation.h" 7 #include "vm/allocation.h"
8 #include "vm/atomic.h" 8 #include "vm/atomic.h"
9 #include "vm/code_patcher.h" 9 #include "vm/code_patcher.h"
10 #include "vm/isolate.h" 10 #include "vm/isolate.h"
(...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 } 559 }
560 PrintCollectedCode(&obj); 560 PrintCollectedCode(&obj);
561 } else if (kind() == kReusedCode) { 561 } else if (kind() == kReusedCode) {
562 if (name() == NULL) { 562 if (name() == NULL) {
563 // Lazily set generated name. 563 // Lazily set generated name.
564 GenerateAndSetSymbolName("[Reused]"); 564 GenerateAndSetSymbolName("[Reused]");
565 } 565 }
566 PrintOverwrittenCode(&obj); 566 PrintOverwrittenCode(&obj);
567 } else if (kind() == kTagCode) { 567 } else if (kind() == kTagCode) {
568 if (name() == NULL) { 568 if (name() == NULL) {
569 const char* tag_name = start() == 0 ? "root" : VMTag::TagName(start()); 569 if (UserTags::IsUserTag(start())) {
570 ASSERT(tag_name != NULL); 570 const char* tag_name = UserTags::TagName(start());
571 SetName(tag_name); 571 ASSERT(tag_name != NULL);
572 SetName(tag_name);
573 } else if (VMTag::IsVMTag(start()) ||
574 VMTag::IsRuntimeEntryTag(start()) ||
575 VMTag::IsNativeEntryTag(start())) {
576 const char* tag_name = VMTag::TagName(start());
577 ASSERT(tag_name != NULL);
578 SetName(tag_name);
579 } else {
580 ASSERT(start() == 0);
581 SetName("root");
582 }
572 } 583 }
573 PrintTagCode(&obj); 584 PrintTagCode(&obj);
574 } else { 585 } else {
575 ASSERT(kind() == kNativeCode); 586 ASSERT(kind() == kNativeCode);
576 if (name() == NULL) { 587 if (name() == NULL) {
577 // Lazily set generated name. 588 // Lazily set generated name.
578 GenerateAndSetSymbolName("[Native]"); 589 GenerateAndSetSymbolName("[Native]");
579 } 590 }
580 PrintNativeCode(&obj); 591 PrintNativeCode(&obj);
581 } 592 }
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after
927 if (timestamp < min_time_) { 938 if (timestamp < min_time_) {
928 min_time_ = timestamp; 939 min_time_ = timestamp;
929 } 940 }
930 // Make sure VM tag is created. 941 // Make sure VM tag is created.
931 if (VMTag::IsNativeEntryTag(sample->vm_tag())) { 942 if (VMTag::IsNativeEntryTag(sample->vm_tag())) {
932 CreateTag(VMTag::kNativeTagId); 943 CreateTag(VMTag::kNativeTagId);
933 } else if (VMTag::IsRuntimeEntryTag(sample->vm_tag())) { 944 } else if (VMTag::IsRuntimeEntryTag(sample->vm_tag())) {
934 CreateTag(VMTag::kRuntimeTagId); 945 CreateTag(VMTag::kRuntimeTagId);
935 } 946 }
936 CreateTag(sample->vm_tag()); 947 CreateTag(sample->vm_tag());
948 // Make sure user tag is created.
949 CreateUserTag(sample->user_tag());
937 // Exclusive tick for bottom frame. 950 // Exclusive tick for bottom frame.
938 Tick(sample->At(0), true, timestamp); 951 Tick(sample->At(0), true, timestamp);
939 // Inclusive tick for all frames. 952 // Inclusive tick for all frames.
940 for (intptr_t i = 0; i < FLAG_profile_depth; i++) { 953 for (intptr_t i = 0; i < FLAG_profile_depth; i++) {
941 if (sample->At(i) == 0) { 954 if (sample->At(i) == 0) {
942 break; 955 break;
943 } 956 }
944 frames_++; 957 frames_++;
945 Tick(sample->At(i), false, timestamp); 958 Tick(sample->At(i), false, timestamp);
946 } 959 }
(...skipping 15 matching lines...) Expand all
962 } 975 }
963 CodeRegion* region = new CodeRegion(CodeRegion::kTagCode, 976 CodeRegion* region = new CodeRegion(CodeRegion::kTagCode,
964 tag, 977 tag,
965 tag + 1, 978 tag + 1,
966 0); 979 0);
967 index = tag_code_table_->InsertCodeRegion(region); 980 index = tag_code_table_->InsertCodeRegion(region);
968 ASSERT(index >= 0); 981 ASSERT(index >= 0);
969 region->set_creation_serial(visited()); 982 region->set_creation_serial(visited());
970 } 983 }
971 984
985 void CreateUserTag(uword tag) {
986 if (tag == 0) {
987 // None set.
988 return;
989 }
990 intptr_t index = tag_code_table_->FindIndex(tag);
991 if (index >= 0) {
992 // Already created.
993 return;
994 }
995 CodeRegion* region = new CodeRegion(CodeRegion::kTagCode,
996 tag,
997 tag + 1,
998 0);
999 index = tag_code_table_->InsertCodeRegion(region);
1000 ASSERT(index >= 0);
1001 region->set_creation_serial(visited());
1002 }
1003
972 void Tick(uword pc, bool exclusive, int64_t timestamp) { 1004 void Tick(uword pc, bool exclusive, int64_t timestamp) {
973 CodeRegionTable::TickResult r; 1005 CodeRegionTable::TickResult r;
974 intptr_t serial = exclusive ? -1 : visited(); 1006 intptr_t serial = exclusive ? -1 : visited();
975 r = live_code_table_->Tick(pc, exclusive, serial, timestamp); 1007 r = live_code_table_->Tick(pc, exclusive, serial, timestamp);
976 if (r == CodeRegionTable::kTicked) { 1008 if (r == CodeRegionTable::kTicked) {
977 // Live code found and ticked. 1009 // Live code found and ticked.
978 return; 1010 return;
979 } 1011 }
980 if (r == CodeRegionTable::kNewerCode) { 1012 if (r == CodeRegionTable::kNewerCode) {
981 // Code has been overwritten by newer code. 1013 // Code has been overwritten by newer code.
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
1101 root_ = new CodeRegionTrieNode(tag_code_table_offset_ + root_index); 1133 root_ = new CodeRegionTrieNode(tag_code_table_offset_ + root_index);
1102 // Use tags by default. 1134 // Use tags by default.
1103 set_use_tags(true); 1135 set_use_tags(true);
1104 } 1136 }
1105 1137
1106 void VisitSample(Sample* sample) { 1138 void VisitSample(Sample* sample) {
1107 // Give the root a tick. 1139 // Give the root a tick.
1108 root_->Tick(); 1140 root_->Tick();
1109 CodeRegionTrieNode* current = root_; 1141 CodeRegionTrieNode* current = root_;
1110 if (use_tags()) { 1142 if (use_tags()) {
1143 intptr_t user_tag_index = FindTagIndex(sample->user_tag());
1144 if (user_tag_index >= 0) {
1145 current = current->GetChild(user_tag_index);
1146 // Give the tag a tick.
1147 current->Tick();
1148 }
1111 if (VMTag::IsNativeEntryTag(sample->vm_tag())) { 1149 if (VMTag::IsNativeEntryTag(sample->vm_tag())) {
1112 // Insert a dummy kNativeTagId node. 1150 // Insert a dummy kNativeTagId node.
1113 intptr_t tag_index = FindTagIndex(VMTag::kNativeTagId); 1151 intptr_t tag_index = FindTagIndex(VMTag::kNativeTagId);
1114 current = current->GetChild(tag_index); 1152 current = current->GetChild(tag_index);
1115 // Give the tag a tick. 1153 // Give the tag a tick.
1116 current->Tick(); 1154 current->Tick();
1117 } else if (VMTag::IsRuntimeEntryTag(sample->vm_tag())) { 1155 } else if (VMTag::IsRuntimeEntryTag(sample->vm_tag())) {
1118 // Insert a dummy kRuntimeTagId node. 1156 // Insert a dummy kRuntimeTagId node.
1119 intptr_t tag_index = FindTagIndex(VMTag::kRuntimeTagId); 1157 intptr_t tag_index = FindTagIndex(VMTag::kRuntimeTagId);
1120 current = current->GetChild(tag_index); 1158 current = current->GetChild(tag_index);
(...skipping 23 matching lines...) Expand all
1144 bool use_tags() const { 1182 bool use_tags() const {
1145 return use_tags_; 1183 return use_tags_;
1146 } 1184 }
1147 1185
1148 void set_use_tags(bool use_tags) { 1186 void set_use_tags(bool use_tags) {
1149 use_tags_ = use_tags; 1187 use_tags_ = use_tags;
1150 } 1188 }
1151 1189
1152 private: 1190 private:
1153 intptr_t FindTagIndex(uword tag) const { 1191 intptr_t FindTagIndex(uword tag) const {
1192 if (tag == 0) {
1193 return -1;
1194 }
1154 intptr_t index = tag_code_table_->FindIndex(tag); 1195 intptr_t index = tag_code_table_->FindIndex(tag);
1196 if (index <= 0) {
1197 return -1;
1198 }
1155 ASSERT(index >= 0); 1199 ASSERT(index >= 0);
1156 ASSERT((tag_code_table_->At(index))->contains(tag)); 1200 ASSERT((tag_code_table_->At(index))->contains(tag));
1157 return tag_code_table_offset_ + index; 1201 return tag_code_table_offset_ + index;
1158 } 1202 }
1159 1203
1160 intptr_t FindFinalIndex(uword pc, int64_t timestamp) const { 1204 intptr_t FindFinalIndex(uword pc, int64_t timestamp) const {
1161 intptr_t index = live_code_table_->FindIndex(pc); 1205 intptr_t index = live_code_table_->FindIndex(pc);
1162 ASSERT(index >= 0); 1206 ASSERT(index >= 0);
1163 CodeRegion* region = live_code_table_->At(index); 1207 CodeRegion* region = live_code_table_->At(index);
1164 ASSERT(region->contains(pc)); 1208 ASSERT(region->contains(pc));
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after
1516 // The stack pointer gives us a better lower bound than 1560 // The stack pointer gives us a better lower bound than
1517 // the isolates stack limit. 1561 // the isolates stack limit.
1518 lower_bound_ = original_sp_; 1562 lower_bound_ = original_sp_;
1519 } 1563 }
1520 int i = 0; 1564 int i = 0;
1521 for (; i < FLAG_profile_depth; i++) { 1565 for (; i < FLAG_profile_depth; i++) {
1522 if (FLAG_profile_verify_stack_walk) { 1566 if (FLAG_profile_verify_stack_walk) {
1523 VerifyCodeAddress(heap, i, reinterpret_cast<uword>(pc)); 1567 VerifyCodeAddress(heap, i, reinterpret_cast<uword>(pc));
1524 } 1568 }
1525 sample_->SetAt(i, reinterpret_cast<uword>(pc)); 1569 sample_->SetAt(i, reinterpret_cast<uword>(pc));
1570 if (fp == NULL) {
1571 return i + 1;
1572 }
1526 if (!ValidFramePointer(fp)) { 1573 if (!ValidFramePointer(fp)) {
1527 return i + 1; 1574 return i + 1;
1528 } 1575 }
1529 pc = CallerPC(fp); 1576 pc = CallerPC(fp);
1530 previous_fp = fp; 1577 previous_fp = fp;
1531 fp = CallerFP(fp); 1578 fp = CallerFP(fp);
1532 intptr_t step = fp - previous_fp; 1579 intptr_t step = fp - previous_fp;
1533 if ((step >= kMaxStep) || (fp <= previous_fp) || !ValidFramePointer(fp)) { 1580 if (fp == NULL) {
1581 return i + 1;
1582 }
1583 if ((step >= kMaxStep)) {
1534 // Frame pointer step is too large. 1584 // Frame pointer step is too large.
1585 return i + 1;
1586 }
1587 if ((fp <= previous_fp)) {
1535 // Frame pointer did not move to a higher address. 1588 // Frame pointer did not move to a higher address.
1589 return i + 1;
1590 }
1591 if (!ValidFramePointer(fp)) {
1536 // Frame pointer is outside of isolate stack bounds. 1592 // Frame pointer is outside of isolate stack bounds.
1537 return i + 1; 1593 return i + 1;
1538 } 1594 }
1539 // Move the lower bound up. 1595 // Move the lower bound up.
1540 lower_bound_ = reinterpret_cast<uword>(fp); 1596 lower_bound_ = reinterpret_cast<uword>(fp);
1541 } 1597 }
1542 return i; 1598 return i;
1543 } 1599 }
1544 1600
1545 private: 1601 private:
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1603 if (profiler_data == NULL) { 1659 if (profiler_data == NULL) {
1604 return; 1660 return;
1605 } 1661 }
1606 SampleBuffer* sample_buffer = profiler_data->sample_buffer(); 1662 SampleBuffer* sample_buffer = profiler_data->sample_buffer();
1607 if (sample_buffer == NULL) { 1663 if (sample_buffer == NULL) {
1608 return; 1664 return;
1609 } 1665 }
1610 Sample* sample = sample_buffer->ReserveSample(); 1666 Sample* sample = sample_buffer->ReserveSample();
1611 sample->Init(isolate, OS::GetCurrentTimeMicros(), state.tid); 1667 sample->Init(isolate, OS::GetCurrentTimeMicros(), state.tid);
1612 sample->set_vm_tag(isolate->vm_tag()); 1668 sample->set_vm_tag(isolate->vm_tag());
1669 sample->set_user_tag(isolate->user_tag());
1613 if (FLAG_profile_native_stack) { 1670 if (FLAG_profile_native_stack) {
1614 // Collect native and Dart frames. 1671 // Collect native and Dart frames.
1615 uword stack_lower = 0; 1672 uword stack_lower = 0;
1616 uword stack_upper = 0; 1673 uword stack_upper = 0;
1617 isolate->GetStackBounds(&stack_lower, &stack_upper); 1674 isolate->GetStackBounds(&stack_lower, &stack_upper);
1618 if ((stack_lower == 0) || (stack_upper == 0)) { 1675 if ((stack_lower == 0) || (stack_upper == 0)) {
1619 stack_lower = 0; 1676 stack_lower = 0;
1620 stack_upper = 0; 1677 stack_upper = 0;
1621 } 1678 }
1622 ProfilerNativeStackWalker stackWalker(sample, stack_lower, stack_upper, 1679 ProfilerNativeStackWalker stackWalker(sample, stack_lower, stack_upper,
1623 state.pc, state.fp, state.sp); 1680 state.pc, state.fp, state.sp);
1624 stackWalker.walk(isolate->heap()); 1681 stackWalker.walk(isolate->heap());
1625 } else { 1682 } else {
1626 if (isolate->top_exit_frame_info() != 0) { 1683 if (isolate->top_exit_frame_info() != 0) {
1627 ProfilerDartStackWalker stackWalker(sample); 1684 ProfilerDartStackWalker stackWalker(sample);
1628 stackWalker.walk(); 1685 stackWalker.walk();
1629 } else { 1686 } else {
1630 // TODO(johnmccutchan): Support collecting only Dart frames with 1687 // TODO(johnmccutchan): Support collecting only Dart frames with
1631 // ProfilerNativeStackWalker. 1688 // ProfilerNativeStackWalker.
1632 } 1689 }
1633 } 1690 }
1634 } 1691 }
1635 1692
1636 } // namespace dart 1693 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/profiler.h ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698