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