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

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 = UserTags::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 if (tag == 0) {
977 // None set.
978 return;
979 }
980 intptr_t index = tag_code_table_->FindIndex(tag);
981 if (index >= 0) {
982 // Already created.
983 return;
984 }
985 CodeRegion* region = new CodeRegion(CodeRegion::kTagCode,
986 tag,
987 tag + 1,
988 0);
989 index = tag_code_table_->InsertCodeRegion(region);
990 ASSERT(index >= 0);
991 region->set_creation_serial(visited());
992 }
993
965 void Tick(uword pc, bool exclusive, int64_t timestamp) { 994 void Tick(uword pc, bool exclusive, int64_t timestamp) {
966 CodeRegionTable::TickResult r; 995 CodeRegionTable::TickResult r;
967 intptr_t serial = exclusive ? -1 : visited(); 996 intptr_t serial = exclusive ? -1 : visited();
968 r = live_code_table_->Tick(pc, exclusive, serial, timestamp); 997 r = live_code_table_->Tick(pc, exclusive, serial, timestamp);
969 if (r == CodeRegionTable::kTicked) { 998 if (r == CodeRegionTable::kTicked) {
970 // Live code found and ticked. 999 // Live code found and ticked.
971 return; 1000 return;
972 } 1001 }
973 if (r == CodeRegionTable::kNewerCode) { 1002 if (r == CodeRegionTable::kNewerCode) {
974 // Code has been overwritten by newer code. 1003 // 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); 1123 root_ = new CodeRegionTrieNode(tag_code_table_offset_ + root_index);
1095 // Use tags by default. 1124 // Use tags by default.
1096 set_use_tags(true); 1125 set_use_tags(true);
1097 } 1126 }
1098 1127
1099 void VisitSample(Sample* sample) { 1128 void VisitSample(Sample* sample) {
1100 // Give the root a tick. 1129 // Give the root a tick.
1101 root_->Tick(); 1130 root_->Tick();
1102 CodeRegionTrieNode* current = root_; 1131 CodeRegionTrieNode* current = root_;
1103 if (use_tags()) { 1132 if (use_tags()) {
1104 intptr_t tag_index = FindTagIndex(sample->vm_tag()); 1133 intptr_t user_tag_index = FindTagIndex(sample->user_tag());
1105 current = current->GetChild(tag_index); 1134 if (user_tag_index >= 0) {
1135 current = current->GetChild(user_tag_index);
1136 // Give the tag a tick.
1137 current->Tick();
1138 }
1139 intptr_t vm_tag_index = FindTagIndex(sample->vm_tag());
1140 ASSERT(vm_tag_index >= 0);
1141 current = current->GetChild(vm_tag_index);
1106 // Give the tag a tick. 1142 // Give the tag a tick.
1107 current->Tick(); 1143 current->Tick();
1108 } 1144 }
1109 // Walk the sampled PCs. 1145 // Walk the sampled PCs.
1110 for (intptr_t i = 0; i < FLAG_profile_depth; i++) { 1146 for (intptr_t i = 0; i < FLAG_profile_depth; i++) {
1111 if (sample->At(i) == 0) { 1147 if (sample->At(i) == 0) {
1112 break; 1148 break;
1113 } 1149 }
1114 intptr_t index = FindFinalIndex(sample->At(i), sample->timestamp()); 1150 intptr_t index = FindFinalIndex(sample->At(i), sample->timestamp());
1115 current = current->GetChild(index); 1151 current = current->GetChild(index);
1116 current->Tick(); 1152 current->Tick();
1117 } 1153 }
1118 } 1154 }
1119 1155
1120 CodeRegionTrieNode* root() const { 1156 CodeRegionTrieNode* root() const {
1121 return root_; 1157 return root_;
1122 } 1158 }
1123 1159
1124 bool use_tags() const { 1160 bool use_tags() const {
1125 return use_tags_; 1161 return use_tags_;
1126 } 1162 }
1127 1163
1128 void set_use_tags(bool use_tags) { 1164 void set_use_tags(bool use_tags) {
1129 use_tags_ = use_tags; 1165 use_tags_ = use_tags;
1130 } 1166 }
1131 1167
1132 private: 1168 private:
1133 intptr_t FindTagIndex(uword tag) const { 1169 intptr_t FindTagIndex(uword tag) const {
1170 if (tag == 0) {
1171 return -1;
1172 }
1134 intptr_t index = tag_code_table_->FindIndex(tag); 1173 intptr_t index = tag_code_table_->FindIndex(tag);
1174 if (index <= 0) {
1175 return -1;
1176 }
1135 ASSERT(index >= 0); 1177 ASSERT(index >= 0);
1136 ASSERT((tag_code_table_->At(index))->contains(tag)); 1178 ASSERT((tag_code_table_->At(index))->contains(tag));
1137 return tag_code_table_offset_ + index; 1179 return tag_code_table_offset_ + index;
1138 } 1180 }
1139 1181
1140 intptr_t FindFinalIndex(uword pc, int64_t timestamp) const { 1182 intptr_t FindFinalIndex(uword pc, int64_t timestamp) const {
1141 intptr_t index = live_code_table_->FindIndex(pc); 1183 intptr_t index = live_code_table_->FindIndex(pc);
1142 ASSERT(index >= 0); 1184 ASSERT(index >= 0);
1143 CodeRegion* region = live_code_table_->At(index); 1185 CodeRegion* region = live_code_table_->At(index);
1144 ASSERT(region->contains(pc)); 1186 ASSERT(region->contains(pc));
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
1424 uword sp) 1466 uword sp)
1425 : sample_(sample), 1467 : sample_(sample),
1426 stack_upper_(stack_upper), 1468 stack_upper_(stack_upper),
1427 original_pc_(pc), 1469 original_pc_(pc),
1428 original_fp_(fp), 1470 original_fp_(fp),
1429 original_sp_(sp), 1471 original_sp_(sp),
1430 lower_bound_(stack_lower) { 1472 lower_bound_(stack_lower) {
1431 ASSERT(sample_ != NULL); 1473 ASSERT(sample_ != NULL);
1432 } 1474 }
1433 1475
1434 int walk(Heap* heap, uword vm_tag) { 1476 int walk(Heap* heap) {
1435 const intptr_t kMaxStep = 0x1000; // 4K. 1477 const intptr_t kMaxStep = 0x1000; // 4K.
1436 const bool kWalkStack = true; // Walk the stack. 1478 const bool kWalkStack = true; // Walk the stack.
1437 // Always store the exclusive PC. 1479 // Always store the exclusive PC.
1438 sample_->SetAt(0, original_pc_); 1480 sample_->SetAt(0, original_pc_);
1439 // Always store the vm tag.
1440 sample_->set_vm_tag(vm_tag);
1441 if (!kWalkStack) { 1481 if (!kWalkStack) {
1442 // Not walking the stack, only took exclusive sample. 1482 // Not walking the stack, only took exclusive sample.
1443 return 1; 1483 return 1;
1444 } 1484 }
1445 uword* pc = reinterpret_cast<uword*>(original_pc_); 1485 uword* pc = reinterpret_cast<uword*>(original_pc_);
1446 uword* fp = reinterpret_cast<uword*>(original_fp_); 1486 uword* fp = reinterpret_cast<uword*>(original_fp_);
1447 uword* previous_fp = fp; 1487 uword* previous_fp = fp;
1448 if (original_sp_ > original_fp_) { 1488 if (original_sp_ > original_fp_) {
1449 // Stack pointer should not be above frame pointer. 1489 // Stack pointer should not be above frame pointer.
1450 return 1; 1490 return 1;
1451 } 1491 }
1452 intptr_t gap = original_fp_ - original_sp_; 1492 intptr_t gap = original_fp_ - original_sp_;
1453 if (gap >= kMaxStep) { 1493 if (gap >= kMaxStep) {
1454 // Gap between frame pointer and stack pointer is 1494 // Gap between frame pointer and stack pointer is
1455 // too large. 1495 // too large.
1456 return 1; 1496 return 1;
1457 } 1497 }
1458 if (original_sp_ < lower_bound_) { 1498 if (original_sp_ < lower_bound_) {
1459 // The stack pointer gives us a better lower bound than 1499 // The stack pointer gives us a better lower bound than
1460 // the isolates stack limit. 1500 // the isolates stack limit.
1461 lower_bound_ = original_sp_; 1501 lower_bound_ = original_sp_;
1462 } 1502 }
1463 int i = 0; 1503 int i = 0;
1464 for (; i < FLAG_profile_depth; i++) { 1504 for (; i < FLAG_profile_depth; i++) {
1465 if (FLAG_profile_verify_stack_walk) { 1505 if (FLAG_profile_verify_stack_walk) {
1466 VerifyCodeAddress(heap, i, reinterpret_cast<uword>(pc)); 1506 VerifyCodeAddress(heap, i, reinterpret_cast<uword>(pc));
1467 } 1507 }
1468 sample_->SetAt(i, reinterpret_cast<uword>(pc)); 1508 sample_->SetAt(i, reinterpret_cast<uword>(pc));
1509 if (fp == NULL) {
1510 return i + 1;
1511 }
1469 if (!ValidFramePointer(fp)) { 1512 if (!ValidFramePointer(fp)) {
1470 return i + 1; 1513 return i + 1;
1471 } 1514 }
1472 pc = CallerPC(fp); 1515 pc = CallerPC(fp);
1473 previous_fp = fp; 1516 previous_fp = fp;
1474 fp = CallerFP(fp); 1517 fp = CallerFP(fp);
1475 intptr_t step = fp - previous_fp; 1518 intptr_t step = fp - previous_fp;
1476 if ((step >= kMaxStep) || (fp <= previous_fp) || !ValidFramePointer(fp)) { 1519 if (fp == NULL) {
1520 return i + 1;
1521 }
1522 if ((step >= kMaxStep)) {
1477 // Frame pointer step is too large. 1523 // Frame pointer step is too large.
1524 return i + 1;
1525 }
1526 if ((fp <= previous_fp)) {
1478 // Frame pointer did not move to a higher address. 1527 // Frame pointer did not move to a higher address.
1528 return i + 1;
1529 }
1530 if (!ValidFramePointer(fp)) {
1479 // Frame pointer is outside of isolate stack bounds. 1531 // Frame pointer is outside of isolate stack bounds.
1480 return i + 1; 1532 return i + 1;
1481 } 1533 }
1482 // Move the lower bound up. 1534 // Move the lower bound up.
1483 lower_bound_ = reinterpret_cast<uword>(fp); 1535 lower_bound_ = reinterpret_cast<uword>(fp);
1484 } 1536 }
1485 return i; 1537 return i;
1486 } 1538 }
1487 1539
1488 private: 1540 private:
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1543 IsolateProfilerData* profiler_data = isolate->profiler_data(); 1595 IsolateProfilerData* profiler_data = isolate->profiler_data();
1544 if (profiler_data == NULL) { 1596 if (profiler_data == NULL) {
1545 return; 1597 return;
1546 } 1598 }
1547 SampleBuffer* sample_buffer = profiler_data->sample_buffer(); 1599 SampleBuffer* sample_buffer = profiler_data->sample_buffer();
1548 if (sample_buffer == NULL) { 1600 if (sample_buffer == NULL) {
1549 return; 1601 return;
1550 } 1602 }
1551 Sample* sample = sample_buffer->ReserveSample(); 1603 Sample* sample = sample_buffer->ReserveSample();
1552 sample->Init(isolate, OS::GetCurrentTimeMicros(), state.tid); 1604 sample->Init(isolate, OS::GetCurrentTimeMicros(), state.tid);
1605 sample->set_vm_tag(isolate->vm_tag());
1606 sample->set_user_tag(isolate->user_tag());
1553 uword stack_lower = 0; 1607 uword stack_lower = 0;
1554 uword stack_upper = 0; 1608 uword stack_upper = 0;
1555 isolate->GetStackBounds(&stack_lower, &stack_upper); 1609 isolate->GetStackBounds(&stack_lower, &stack_upper);
1556 if ((stack_lower == 0) || (stack_upper == 0)) { 1610 if ((stack_lower == 0) || (stack_upper == 0)) {
1557 stack_lower = 0; 1611 stack_lower = 0;
1558 stack_upper = 0; 1612 stack_upper = 0;
1559 } 1613 }
1560 ProfilerSampleStackWalker stackWalker(sample, stack_lower, stack_upper, 1614 ProfilerSampleStackWalker stackWalker(sample, stack_lower, stack_upper,
1561 state.pc, state.fp, state.sp); 1615 state.pc, state.fp, state.sp);
1562 stackWalker.walk(isolate->heap(), isolate->vm_tag()); 1616 stackWalker.walk(isolate->heap());
1563 } 1617 }
1564 1618
1565 } // namespace dart 1619 } // 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