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

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
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 546 matching lines...) Expand 10 before | Expand all | Expand 10 after
557 } 557 }
558 PrintCollectedCode(&obj); 558 PrintCollectedCode(&obj);
559 } else if (kind() == kReusedCode) { 559 } else if (kind() == kReusedCode) {
560 if (name() == NULL) { 560 if (name() == NULL) {
561 // Lazily set generated name. 561 // Lazily set generated name.
562 GenerateAndSetSymbolName("[Reused]"); 562 GenerateAndSetSymbolName("[Reused]");
563 } 563 }
564 PrintOverwrittenCode(&obj); 564 PrintOverwrittenCode(&obj);
565 } else if (kind() == kTagCode) { 565 } else if (kind() == kTagCode) {
566 if (name() == NULL) { 566 if (name() == NULL) {
567 const char* tag_name = start() == 0 ? "root" : VMTag::TagName(start()); 567 if (VMTag::IsVMTag(start())) {
568 ASSERT(tag_name != NULL); 568 const char* tag_name = VMTag::TagName(start());
569 SetName(tag_name); 569 ASSERT(tag_name != NULL);
570 SetName(tag_name);
571 } else if (start() != 0) {
572 const char* tag_name = UserTagHelper::TagName(start());
573 ASSERT(tag_name != NULL);
574 SetName(tag_name);
575 } else {
576 SetName("root");
577 }
570 } 578 }
571 PrintTagCode(&obj); 579 PrintTagCode(&obj);
572 } else { 580 } else {
573 ASSERT(kind() == kNativeCode); 581 ASSERT(kind() == kNativeCode);
574 if (name() == NULL) { 582 if (name() == NULL) {
575 // Lazily set generated name. 583 // Lazily set generated name.
576 GenerateAndSetSymbolName("[Native]"); 584 GenerateAndSetSymbolName("[Native]");
577 } 585 }
578 PrintNativeCode(&obj); 586 PrintNativeCode(&obj);
579 } 587 }
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
920 void VisitSample(Sample* sample) { 928 void VisitSample(Sample* sample) {
921 int64_t timestamp = sample->timestamp(); 929 int64_t timestamp = sample->timestamp();
922 if (timestamp > max_time_) { 930 if (timestamp > max_time_) {
923 max_time_ = timestamp; 931 max_time_ = timestamp;
924 } 932 }
925 if (timestamp < min_time_) { 933 if (timestamp < min_time_) {
926 min_time_ = timestamp; 934 min_time_ = timestamp;
927 } 935 }
928 // Make sure VM tag is created. 936 // Make sure VM tag is created.
929 CreateTag(sample->vm_tag()); 937 CreateTag(sample->vm_tag());
938 // Make sure user tag is created.
939 CreateUserTag(sample->user_tag());
930 // Exclusive tick for bottom frame. 940 // Exclusive tick for bottom frame.
931 Tick(sample->At(0), true, timestamp); 941 Tick(sample->At(0), true, timestamp);
932 // Inclusive tick for all frames. 942 // Inclusive tick for all frames.
933 for (intptr_t i = 0; i < FLAG_profile_depth; i++) { 943 for (intptr_t i = 0; i < FLAG_profile_depth; i++) {
934 if (sample->At(i) == 0) { 944 if (sample->At(i) == 0) {
935 break; 945 break;
936 } 946 }
937 frames_++; 947 frames_++;
938 Tick(sample->At(i), false, timestamp); 948 Tick(sample->At(i), false, timestamp);
939 } 949 }
(...skipping 15 matching lines...) Expand all
955 } 965 }
956 CodeRegion* region = new CodeRegion(CodeRegion::kTagCode, 966 CodeRegion* region = new CodeRegion(CodeRegion::kTagCode,
957 tag, 967 tag,
958 tag + 1, 968 tag + 1,
959 0); 969 0);
960 index = tag_code_table_->InsertCodeRegion(region); 970 index = tag_code_table_->InsertCodeRegion(region);
961 ASSERT(index >= 0); 971 ASSERT(index >= 0);
962 region->set_creation_serial(visited()); 972 region->set_creation_serial(visited());
963 } 973 }
964 974
975 void CreateUserTag(uword tag) {
976 intptr_t index = tag_code_table_->FindIndex(tag);
977 if (index >= 0) {
978 // Already created.
979 return;
980 }
981 CodeRegion* region = new CodeRegion(CodeRegion::kTagCode,
982 tag,
983 tag + 1,
984 0);
985 index = tag_code_table_->InsertCodeRegion(region);
986 ASSERT(index >= 0);
987 region->set_creation_serial(visited());
988 }
989
965 void Tick(uword pc, bool exclusive, int64_t timestamp) { 990 void Tick(uword pc, bool exclusive, int64_t timestamp) {
966 CodeRegionTable::TickResult r; 991 CodeRegionTable::TickResult r;
967 intptr_t serial = exclusive ? -1 : visited(); 992 intptr_t serial = exclusive ? -1 : visited();
968 r = live_code_table_->Tick(pc, exclusive, serial, timestamp); 993 r = live_code_table_->Tick(pc, exclusive, serial, timestamp);
969 if (r == CodeRegionTable::kTicked) { 994 if (r == CodeRegionTable::kTicked) {
970 // Live code found and ticked. 995 // Live code found and ticked.
971 return; 996 return;
972 } 997 }
973 if (r == CodeRegionTable::kNewerCode) { 998 if (r == CodeRegionTable::kNewerCode) {
974 // Code has been overwritten by newer code. 999 // Code has been overwritten by newer code.
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
1094 root_ = new CodeRegionTrieNode(tag_code_table_offset_ + root_index); 1119 root_ = new CodeRegionTrieNode(tag_code_table_offset_ + root_index);
1095 // Use tags by default. 1120 // Use tags by default.
1096 set_use_tags(true); 1121 set_use_tags(true);
1097 } 1122 }
1098 1123
1099 void VisitSample(Sample* sample) { 1124 void VisitSample(Sample* sample) {
1100 // Give the root a tick. 1125 // Give the root a tick.
1101 root_->Tick(); 1126 root_->Tick();
1102 CodeRegionTrieNode* current = root_; 1127 CodeRegionTrieNode* current = root_;
1103 if (use_tags()) { 1128 if (use_tags()) {
1104 intptr_t tag_index = FindTagIndex(sample->vm_tag()); 1129 intptr_t user_tag_index = FindTagIndex(sample->user_tag());
1105 current = current->GetChild(tag_index); 1130 if (user_tag_index >= 0) {
1131 current = current->GetChild(user_tag_index);
1132 // Give the tag a tick.
1133 current->Tick();
1134 }
1135 intptr_t vm_tag_index = FindTagIndex(sample->vm_tag());
1136 current = current->GetChild(vm_tag_index);
1106 // Give the tag a tick. 1137 // Give the tag a tick.
1107 current->Tick(); 1138 current->Tick();
1108 } 1139 }
1109 // Walk the sampled PCs. 1140 // Walk the sampled PCs.
1110 for (intptr_t i = 0; i < FLAG_profile_depth; i++) { 1141 for (intptr_t i = 0; i < FLAG_profile_depth; i++) {
1111 if (sample->At(i) == 0) { 1142 if (sample->At(i) == 0) {
1112 break; 1143 break;
1113 } 1144 }
1114 intptr_t index = FindFinalIndex(sample->At(i), sample->timestamp()); 1145 intptr_t index = FindFinalIndex(sample->At(i), sample->timestamp());
1115 current = current->GetChild(index); 1146 current = current->GetChild(index);
1116 current->Tick(); 1147 current->Tick();
1117 } 1148 }
1118 } 1149 }
1119 1150
1120 CodeRegionTrieNode* root() const { 1151 CodeRegionTrieNode* root() const {
1121 return root_; 1152 return root_;
1122 } 1153 }
1123 1154
1124 bool use_tags() const { 1155 bool use_tags() const {
1125 return use_tags_; 1156 return use_tags_;
1126 } 1157 }
1127 1158
1128 void set_use_tags(bool use_tags) { 1159 void set_use_tags(bool use_tags) {
1129 use_tags_ = use_tags; 1160 use_tags_ = use_tags;
1130 } 1161 }
1131 1162
1132 private: 1163 private:
1133 intptr_t FindTagIndex(uword tag) const { 1164 intptr_t FindTagIndex(uword tag) const {
1134 intptr_t index = tag_code_table_->FindIndex(tag); 1165 intptr_t index = tag_code_table_->FindIndex(tag);
1166 if (index <= 0) {
1167 return -1;
1168 }
1135 ASSERT(index >= 0); 1169 ASSERT(index >= 0);
1136 ASSERT((tag_code_table_->At(index))->contains(tag)); 1170 ASSERT((tag_code_table_->At(index))->contains(tag));
1137 return tag_code_table_offset_ + index; 1171 return tag_code_table_offset_ + index;
1138 } 1172 }
1139 1173
1140 intptr_t FindFinalIndex(uword pc, int64_t timestamp) const { 1174 intptr_t FindFinalIndex(uword pc, int64_t timestamp) const {
1141 intptr_t index = live_code_table_->FindIndex(pc); 1175 intptr_t index = live_code_table_->FindIndex(pc);
1142 ASSERT(index >= 0); 1176 ASSERT(index >= 0);
1143 CodeRegion* region = live_code_table_->At(index); 1177 CodeRegion* region = live_code_table_->At(index);
1144 ASSERT(region->contains(pc)); 1178 ASSERT(region->contains(pc));
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
1424 uword sp) 1458 uword sp)
1425 : sample_(sample), 1459 : sample_(sample),
1426 stack_upper_(stack_upper), 1460 stack_upper_(stack_upper),
1427 original_pc_(pc), 1461 original_pc_(pc),
1428 original_fp_(fp), 1462 original_fp_(fp),
1429 original_sp_(sp), 1463 original_sp_(sp),
1430 lower_bound_(stack_lower) { 1464 lower_bound_(stack_lower) {
1431 ASSERT(sample_ != NULL); 1465 ASSERT(sample_ != NULL);
1432 } 1466 }
1433 1467
1434 int walk(Heap* heap, uword vm_tag) { 1468 int walk(Heap* heap, uword vm_tag, uword user_tag) {
1435 const intptr_t kMaxStep = 0x1000; // 4K. 1469 const intptr_t kMaxStep = 0x1000; // 4K.
1436 const bool kWalkStack = true; // Walk the stack. 1470 const bool kWalkStack = true; // Walk the stack.
1437 // Always store the exclusive PC. 1471 // Always store the exclusive PC.
1438 sample_->SetAt(0, original_pc_); 1472 sample_->SetAt(0, original_pc_);
1439 // Always store the vm tag. 1473 // Always store the vm tag.
1440 sample_->set_vm_tag(vm_tag); 1474 sample_->set_vm_tag(vm_tag);
1475 // Always store the user tag.
1476 sample_->set_user_tag(user_tag);
1441 if (!kWalkStack) { 1477 if (!kWalkStack) {
1442 // Not walking the stack, only took exclusive sample. 1478 // Not walking the stack, only took exclusive sample.
1443 return 1; 1479 return 1;
1444 } 1480 }
1445 uword* pc = reinterpret_cast<uword*>(original_pc_); 1481 uword* pc = reinterpret_cast<uword*>(original_pc_);
1446 uword* fp = reinterpret_cast<uword*>(original_fp_); 1482 uword* fp = reinterpret_cast<uword*>(original_fp_);
1447 uword* previous_fp = fp; 1483 uword* previous_fp = fp;
1448 if (original_sp_ > original_fp_) { 1484 if (original_sp_ > original_fp_) {
1449 // Stack pointer should not be above frame pointer. 1485 // Stack pointer should not be above frame pointer.
1450 return 1; 1486 return 1;
1451 } 1487 }
1452 intptr_t gap = original_fp_ - original_sp_; 1488 intptr_t gap = original_fp_ - original_sp_;
1453 if (gap >= kMaxStep) { 1489 if (gap >= kMaxStep) {
1454 // Gap between frame pointer and stack pointer is 1490 // Gap between frame pointer and stack pointer is
1455 // too large. 1491 // too large.
1456 return 1; 1492 return 1;
1457 } 1493 }
1458 if (original_sp_ < lower_bound_) { 1494 if (original_sp_ < lower_bound_) {
1459 // The stack pointer gives us a better lower bound than 1495 // The stack pointer gives us a better lower bound than
1460 // the isolates stack limit. 1496 // the isolates stack limit.
1461 lower_bound_ = original_sp_; 1497 lower_bound_ = original_sp_;
1462 } 1498 }
1463 int i = 0; 1499 int i = 0;
1464 for (; i < FLAG_profile_depth; i++) { 1500 for (; i < FLAG_profile_depth; i++) {
1465 if (FLAG_profile_verify_stack_walk) { 1501 if (FLAG_profile_verify_stack_walk) {
1466 VerifyCodeAddress(heap, i, reinterpret_cast<uword>(pc)); 1502 VerifyCodeAddress(heap, i, reinterpret_cast<uword>(pc));
1467 } 1503 }
1468 sample_->SetAt(i, reinterpret_cast<uword>(pc)); 1504 sample_->SetAt(i, reinterpret_cast<uword>(pc));
1505 if (fp == NULL) {
1506 return i + 1;
1507 }
1469 if (!ValidFramePointer(fp)) { 1508 if (!ValidFramePointer(fp)) {
1470 return i + 1; 1509 return i + 1;
1471 } 1510 }
1472 pc = CallerPC(fp); 1511 pc = CallerPC(fp);
1473 previous_fp = fp; 1512 previous_fp = fp;
1474 fp = CallerFP(fp); 1513 fp = CallerFP(fp);
1475 intptr_t step = fp - previous_fp; 1514 intptr_t step = fp - previous_fp;
1476 if ((step >= kMaxStep) || (fp <= previous_fp) || !ValidFramePointer(fp)) { 1515 if (fp == NULL) {
1516 return i + 1;
1517 }
1518 if ((step >= kMaxStep)) {
1477 // Frame pointer step is too large. 1519 // Frame pointer step is too large.
1520 return i + 1;
1521 }
1522 if ((fp <= previous_fp)) {
1478 // Frame pointer did not move to a higher address. 1523 // Frame pointer did not move to a higher address.
1524 return i + 1;
1525 }
1526 if (!ValidFramePointer(fp)) {
1479 // Frame pointer is outside of isolate stack bounds. 1527 // Frame pointer is outside of isolate stack bounds.
1480 return i + 1; 1528 return i + 1;
1481 } 1529 }
1482 // Move the lower bound up. 1530 // Move the lower bound up.
1483 lower_bound_ = reinterpret_cast<uword>(fp); 1531 lower_bound_ = reinterpret_cast<uword>(fp);
1484 } 1532 }
1485 return i; 1533 return i;
1486 } 1534 }
1487 1535
1488 private: 1536 private:
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1552 sample->Init(isolate, OS::GetCurrentTimeMicros(), state.tid); 1600 sample->Init(isolate, OS::GetCurrentTimeMicros(), state.tid);
1553 uword stack_lower = 0; 1601 uword stack_lower = 0;
1554 uword stack_upper = 0; 1602 uword stack_upper = 0;
1555 isolate->GetStackBounds(&stack_lower, &stack_upper); 1603 isolate->GetStackBounds(&stack_lower, &stack_upper);
1556 if ((stack_lower == 0) || (stack_upper == 0)) { 1604 if ((stack_lower == 0) || (stack_upper == 0)) {
1557 stack_lower = 0; 1605 stack_lower = 0;
1558 stack_upper = 0; 1606 stack_upper = 0;
1559 } 1607 }
1560 ProfilerSampleStackWalker stackWalker(sample, stack_lower, stack_upper, 1608 ProfilerSampleStackWalker stackWalker(sample, stack_lower, stack_upper,
1561 state.pc, state.fp, state.sp); 1609 state.pc, state.fp, state.sp);
1562 stackWalker.walk(isolate->heap(), isolate->vm_tag()); 1610 stackWalker.walk(isolate->heap(), isolate->vm_tag(), isolate->user_tag());
1563 } 1611 }
1564 1612
1565 } // namespace dart 1613 } // namespace dart
OLDNEW
« runtime/vm/object.cc ('K') | « 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