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

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

Issue 1268803006: Support profiler code transition tags (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 4 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_service.h ('k') | runtime/vm/profiler_test.cc » ('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) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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 "vm/profiler_service.h" 5 #include "vm/profiler_service.h"
6 6
7 #include "vm/growable_array.h" 7 #include "vm/growable_array.h"
8 #include "vm/native_symbol.h" 8 #include "vm/native_symbol.h"
9 #include "vm/object.h" 9 #include "vm/object.h"
10 #include "vm/os.h" 10 #include "vm/os.h"
(...skipping 563 matching lines...) Expand 10 before | Expand all | Expand 10 after
574 const char* tag_name = UserTags::TagName(start()); 574 const char* tag_name = UserTags::TagName(start());
575 ASSERT(tag_name != NULL); 575 ASSERT(tag_name != NULL);
576 SetName(tag_name); 576 SetName(tag_name);
577 } else if (VMTag::IsVMTag(start()) || 577 } else if (VMTag::IsVMTag(start()) ||
578 VMTag::IsRuntimeEntryTag(start()) || 578 VMTag::IsRuntimeEntryTag(start()) ||
579 VMTag::IsNativeEntryTag(start())) { 579 VMTag::IsNativeEntryTag(start())) {
580 const char* tag_name = VMTag::TagName(start()); 580 const char* tag_name = VMTag::TagName(start());
581 ASSERT(tag_name != NULL); 581 ASSERT(tag_name != NULL);
582 SetName(tag_name); 582 SetName(tag_name);
583 } else { 583 } else {
584 if (start() == VMTag::kRootTagId) { 584 switch (start()) {
585 SetName("Root"); 585 case VMTag::kRootTagId:
586 } else { 586 SetName("Root");
587 ASSERT(start() == VMTag::kTruncatedTagId); 587 break;
588 SetName("[Truncated]"); 588 case VMTag::kTruncatedTagId:
589 SetName("[Truncated]");
590 break;
591 case VMTag::kNoneCodeTagId:
592 SetName("[No Code]");
593 break;
594 case VMTag::kOptimizedCodeTagId:
595 SetName("[Optimized Code]");
596 break;
597 case VMTag::kUnoptimizedCodeTagId:
598 SetName("[Unoptimized Code]");
599 break;
600 case VMTag::kNativeCodeTagId:
601 SetName("[Native Code]");
602 break;
603 case VMTag::kInlineStartCodeTagId:
604 SetName("[Inline Start]");
605 break;
606 case VMTag::kInlineEndCodeTagId:
607 SetName("[Inline End]");
608 break;
609 default:
610 UNIMPLEMENTED();
611 break;
589 } 612 }
590 } 613 }
591 } 614 }
592 function = table->AddTag(start(), name()); 615 function = table->AddTag(start(), name());
593 } else { 616 } else {
594 UNREACHABLE(); 617 UNREACHABLE();
595 } 618 }
596 ASSERT(function != NULL); 619 ASSERT(function != NULL);
597 620
598 function->AddProfileCode(code_table_index()); 621 function->AddProfileCode(code_table_index());
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after
944 code_objects_.Add(code_object); 967 code_objects_.Add(code_object);
945 } 968 }
946 969
947 private: 970 private:
948 ZoneGrowableArray<ProfileFunctionTrieNodeCode> code_objects_; 971 ZoneGrowableArray<ProfileFunctionTrieNodeCode> code_objects_;
949 }; 972 };
950 973
951 974
952 class ProfileBuilder : public ValueObject { 975 class ProfileBuilder : public ValueObject {
953 public: 976 public:
977 enum ProfileInfoKind {
978 kNone,
979 kOptimized,
980 kUnoptimized,
981 kNative,
982 kInlineStart,
983 kInlineFinish,
984 kNumProfileInfoKind,
985 };
986
954 ProfileBuilder(Isolate* isolate, 987 ProfileBuilder(Isolate* isolate,
955 SampleFilter* filter, 988 SampleFilter* filter,
956 Profile::TagOrder tag_order, 989 Profile::TagOrder tag_order,
990 intptr_t extra_tags,
957 Profile* profile) 991 Profile* profile)
958 : isolate_(isolate), 992 : isolate_(isolate),
959 vm_isolate_(Dart::vm_isolate()), 993 vm_isolate_(Dart::vm_isolate()),
960 filter_(filter), 994 filter_(filter),
961 tag_order_(tag_order), 995 tag_order_(tag_order),
996 extra_tags_(extra_tags),
962 profile_(profile), 997 profile_(profile),
963 deoptimized_code_(new DeoptimizedCodeSet(isolate)), 998 deoptimized_code_(new DeoptimizedCodeSet(isolate)),
964 null_code_(Code::ZoneHandle()), 999 null_code_(Code::ZoneHandle()),
965 null_function_(Function::ZoneHandle()), 1000 null_function_(Function::ZoneHandle()),
966 tick_functions_(false), 1001 tick_functions_(false),
967 inclusive_tree_(false), 1002 inclusive_tree_(false),
968 samples_(NULL) { 1003 samples_(NULL),
1004 info_kind_(kNone) {
969 ASSERT(profile_ != NULL); 1005 ASSERT(profile_ != NULL);
970 } 1006 }
971 1007
972 void Build() { 1008 void Build() {
973 ScopeTimer sw("ProfileBuilder::Build", FLAG_trace_profiler); 1009 ScopeTimer sw("ProfileBuilder::Build", FLAG_trace_profiler);
974 FilterSamples(); 1010 FilterSamples();
975 1011
976 Setup(); 1012 Setup();
977 BuildCodeTable(); 1013 BuildCodeTable();
978 FinalizeCodeIndexes(); 1014 FinalizeCodeIndexes();
(...skipping 19 matching lines...) Expand all
998 } 1034 }
999 1035
1000 void Setup() { 1036 void Setup() {
1001 profile_->live_code_ = new ProfileCodeTable(); 1037 profile_->live_code_ = new ProfileCodeTable();
1002 profile_->dead_code_ = new ProfileCodeTable(); 1038 profile_->dead_code_ = new ProfileCodeTable();
1003 profile_->tag_code_ = new ProfileCodeTable(); 1039 profile_->tag_code_ = new ProfileCodeTable();
1004 profile_->functions_ = new ProfileFunctionTable(); 1040 profile_->functions_ = new ProfileFunctionTable();
1005 // Register some synthetic tags. 1041 // Register some synthetic tags.
1006 RegisterProfileCodeTag(VMTag::kRootTagId); 1042 RegisterProfileCodeTag(VMTag::kRootTagId);
1007 RegisterProfileCodeTag(VMTag::kTruncatedTagId); 1043 RegisterProfileCodeTag(VMTag::kTruncatedTagId);
1044 RegisterProfileCodeTag(VMTag::kNoneCodeTagId);
1045 RegisterProfileCodeTag(VMTag::kOptimizedCodeTagId);
1046 RegisterProfileCodeTag(VMTag::kUnoptimizedCodeTagId);
1047 RegisterProfileCodeTag(VMTag::kNativeCodeTagId);
1048 RegisterProfileCodeTag(VMTag::kInlineStartCodeTagId);
1049 RegisterProfileCodeTag(VMTag::kInlineEndCodeTagId);
1008 } 1050 }
1009 1051
1010 void FilterSamples() { 1052 void FilterSamples() {
1011 ScopeTimer sw("ProfileBuilder::FilterSamples", FLAG_trace_profiler); 1053 ScopeTimer sw("ProfileBuilder::FilterSamples", FLAG_trace_profiler);
1012 MutexLocker profiler_data_lock(isolate_->profiler_data_mutex()); 1054 MutexLocker profiler_data_lock(isolate_->profiler_data_mutex());
1013 IsolateProfilerData* profiler_data = isolate_->profiler_data(); 1055 IsolateProfilerData* profiler_data = isolate_->profiler_data();
1014 if (profiler_data == NULL) { 1056 if (profiler_data == NULL) {
1015 return; 1057 return;
1016 } 1058 }
1017 SampleBuffer* sample_buffer = profiler_data->sample_buffer(); 1059 SampleBuffer* sample_buffer = profiler_data->sample_buffer();
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
1145 sample_index++) { 1187 sample_index++) {
1146 ProcessedSample* sample = samples_->At(sample_index); 1188 ProcessedSample* sample = samples_->At(sample_index);
1147 1189
1148 // Tick the root. 1190 // Tick the root.
1149 ProfileCodeTrieNode* current = root; 1191 ProfileCodeTrieNode* current = root;
1150 current->Tick(); 1192 current->Tick();
1151 1193
1152 // VM & User tags. 1194 // VM & User tags.
1153 current = AppendTags(sample->vm_tag(), sample->user_tag(), current); 1195 current = AppendTags(sample->vm_tag(), sample->user_tag(), current);
1154 1196
1197 ResetKind();
1198
1155 // Truncated tag. 1199 // Truncated tag.
1156 if (sample->truncated()) { 1200 if (sample->truncated()) {
1157 current = AppendTruncatedTag(current); 1201 current = AppendTruncatedTag(current);
1158 } 1202 }
1159 1203
1160 // Walk the sampled PCs. 1204 // Walk the sampled PCs.
1205 Code& code = Code::Handle();
1161 for (intptr_t frame_index = sample->length() - 1; 1206 for (intptr_t frame_index = sample->length() - 1;
1162 frame_index >= 0; 1207 frame_index >= 0;
1163 frame_index--) { 1208 frame_index--) {
1164 ASSERT(sample->At(frame_index) != 0); 1209 ASSERT(sample->At(frame_index) != 0);
1165 intptr_t index = 1210 intptr_t index =
1166 GetProfileCodeIndex(sample->At(frame_index), sample->timestamp()); 1211 GetProfileCodeIndex(sample->At(frame_index), sample->timestamp());
1167 ASSERT(index >= 0); 1212 ASSERT(index >= 0);
1213 ProfileCode* profile_code =
1214 GetProfileCode(sample->At(frame_index), sample->timestamp());
1215 ASSERT(profile_code->code_table_index() == index);
1216 code ^= profile_code->code();
1217 current = AppendKind(code, current);
1168 current = current->GetChild(index); 1218 current = current->GetChild(index);
1169 current->Tick(); 1219 current->Tick();
1170 } 1220 }
1171 } 1221 }
1172 } 1222 }
1173 1223
1174 void BuildExclusiveCodeTrie(ProfileCodeTrieNode* root) { 1224 void BuildExclusiveCodeTrie(ProfileCodeTrieNode* root) {
1175 ScopeTimer sw("ProfileBuilder::BuildExclusiveCodeTrie", 1225 ScopeTimer sw("ProfileBuilder::BuildExclusiveCodeTrie",
1176 FLAG_trace_profiler); 1226 FLAG_trace_profiler);
1177 for (intptr_t sample_index = 0; 1227 for (intptr_t sample_index = 0;
1178 sample_index < samples_->length(); 1228 sample_index < samples_->length();
1179 sample_index++) { 1229 sample_index++) {
1180 ProcessedSample* sample = samples_->At(sample_index); 1230 ProcessedSample* sample = samples_->At(sample_index);
1181 1231
1182 // Tick the root. 1232 // Tick the root.
1183 ProfileCodeTrieNode* current = root; 1233 ProfileCodeTrieNode* current = root;
1184 current->Tick(); 1234 current->Tick();
1185 1235
1186 // VM & User tags. 1236 // VM & User tags.
1187 current = AppendTags(sample->vm_tag(), sample->user_tag(), current); 1237 current = AppendTags(sample->vm_tag(), sample->user_tag(), current);
1188 1238
1239 ResetKind();
1240
1189 // Walk the sampled PCs. 1241 // Walk the sampled PCs.
1242 Code& code = Code::Handle();
1190 for (intptr_t frame_index = 0; 1243 for (intptr_t frame_index = 0;
1191 frame_index < sample->length(); 1244 frame_index < sample->length();
1192 frame_index++) { 1245 frame_index++) {
1193 ASSERT(sample->At(frame_index) != 0); 1246 ASSERT(sample->At(frame_index) != 0);
1194 intptr_t index = 1247 intptr_t index =
1195 GetProfileCodeIndex(sample->At(frame_index), sample->timestamp()); 1248 GetProfileCodeIndex(sample->At(frame_index), sample->timestamp());
1196 ASSERT(index >= 0); 1249 ASSERT(index >= 0);
1250 ProfileCode* profile_code =
1251 GetProfileCode(sample->At(frame_index), sample->timestamp());
1252 ASSERT(profile_code->code_table_index() == index);
1253 code ^= profile_code->code();
1197 current = current->GetChild(index); 1254 current = current->GetChild(index);
1198 if (ShouldTickNode(sample, frame_index)) { 1255 if (ShouldTickNode(sample, frame_index)) {
1199 current->Tick(); 1256 current->Tick();
1200 } 1257 }
1258 current = AppendKind(code, current);
1201 } 1259 }
1202 // Truncated tag. 1260 // Truncated tag.
1203 if (sample->truncated()) { 1261 if (sample->truncated()) {
1204 current = AppendTruncatedTag(current); 1262 current = AppendTruncatedTag(current);
1205 } 1263 }
1206 } 1264 }
1207 } 1265 }
1208 1266
1209 void BuildFunctionTrie(Profile::TrieKind kind) { 1267 void BuildFunctionTrie(Profile::TrieKind kind) {
1210 ProfileFunctionTrieNode* root = 1268 ProfileFunctionTrieNode* root =
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1263 sample_index++) { 1321 sample_index++) {
1264 ProcessedSample* sample = samples_->At(sample_index); 1322 ProcessedSample* sample = samples_->At(sample_index);
1265 1323
1266 // Tick the root. 1324 // Tick the root.
1267 ProfileFunctionTrieNode* current = root; 1325 ProfileFunctionTrieNode* current = root;
1268 current->Tick(); 1326 current->Tick();
1269 1327
1270 // VM & User tags. 1328 // VM & User tags.
1271 current = AppendTags(sample->vm_tag(), sample->user_tag(), current); 1329 current = AppendTags(sample->vm_tag(), sample->user_tag(), current);
1272 1330
1331 ResetKind();
1332
1273 // Walk the sampled PCs. 1333 // Walk the sampled PCs.
1274 for (intptr_t frame_index = 0; 1334 for (intptr_t frame_index = 0;
1275 frame_index < sample->length(); 1335 frame_index < sample->length();
1276 frame_index++) { 1336 frame_index++) {
1277 ASSERT(sample->At(frame_index) != 0); 1337 ASSERT(sample->At(frame_index) != 0);
1278 current = ProcessFrame(current, sample_index, sample, frame_index); 1338 current = ProcessFrame(current, sample_index, sample, frame_index);
1279 } 1339 }
1280 1340
1281 // Truncated tag. 1341 // Truncated tag.
1282 if (sample->truncated()) { 1342 if (sample->truncated()) {
(...skipping 16 matching lines...) Expand all
1299 const intptr_t code_index = profile_code->code_table_index(); 1359 const intptr_t code_index = profile_code->code_table_index();
1300 ASSERT(profile_code != NULL); 1360 ASSERT(profile_code != NULL);
1301 const Code& code = Code::ZoneHandle(profile_code->code()); 1361 const Code& code = Code::ZoneHandle(profile_code->code());
1302 GrowableArray<Function*> inlined_functions; 1362 GrowableArray<Function*> inlined_functions;
1303 if (!code.IsNull()) { 1363 if (!code.IsNull()) {
1304 intptr_t offset = pc - code.EntryPoint(); 1364 intptr_t offset = pc - code.EntryPoint();
1305 code.GetInlinedFunctionsAt(offset, &inlined_functions); 1365 code.GetInlinedFunctionsAt(offset, &inlined_functions);
1306 } 1366 }
1307 if (code.IsNull() || (inlined_functions.length() == 0)) { 1367 if (code.IsNull() || (inlined_functions.length() == 0)) {
1308 // No inlined functions. 1368 // No inlined functions.
1369 if (inclusive_tree_) {
1370 current = AppendKind(code, current);
1371 }
1309 current = ProcessFunction(current, 1372 current = ProcessFunction(current,
1310 sample_index, 1373 sample_index,
1311 sample, 1374 sample,
1312 frame_index, 1375 frame_index,
1313 function, 1376 function,
1314 code_index); 1377 code_index);
1378 if (!inclusive_tree_) {
1379 current = AppendKind(code, current);
1380 }
1315 return current; 1381 return current;
1316 } 1382 }
1317 1383
1384 ASSERT(code.is_optimized());
1385
1318 if (inclusive_tree_) { 1386 if (inclusive_tree_) {
1319 // Append the inlined children.
1320 for (intptr_t i = inlined_functions.length() - 1; i >= 0; i--) { 1387 for (intptr_t i = inlined_functions.length() - 1; i >= 0; i--) {
1321 Function* inlined_function = inlined_functions[i]; 1388 Function* inlined_function = inlined_functions[i];
1322 ASSERT(inlined_function != NULL); 1389 ASSERT(inlined_function != NULL);
1323 ASSERT(!inlined_function->IsNull()); 1390 ASSERT(!inlined_function->IsNull());
1391 const bool inliner = i == (inlined_functions.length() - 1);
1392 if (inliner) {
1393 current = AppendKind(code, current);
1394 }
1324 current = ProcessInlinedFunction(current, 1395 current = ProcessInlinedFunction(current,
1325 sample_index, 1396 sample_index,
1326 sample, 1397 sample,
1327 frame_index, 1398 frame_index,
1328 inlined_function, 1399 inlined_function,
1329 code_index); 1400 code_index);
1401 if (inliner) {
1402 current = AppendKind(kInlineStart, current);
1403 }
1330 } 1404 }
1405 current = AppendKind(kInlineFinish, current);
1331 } else { 1406 } else {
1332 // Append the inlined children. 1407 // Append the inlined children.
1408 current = AppendKind(kInlineFinish, current);
1333 for (intptr_t i = 0; i < inlined_functions.length(); i++) { 1409 for (intptr_t i = 0; i < inlined_functions.length(); i++) {
1334 Function* inlined_function = inlined_functions[i]; 1410 Function* inlined_function = inlined_functions[i];
1335 ASSERT(inlined_function != NULL); 1411 ASSERT(inlined_function != NULL);
1336 ASSERT(!inlined_function->IsNull()); 1412 ASSERT(!inlined_function->IsNull());
1413 const bool inliner = i == (inlined_functions.length() - 1);
1414 if (inliner) {
1415 current = AppendKind(kInlineStart, current);
1416 }
1337 current = ProcessInlinedFunction(current, 1417 current = ProcessInlinedFunction(current,
1338 sample_index, 1418 sample_index,
1339 sample, 1419 sample,
1340 frame_index + i, 1420 frame_index + i,
1341 inlined_function, 1421 inlined_function,
1342 code_index); 1422 code_index);
1423 if (inliner) {
1424 current = AppendKind(code, current);
1425 }
1343 } 1426 }
1344 } 1427 }
1345 1428
1346 return current; 1429 return current;
1347 } 1430 }
1348 1431
1349 ProfileFunctionTrieNode* ProcessInlinedFunction( 1432 ProfileFunctionTrieNode* ProcessInlinedFunction(
1350 ProfileFunctionTrieNode* current, 1433 ProfileFunctionTrieNode* current,
1351 intptr_t sample_index, 1434 intptr_t sample_index,
1352 ProcessedSample* sample, 1435 ProcessedSample* sample,
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1457 !VMTag::IsRuntimeEntryTag(vm_tag)) { 1540 !VMTag::IsRuntimeEntryTag(vm_tag)) {
1458 return current; 1541 return current;
1459 } 1542 }
1460 intptr_t tag_index = GetProfileCodeTagIndex(vm_tag); 1543 intptr_t tag_index = GetProfileCodeTagIndex(vm_tag);
1461 current = current->GetChild(tag_index); 1544 current = current->GetChild(tag_index);
1462 // Give the tag a tick. 1545 // Give the tag a tick.
1463 current->Tick(); 1546 current->Tick();
1464 return current; 1547 return current;
1465 } 1548 }
1466 1549
1550 uword ProfileInfoKindToVMTag(ProfileInfoKind kind) {
1551 switch (kind) {
1552 case kNone:
1553 return VMTag::kNoneCodeTagId;
1554 case kOptimized:
1555 return VMTag::kOptimizedCodeTagId;
1556 case kUnoptimized:
1557 return VMTag::kUnoptimizedCodeTagId;
1558 case kNative:
1559 return VMTag::kNativeCodeTagId;
1560 case kInlineStart:
1561 return VMTag::kInlineStartCodeTagId;
1562 case kInlineFinish:
1563 return VMTag::kInlineEndCodeTagId;
1564 default:
1565 UNIMPLEMENTED();
1566 return VMTag::kInvalidTagId;
1567 }
1568 }
1569
1570 ProfileCodeTrieNode* AppendKind(ProfileInfoKind kind,
1571 ProfileCodeTrieNode* current) {
1572 if (!TagsEnabled(ProfilerService::kCodeTransitionTagsBit)) {
1573 // Only emit if debug tags are requested.
1574 return current;
1575 }
1576 if (kind != info_kind_) {
1577 info_kind_ = kind;
1578 intptr_t tag_index = GetProfileCodeTagIndex(ProfileInfoKindToVMTag(kind));
1579 ASSERT(tag_index >= 0);
1580 current = current->GetChild(tag_index);
1581 current->Tick();
1582 }
1583 return current;
1584 }
1585
1586 ProfileCodeTrieNode* AppendKind(const Code& code,
1587 ProfileCodeTrieNode* current) {
1588 if (code.IsNull()) {
1589 return AppendKind(kNone, current);
1590 } else if (code.is_optimized()) {
1591 return AppendKind(kOptimized, current);
1592 } else {
1593 return AppendKind(kUnoptimized, current);
1594 }
1595 }
1596
1467 ProfileCodeTrieNode* AppendVMTags(uword vm_tag, 1597 ProfileCodeTrieNode* AppendVMTags(uword vm_tag,
1468 ProfileCodeTrieNode* current) { 1598 ProfileCodeTrieNode* current) {
1469 current = AppendVMTag(vm_tag, current); 1599 current = AppendVMTag(vm_tag, current);
1470 current = AppendSpecificNativeRuntimeEntryVMTag(vm_tag, current); 1600 current = AppendSpecificNativeRuntimeEntryVMTag(vm_tag, current);
1471 return current; 1601 return current;
1472 } 1602 }
1473 1603
1474 ProfileCodeTrieNode* AppendTags(uword vm_tag, 1604 ProfileCodeTrieNode* AppendTags(uword vm_tag,
1475 uword user_tag, 1605 uword user_tag,
1476 ProfileCodeTrieNode* current) { 1606 ProfileCodeTrieNode* current) {
(...skipping 16 matching lines...) Expand all
1493 (tag_order() == Profile::kVM)); 1623 (tag_order() == Profile::kVM));
1494 current = AppendVMTags(vm_tag, current); 1624 current = AppendVMTags(vm_tag, current);
1495 // Only VM. 1625 // Only VM.
1496 if (tag_order() == Profile::kVM) { 1626 if (tag_order() == Profile::kVM) {
1497 return current; 1627 return current;
1498 } 1628 }
1499 return AppendUserTag(user_tag, current); 1629 return AppendUserTag(user_tag, current);
1500 } 1630 }
1501 1631
1502 // ProfileFunctionTrieNode 1632 // ProfileFunctionTrieNode
1633 void ResetKind() {
1634 info_kind_ = kNone;
1635 }
1636
1637 ProfileFunctionTrieNode* AppendKind(ProfileInfoKind kind,
1638 ProfileFunctionTrieNode* current) {
1639 if (!TagsEnabled(ProfilerService::kCodeTransitionTagsBit)) {
1640 // Only emit if debug tags are requested.
1641 return current;
1642 }
1643 if (kind != info_kind_) {
1644 info_kind_ = kind;
1645 intptr_t tag_index =
1646 GetProfileFunctionTagIndex(ProfileInfoKindToVMTag(kind));
1647 ASSERT(tag_index >= 0);
1648 current = current->GetChild(tag_index);
1649 current->Tick();
1650 }
1651 return current;
1652 }
1653
1654 ProfileFunctionTrieNode* AppendKind(const Code& code,
1655 ProfileFunctionTrieNode* current) {
1656 if (code.IsNull()) {
1657 return AppendKind(kNone, current);
1658 } else if (code.is_optimized()) {
1659 return AppendKind(kOptimized, current);
1660 } else {
1661 return AppendKind(kUnoptimized, current);
1662 }
1663 }
1664
1503 ProfileFunctionTrieNode* AppendUserTag(uword user_tag, 1665 ProfileFunctionTrieNode* AppendUserTag(uword user_tag,
1504 ProfileFunctionTrieNode* current) { 1666 ProfileFunctionTrieNode* current) {
1505 intptr_t user_tag_index = GetProfileFunctionTagIndex(user_tag); 1667 intptr_t user_tag_index = GetProfileFunctionTagIndex(user_tag);
1506 if (user_tag_index >= 0) { 1668 if (user_tag_index >= 0) {
1507 current = current->GetChild(user_tag_index); 1669 current = current->GetChild(user_tag_index);
1508 current->Tick(); 1670 current->Tick();
1509 } 1671 }
1510 return current; 1672 return current;
1511 } 1673 }
1512 1674
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
1776 Profile::TagOrder tag_order() const { 1938 Profile::TagOrder tag_order() const {
1777 return tag_order_; 1939 return tag_order_;
1778 } 1940 }
1779 1941
1780 bool vm_tags_emitted() const { 1942 bool vm_tags_emitted() const {
1781 return (tag_order_ == Profile::kUserVM) || 1943 return (tag_order_ == Profile::kUserVM) ||
1782 (tag_order_ == Profile::kVMUser) || 1944 (tag_order_ == Profile::kVMUser) ||
1783 (tag_order_ == Profile::kVM); 1945 (tag_order_ == Profile::kVM);
1784 } 1946 }
1785 1947
1948 bool TagsEnabled(intptr_t extra_tags_bits) const {
1949 return (extra_tags_ & extra_tags_bits) != 0;
1950 }
1951
1786 Isolate* isolate_; 1952 Isolate* isolate_;
1787 Isolate* vm_isolate_; 1953 Isolate* vm_isolate_;
1788 SampleFilter* filter_; 1954 SampleFilter* filter_;
1789 Profile::TagOrder tag_order_; 1955 Profile::TagOrder tag_order_;
1956 intptr_t extra_tags_;
1790 Profile* profile_; 1957 Profile* profile_;
1791 DeoptimizedCodeSet* deoptimized_code_; 1958 DeoptimizedCodeSet* deoptimized_code_;
1792 const Code& null_code_; 1959 const Code& null_code_;
1793 const Function& null_function_; 1960 const Function& null_function_;
1794 bool tick_functions_; 1961 bool tick_functions_;
1795 bool inclusive_tree_; 1962 bool inclusive_tree_;
1796 1963
1797 ProcessedSampleBuffer* samples_; 1964 ProcessedSampleBuffer* samples_;
1965 ProfileInfoKind info_kind_;
1798 }; 1966 };
1799 1967
1800 1968
1801 Profile::Profile(Isolate* isolate) 1969 Profile::Profile(Isolate* isolate)
1802 : isolate_(isolate), 1970 : isolate_(isolate),
1803 live_code_(NULL), 1971 live_code_(NULL),
1804 dead_code_(NULL), 1972 dead_code_(NULL),
1805 tag_code_(NULL), 1973 tag_code_(NULL),
1806 functions_(NULL), 1974 functions_(NULL),
1807 dead_code_index_offset_(-1), 1975 dead_code_index_offset_(-1),
1808 tag_code_index_offset_(-1), 1976 tag_code_index_offset_(-1),
1809 min_time_(kMaxInt64), 1977 min_time_(kMaxInt64),
1810 max_time_(0) { 1978 max_time_(0) {
1811 ASSERT(isolate_ != NULL); 1979 ASSERT(isolate_ != NULL);
1812 for (intptr_t i = 0; i < kNumTrieKinds; i++) { 1980 for (intptr_t i = 0; i < kNumTrieKinds; i++) {
1813 roots_[i] = NULL; 1981 roots_[i] = NULL;
1814 } 1982 }
1815 } 1983 }
1816 1984
1817 1985
1818 void Profile::Build(SampleFilter* filter, TagOrder tag_order) { 1986 void Profile::Build(SampleFilter* filter,
1819 ProfileBuilder builder(isolate_, filter, tag_order, this); 1987 TagOrder tag_order,
1988 intptr_t extra_tags) {
1989 ProfileBuilder builder(isolate_, filter, tag_order, extra_tags, this);
1820 builder.Build(); 1990 builder.Build();
1821 } 1991 }
1822 1992
1823 1993
1824 ProfileFunction* Profile::GetFunction(intptr_t index) { 1994 ProfileFunction* Profile::GetFunction(intptr_t index) {
1825 ASSERT(functions_ != NULL); 1995 ASSERT(functions_ != NULL);
1826 return functions_->At(index); 1996 return functions_->At(index);
1827 } 1997 }
1828 1998
1829 1999
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
2012 2182
2013 intptr_t ProfileTrieWalker::SiblingCount() { 2183 intptr_t ProfileTrieWalker::SiblingCount() {
2014 ASSERT(parent_ != NULL); 2184 ASSERT(parent_ != NULL);
2015 return parent_->NumChildren(); 2185 return parent_->NumChildren();
2016 } 2186 }
2017 2187
2018 2188
2019 void ProfilerService::PrintJSONImpl(Isolate* isolate, 2189 void ProfilerService::PrintJSONImpl(Isolate* isolate,
2020 JSONStream* stream, 2190 JSONStream* stream,
2021 Profile::TagOrder tag_order, 2191 Profile::TagOrder tag_order,
2192 intptr_t extra_tags,
2022 SampleFilter* filter) { 2193 SampleFilter* filter) {
2023 // Disable profile interrupts while processing the buffer. 2194 // Disable profile interrupts while processing the buffer.
2024 Profiler::EndExecution(isolate); 2195 Profiler::EndExecution(isolate);
2025 2196
2026 { 2197 {
2027 MutexLocker profiler_data_lock(isolate->profiler_data_mutex()); 2198 MutexLocker profiler_data_lock(isolate->profiler_data_mutex());
2028 IsolateProfilerData* profiler_data = isolate->profiler_data(); 2199 IsolateProfilerData* profiler_data = isolate->profiler_data();
2029 if (profiler_data == NULL) { 2200 if (profiler_data == NULL) {
2030 stream->PrintError(kFeatureDisabled, NULL); 2201 stream->PrintError(kFeatureDisabled, NULL);
2031 return; 2202 return;
2032 } 2203 }
2033 } 2204 }
2034 2205
2035 { 2206 {
2036 StackZone zone(isolate); 2207 StackZone zone(isolate);
2037 HANDLESCOPE(isolate); 2208 HANDLESCOPE(isolate);
2038 Profile profile(isolate); 2209 Profile profile(isolate);
2039 profile.Build(filter, tag_order); 2210 profile.Build(filter, tag_order, extra_tags);
2040 profile.PrintJSON(stream); 2211 profile.PrintJSON(stream);
2041 } 2212 }
2042 2213
2043 // Enable profile interrupts. 2214 // Enable profile interrupts.
2044 Profiler::BeginExecution(isolate); 2215 Profiler::BeginExecution(isolate);
2045 } 2216 }
2046 2217
2047 2218
2048 class NoAllocationSampleFilter : public SampleFilter { 2219 class NoAllocationSampleFilter : public SampleFilter {
2049 public: 2220 public:
2050 explicit NoAllocationSampleFilter(Isolate* isolate) 2221 explicit NoAllocationSampleFilter(Isolate* isolate)
2051 : SampleFilter(isolate) { 2222 : SampleFilter(isolate) {
2052 } 2223 }
2053 2224
2054 bool FilterSample(Sample* sample) { 2225 bool FilterSample(Sample* sample) {
2055 return !sample->is_allocation_sample(); 2226 return !sample->is_allocation_sample();
2056 } 2227 }
2057 }; 2228 };
2058 2229
2059 2230
2060 void ProfilerService::PrintJSON(JSONStream* stream, 2231 void ProfilerService::PrintJSON(JSONStream* stream,
2061 Profile::TagOrder tag_order) { 2232 Profile::TagOrder tag_order,
2233 intptr_t extra_tags) {
2062 Isolate* isolate = Isolate::Current(); 2234 Isolate* isolate = Isolate::Current();
2063 NoAllocationSampleFilter filter(isolate); 2235 NoAllocationSampleFilter filter(isolate);
2064 PrintJSONImpl(isolate, stream, tag_order, &filter); 2236 PrintJSONImpl(isolate, stream, tag_order, extra_tags, &filter);
2065 } 2237 }
2066 2238
2067 2239
2068 class ClassAllocationSampleFilter : public SampleFilter { 2240 class ClassAllocationSampleFilter : public SampleFilter {
2069 public: 2241 public:
2070 ClassAllocationSampleFilter(Isolate* isolate, const Class& cls) 2242 ClassAllocationSampleFilter(Isolate* isolate, const Class& cls)
2071 : SampleFilter(isolate), 2243 : SampleFilter(isolate),
2072 cls_(Class::Handle(cls.raw())) { 2244 cls_(Class::Handle(cls.raw())) {
2073 ASSERT(!cls_.IsNull()); 2245 ASSERT(!cls_.IsNull());
2074 } 2246 }
2075 2247
2076 bool FilterSample(Sample* sample) { 2248 bool FilterSample(Sample* sample) {
2077 return sample->is_allocation_sample() && 2249 return sample->is_allocation_sample() &&
2078 (sample->allocation_cid() == cls_.id()); 2250 (sample->allocation_cid() == cls_.id());
2079 } 2251 }
2080 2252
2081 private: 2253 private:
2082 const Class& cls_; 2254 const Class& cls_;
2083 }; 2255 };
2084 2256
2085 2257
2086 void ProfilerService::PrintAllocationJSON(JSONStream* stream, 2258 void ProfilerService::PrintAllocationJSON(JSONStream* stream,
2087 Profile::TagOrder tag_order, 2259 Profile::TagOrder tag_order,
2088 const Class& cls) { 2260 const Class& cls) {
2089 Isolate* isolate = Isolate::Current(); 2261 Isolate* isolate = Isolate::Current();
2090 ClassAllocationSampleFilter filter(isolate, cls); 2262 ClassAllocationSampleFilter filter(isolate, cls);
2091 PrintJSONImpl(isolate, stream, tag_order, &filter); 2263 PrintJSONImpl(isolate, stream, tag_order, kNoExtraTags, &filter);
2092 } 2264 }
2093 2265
2094 2266
2095 void ProfilerService::ClearSamples() { 2267 void ProfilerService::ClearSamples() {
2096 Isolate* isolate = Isolate::Current(); 2268 Isolate* isolate = Isolate::Current();
2097 2269
2098 // Disable profile interrupts while processing the buffer. 2270 // Disable profile interrupts while processing the buffer.
2099 Profiler::EndExecution(isolate); 2271 Profiler::EndExecution(isolate);
2100 2272
2101 MutexLocker profiler_data_lock(isolate->profiler_data_mutex()); 2273 MutexLocker profiler_data_lock(isolate->profiler_data_mutex());
2102 IsolateProfilerData* profiler_data = isolate->profiler_data(); 2274 IsolateProfilerData* profiler_data = isolate->profiler_data();
2103 if (profiler_data == NULL) { 2275 if (profiler_data == NULL) {
2104 return; 2276 return;
2105 } 2277 }
2106 SampleBuffer* sample_buffer = profiler_data->sample_buffer(); 2278 SampleBuffer* sample_buffer = profiler_data->sample_buffer();
2107 ASSERT(sample_buffer != NULL); 2279 ASSERT(sample_buffer != NULL);
2108 2280
2109 ClearProfileVisitor clear_profile(isolate); 2281 ClearProfileVisitor clear_profile(isolate);
2110 sample_buffer->VisitSamples(&clear_profile); 2282 sample_buffer->VisitSamples(&clear_profile);
2111 2283
2112 // Enable profile interrupts. 2284 // Enable profile interrupts.
2113 Profiler::BeginExecution(isolate); 2285 Profiler::BeginExecution(isolate);
2114 } 2286 }
2115 2287
2116 } // namespace dart 2288 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/profiler_service.h ('k') | runtime/vm/profiler_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698