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

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

Issue 2748403002: Added page to Observatory to display native memory allocation information. (Closed)
Patch Set: Added page to Observatory to display native memory allocation information. Created 3 years, 9 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
« runtime/vm/profiler_service.h ('K') | « runtime/vm/profiler_service.h ('k') | no next file » | 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/hash_map.h" 8 #include "vm/hash_map.h"
9 #include "vm/log.h" 9 #include "vm/log.h"
10 #include "vm/malloc_hooks.h"
10 #include "vm/native_symbol.h" 11 #include "vm/native_symbol.h"
11 #include "vm/object.h" 12 #include "vm/object.h"
12 #include "vm/os.h" 13 #include "vm/os.h"
13 #include "vm/profiler.h" 14 #include "vm/profiler.h"
14 #include "vm/reusable_handles.h" 15 #include "vm/reusable_handles.h"
15 #include "vm/scope_timer.h" 16 #include "vm/scope_timer.h"
16 17
17 namespace dart { 18 namespace dart {
18 19
19 DECLARE_FLAG(int, max_profile_depth); 20 DECLARE_FLAG(int, max_profile_depth);
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 func->AddProperty("name", name()); 224 func->AddProperty("name", name());
224 func->AddProperty("_kind", KindToCString(kind())); 225 func->AddProperty("_kind", KindToCString(kind()));
225 } 226 }
226 227
227 228
228 void ProfileFunction::PrintToJSONArray(JSONArray* functions) { 229 void ProfileFunction::PrintToJSONArray(JSONArray* functions) {
229 JSONObject obj(functions); 230 JSONObject obj(functions);
230 obj.AddProperty("kind", KindToCString(kind())); 231 obj.AddProperty("kind", KindToCString(kind()));
231 obj.AddPropertyF("inclusiveTicks", "%" Pd "", inclusive_ticks()); 232 obj.AddPropertyF("inclusiveTicks", "%" Pd "", inclusive_ticks());
232 obj.AddPropertyF("exclusiveTicks", "%" Pd "", exclusive_ticks()); 233 obj.AddPropertyF("exclusiveTicks", "%" Pd "", exclusive_ticks());
234
233 if (kind() == kDartFunction) { 235 if (kind() == kDartFunction) {
234 ASSERT(!function_.IsNull()); 236 ASSERT(!function_.IsNull());
235 obj.AddProperty("function", function_); 237 obj.AddProperty("function", function_);
236 } else { 238 } else {
237 JSONObject func(&obj, "function"); 239 JSONObject func(&obj, "function");
238 PrintToJSONObject(&func); 240 PrintToJSONObject(&func);
239 } 241 }
240 { 242 {
241 JSONArray codes(&obj, "codes"); 243 JSONArray codes(&obj, "codes");
242 for (intptr_t i = 0; i < profile_codes_.length(); i++) { 244 for (intptr_t i = 0; i < profile_codes_.length(); i++) {
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 // If exclusive is set, tick it. 350 // If exclusive is set, tick it.
349 if (exclusive) { 351 if (exclusive) {
350 exclusive_ticks_++; 352 exclusive_ticks_++;
351 TickAddress(pc, true); 353 TickAddress(pc, true);
352 } 354 }
353 // Fall through and tick inclusive count too. 355 // Fall through and tick inclusive count too.
354 if (inclusive_serial_ == serial) { 356 if (inclusive_serial_ == serial) {
355 // Already gave inclusive tick for this sample. 357 // Already gave inclusive tick for this sample.
356 return; 358 return;
357 } 359 }
360
358 inclusive_serial_ = serial; 361 inclusive_serial_ = serial;
359 inclusive_ticks_++; 362 inclusive_ticks_++;
360 TickAddress(pc, false); 363 TickAddress(pc, false);
361 } 364 }
362 365
363 366
364 void ProfileCode::TickAddress(uword pc, bool exclusive) { 367 void ProfileCode::TickAddress(uword pc, bool exclusive) {
365 const intptr_t length = address_ticks_.length(); 368 const intptr_t length = address_ticks_.length();
366 369
367 intptr_t i = 0; 370 intptr_t i = 0;
(...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after
856 !b->Contains(a->start()) && !b->Contains(a->end() - 1)); 859 !b->Contains(a->start()) && !b->Contains(a->end() - 1));
857 } 860 }
858 } 861 }
859 } 862 }
860 863
861 ZoneGrowableArray<ProfileCode*> table_; 864 ZoneGrowableArray<ProfileCode*> table_;
862 }; 865 };
863 866
864 867
865 ProfileTrieNode::ProfileTrieNode(intptr_t table_index) 868 ProfileTrieNode::ProfileTrieNode(intptr_t table_index)
866 : table_index_(table_index), count_(0), children_(0), frame_id_(-1) { 869 : table_index_(table_index),
870 count_(0),
871 exclusive_allocations_(0),
872 inclusive_allocations_(0),
873 children_(0),
874 frame_id_(-1) {
867 ASSERT(table_index_ >= 0); 875 ASSERT(table_index_ >= 0);
868 } 876 }
869 877
870 878
871 ProfileTrieNode::~ProfileTrieNode() {} 879 ProfileTrieNode::~ProfileTrieNode() {}
872 880
873 881
882 void ProfileTrieNode::Tick(ProcessedSample* sample, bool exclusive) {
883 count_++;
884 IncrementAllocation(sample->native_allocation_size_bytes(), exclusive);
885 }
886
887
874 void ProfileTrieNode::SortChildren() { 888 void ProfileTrieNode::SortChildren() {
875 children_.Sort(ProfileTrieNodeCompare); 889 children_.Sort(ProfileTrieNodeCompare);
876 // Recurse. 890 // Recurse.
877 for (intptr_t i = 0; i < children_.length(); i++) { 891 for (intptr_t i = 0; i < children_.length(); i++) {
878 children_[i]->SortChildren(); 892 children_[i]->SortChildren();
879 } 893 }
880 } 894 }
881 895
882 896
883 intptr_t ProfileTrieNode::IndexOf(ProfileTrieNode* node) { 897 intptr_t ProfileTrieNode::IndexOf(ProfileTrieNode* node) {
(...skipping 13 matching lines...) Expand all
897 911
898 void PrintToJSONArray(JSONArray* array) const { 912 void PrintToJSONArray(JSONArray* array) const {
899 ASSERT(array != NULL); 913 ASSERT(array != NULL);
900 // Write CodeRegion index. 914 // Write CodeRegion index.
901 array->AddValue(table_index()); 915 array->AddValue(table_index());
902 // Write count. 916 // Write count.
903 array->AddValue(count()); 917 array->AddValue(count());
904 // Write number of children. 918 // Write number of children.
905 intptr_t child_count = NumChildren(); 919 intptr_t child_count = NumChildren();
906 array->AddValue(child_count); 920 array->AddValue(child_count);
921 // Write inclusive allocations.
922 array->AddValue64(inclusive_allocations_);
923 // Write exclusive allocations.
924 array->AddValue64(exclusive_allocations_);
907 // Recurse. 925 // Recurse.
908 for (intptr_t i = 0; i < child_count; i++) { 926 for (intptr_t i = 0; i < child_count; i++) {
909 children_[i]->PrintToJSONArray(array); 927 children_[i]->PrintToJSONArray(array);
910 } 928 }
911 } 929 }
912 930
913 ProfileCodeTrieNode* GetChild(intptr_t child_table_index) { 931 ProfileCodeTrieNode* GetChild(intptr_t child_table_index) {
914 const intptr_t length = NumChildren(); 932 const intptr_t length = NumChildren();
915 intptr_t i = 0; 933 intptr_t i = 0;
916 while (i < length) { 934 while (i < length) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
958 public: 976 public:
959 explicit ProfileFunctionTrieNode(intptr_t table_index) 977 explicit ProfileFunctionTrieNode(intptr_t table_index)
960 : ProfileTrieNode(table_index), code_objects_(1) {} 978 : ProfileTrieNode(table_index), code_objects_(1) {}
961 979
962 void PrintToJSONArray(JSONArray* array) const { 980 void PrintToJSONArray(JSONArray* array) const {
963 ASSERT(array != NULL); 981 ASSERT(array != NULL);
964 // Write CodeRegion index. 982 // Write CodeRegion index.
965 array->AddValue(table_index()); 983 array->AddValue(table_index());
966 // Write count. 984 // Write count.
967 array->AddValue(count()); 985 array->AddValue(count());
986 // Write inclusive allocations.
987 array->AddValue64(inclusive_allocations_);
988 // Write exclusive allocations.
989 array->AddValue64(exclusive_allocations_);
968 // Write number of code objects. 990 // Write number of code objects.
969 intptr_t code_count = code_objects_.length(); 991 intptr_t code_count = code_objects_.length();
970 array->AddValue(code_count); 992 array->AddValue(code_count);
971 // Write each code object index and ticks. 993 // Write each code object index and ticks.
972 for (intptr_t i = 0; i < code_count; i++) { 994 for (intptr_t i = 0; i < code_count; i++) {
973 array->AddValue(code_objects_[i].index()); 995 array->AddValue(code_objects_[i].index());
974 array->AddValue(code_objects_[i].ticks()); 996 array->AddValue(code_objects_[i].ticks());
975 } 997 }
976 // Write number of children. 998 // Write number of children.
977 intptr_t child_count = children_.length(); 999 intptr_t child_count = children_.length();
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
1316 // and tick each one. 1338 // and tick each one.
1317 for (intptr_t frame_index = 0; frame_index < sample->length(); 1339 for (intptr_t frame_index = 0; frame_index < sample->length();
1318 frame_index++) { 1340 frame_index++) {
1319 const uword pc = sample->At(frame_index); 1341 const uword pc = sample->At(frame_index);
1320 ASSERT(pc != 0); 1342 ASSERT(pc != 0);
1321 ProfileCode* code = FindOrRegisterProfileCode(pc, timestamp); 1343 ProfileCode* code = FindOrRegisterProfileCode(pc, timestamp);
1322 ASSERT(code != NULL); 1344 ASSERT(code != NULL);
1323 code->Tick(pc, IsExecutingFrame(sample, frame_index), sample_index); 1345 code->Tick(pc, IsExecutingFrame(sample, frame_index), sample_index);
1324 } 1346 }
1325 1347
1326 TickExitFrame(sample->vm_tag(), sample_index); 1348 TickExitFrame(sample->vm_tag(), sample_index, sample);
1327 } 1349 }
1328 SanitizeMinMaxTimes(); 1350 SanitizeMinMaxTimes();
1329 } 1351 }
1330 1352
1331 void FinalizeCodeIndexes() { 1353 void FinalizeCodeIndexes() {
1332 ScopeTimer sw("ProfileBuilder::FinalizeCodeIndexes", FLAG_trace_profiler); 1354 ScopeTimer sw("ProfileBuilder::FinalizeCodeIndexes", FLAG_trace_profiler);
1333 ProfileCodeTable* live_table = profile_->live_code_; 1355 ProfileCodeTable* live_table = profile_->live_code_;
1334 ProfileCodeTable* dead_table = profile_->dead_code_; 1356 ProfileCodeTable* dead_table = profile_->dead_code_;
1335 ProfileCodeTable* tag_table = profile_->tag_code_; 1357 ProfileCodeTable* tag_table = profile_->tag_code_;
1336 const intptr_t dead_code_index_offset = live_table->length(); 1358 const intptr_t dead_code_index_offset = live_table->length();
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1402 1424
1403 void BuildInclusiveCodeTrie(ProfileCodeTrieNode* root) { 1425 void BuildInclusiveCodeTrie(ProfileCodeTrieNode* root) {
1404 ScopeTimer sw("ProfileBuilder::BuildInclusiveCodeTrie", 1426 ScopeTimer sw("ProfileBuilder::BuildInclusiveCodeTrie",
1405 FLAG_trace_profiler); 1427 FLAG_trace_profiler);
1406 for (intptr_t sample_index = 0; sample_index < samples_->length(); 1428 for (intptr_t sample_index = 0; sample_index < samples_->length();
1407 sample_index++) { 1429 sample_index++) {
1408 ProcessedSample* sample = samples_->At(sample_index); 1430 ProcessedSample* sample = samples_->At(sample_index);
1409 1431
1410 // Tick the root. 1432 // Tick the root.
1411 ProfileCodeTrieNode* current = root; 1433 ProfileCodeTrieNode* current = root;
1412 current->Tick(); 1434 current->Tick(sample);
1413 1435
1414 // VM & User tags. 1436 // VM & User tags.
1415 current = AppendTags(sample->vm_tag(), sample->user_tag(), current); 1437 current =
1438 AppendTags(sample->vm_tag(), sample->user_tag(), current, sample);
1416 1439
1417 ResetKind(); 1440 ResetKind();
1418 1441
1419 // Truncated tag. 1442 // Truncated tag.
1420 if (sample->truncated()) { 1443 if (sample->truncated()) {
1421 current = AppendTruncatedTag(current); 1444 current = AppendTruncatedTag(current, sample);
1422 } 1445 }
1423 1446
1424 // Walk the sampled PCs. 1447 // Walk the sampled PCs.
1425 Code& code = Code::Handle(); 1448 Code& code = Code::Handle();
1426 for (intptr_t frame_index = sample->length() - 1; frame_index >= 0; 1449 for (intptr_t frame_index = sample->length() - 1; frame_index >= 0;
1427 frame_index--) { 1450 frame_index--) {
1428 ASSERT(sample->At(frame_index) != 0); 1451 ASSERT(sample->At(frame_index) != 0);
1429 intptr_t index = 1452 intptr_t index =
1430 GetProfileCodeIndex(sample->At(frame_index), sample->timestamp()); 1453 GetProfileCodeIndex(sample->At(frame_index), sample->timestamp());
1431 ASSERT(index >= 0); 1454 ASSERT(index >= 0);
1432 ProfileCode* profile_code = 1455 ProfileCode* profile_code =
1433 GetProfileCode(sample->At(frame_index), sample->timestamp()); 1456 GetProfileCode(sample->At(frame_index), sample->timestamp());
1434 ASSERT(profile_code->code_table_index() == index); 1457 ASSERT(profile_code->code_table_index() == index);
1435 code ^= profile_code->code(); 1458 code ^= profile_code->code();
1436 current = AppendKind(code, current); 1459 current = AppendKind(code, current, sample);
1437 current = current->GetChild(index); 1460 current = current->GetChild(index);
1438 current->Tick(); 1461 current->Tick(sample, (frame_index == 0));
1439 } 1462 }
1440 1463
1441 if (!sample->first_frame_executing()) { 1464 if (!sample->first_frame_executing()) {
1442 current = AppendExitFrame(sample->vm_tag(), current); 1465 current = AppendExitFrame(sample->vm_tag(), current, sample);
1443 } 1466 }
1444 } 1467 }
1445 } 1468 }
1446 1469
1447 void BuildExclusiveCodeTrie(ProfileCodeTrieNode* root) { 1470 void BuildExclusiveCodeTrie(ProfileCodeTrieNode* root) {
1448 ScopeTimer sw("ProfileBuilder::BuildExclusiveCodeTrie", 1471 ScopeTimer sw("ProfileBuilder::BuildExclusiveCodeTrie",
1449 FLAG_trace_profiler); 1472 FLAG_trace_profiler);
1450 for (intptr_t sample_index = 0; sample_index < samples_->length(); 1473 for (intptr_t sample_index = 0; sample_index < samples_->length();
1451 sample_index++) { 1474 sample_index++) {
1452 ProcessedSample* sample = samples_->At(sample_index); 1475 ProcessedSample* sample = samples_->At(sample_index);
1453 1476
1454 // Tick the root. 1477 // Tick the root.
1455 ProfileCodeTrieNode* current = root; 1478 ProfileCodeTrieNode* current = root;
1456 current->Tick(); 1479 current->Tick(sample);
1457
1458 // VM & User tags. 1480 // VM & User tags.
1459 current = AppendTags(sample->vm_tag(), sample->user_tag(), current); 1481 current =
1482 AppendTags(sample->vm_tag(), sample->user_tag(), current, sample);
1460 1483
1461 ResetKind(); 1484 ResetKind();
1462 1485
1463 if (!sample->first_frame_executing()) { 1486 if (!sample->first_frame_executing()) {
1464 current = AppendExitFrame(sample->vm_tag(), current); 1487 current = AppendExitFrame(sample->vm_tag(), current, sample);
1465 } 1488 }
1466 1489
1467 // Walk the sampled PCs. 1490 // Walk the sampled PCs.
1468 Code& code = Code::Handle(); 1491 Code& code = Code::Handle();
1469 for (intptr_t frame_index = 0; frame_index < sample->length(); 1492 for (intptr_t frame_index = 0; frame_index < sample->length();
1470 frame_index++) { 1493 frame_index++) {
1471 ASSERT(sample->At(frame_index) != 0); 1494 ASSERT(sample->At(frame_index) != 0);
1472 intptr_t index = 1495 intptr_t index =
1473 GetProfileCodeIndex(sample->At(frame_index), sample->timestamp()); 1496 GetProfileCodeIndex(sample->At(frame_index), sample->timestamp());
1474 ASSERT(index >= 0); 1497 ASSERT(index >= 0);
1475 ProfileCode* profile_code = 1498 ProfileCode* profile_code =
1476 GetProfileCode(sample->At(frame_index), sample->timestamp()); 1499 GetProfileCode(sample->At(frame_index), sample->timestamp());
1477 ASSERT(profile_code->code_table_index() == index); 1500 ASSERT(profile_code->code_table_index() == index);
1478 code ^= profile_code->code(); 1501 code ^= profile_code->code();
1479 current = current->GetChild(index); 1502 current = current->GetChild(index);
1480 if (ShouldTickNode(sample, frame_index)) { 1503 if (ShouldTickNode(sample, frame_index)) {
1481 current->Tick(); 1504 current->Tick(sample, (frame_index == 0));
1482 } 1505 }
1483 current = AppendKind(code, current); 1506 current = AppendKind(code, current, sample);
1484 } 1507 }
1485 // Truncated tag. 1508 // Truncated tag.
1486 if (sample->truncated()) { 1509 if (sample->truncated()) {
1487 current = AppendTruncatedTag(current); 1510 current = AppendTruncatedTag(current, sample);
1488 } 1511 }
1489 } 1512 }
1490 } 1513 }
1491 1514
1492 void BuildFunctionTrie(Profile::TrieKind kind) { 1515 void BuildFunctionTrie(Profile::TrieKind kind) {
1493 ProfileFunctionTrieNode* root = new ProfileFunctionTrieNode( 1516 ProfileFunctionTrieNode* root = new ProfileFunctionTrieNode(
1494 GetProfileFunctionTagIndex(VMTag::kRootTagId)); 1517 GetProfileFunctionTagIndex(VMTag::kRootTagId));
1495 // We tick the functions while building the trie, but, we don't want to do 1518 // We tick the functions while building the trie, but, we don't want to do
1496 // it for both tries, just the exclusive trie. 1519 // it for both tries, just the exclusive trie.
1497 inclusive_tree_ = IsInclusiveTrie(kind); 1520 inclusive_tree_ = IsInclusiveTrie(kind);
(...skipping 10 matching lines...) Expand all
1508 void BuildInclusiveFunctionTrie(ProfileFunctionTrieNode* root) { 1531 void BuildInclusiveFunctionTrie(ProfileFunctionTrieNode* root) {
1509 ScopeTimer sw("ProfileBuilder::BuildInclusiveFunctionTrie", 1532 ScopeTimer sw("ProfileBuilder::BuildInclusiveFunctionTrie",
1510 FLAG_trace_profiler); 1533 FLAG_trace_profiler);
1511 ASSERT(!tick_functions_); 1534 ASSERT(!tick_functions_);
1512 for (intptr_t sample_index = 0; sample_index < samples_->length(); 1535 for (intptr_t sample_index = 0; sample_index < samples_->length();
1513 sample_index++) { 1536 sample_index++) {
1514 ProcessedSample* sample = samples_->At(sample_index); 1537 ProcessedSample* sample = samples_->At(sample_index);
1515 1538
1516 // Tick the root. 1539 // Tick the root.
1517 ProfileFunctionTrieNode* current = root; 1540 ProfileFunctionTrieNode* current = root;
1518 current->Tick(); 1541 current->Tick(sample);
1519
1520 // VM & User tags. 1542 // VM & User tags.
1521 current = AppendTags(sample->vm_tag(), sample->user_tag(), current); 1543 current =
1544 AppendTags(sample->vm_tag(), sample->user_tag(), current, sample);
1522 1545
1523 // Truncated tag. 1546 // Truncated tag.
1524 if (sample->truncated()) { 1547 if (sample->truncated()) {
1525 current = AppendTruncatedTag(current); 1548 current = AppendTruncatedTag(current, sample);
1526 } 1549 }
1527 1550
1528 // Walk the sampled PCs. 1551 // Walk the sampled PCs.
1529 for (intptr_t frame_index = sample->length() - 1; frame_index >= 0; 1552 for (intptr_t frame_index = sample->length() - 1; frame_index >= 0;
1530 frame_index--) { 1553 frame_index--) {
1531 ASSERT(sample->At(frame_index) != 0); 1554 ASSERT(sample->At(frame_index) != 0);
1532 current = ProcessFrame(current, sample_index, sample, frame_index); 1555 current = ProcessFrame(current, sample_index, sample, frame_index);
1533 } 1556 }
1534 1557
1535 if (!sample->first_frame_executing()) { 1558 if (!sample->first_frame_executing()) {
1536 current = AppendExitFrame(sample->vm_tag(), current); 1559 current = AppendExitFrame(sample->vm_tag(), current, sample);
1537 } 1560 }
1538 1561
1539 sample->set_timeline_trie(current); 1562 sample->set_timeline_trie(current);
1540 } 1563 }
1541 } 1564 }
1542 1565
1543 void BuildExclusiveFunctionTrie(ProfileFunctionTrieNode* root) { 1566 void BuildExclusiveFunctionTrie(ProfileFunctionTrieNode* root) {
1544 ScopeTimer sw("ProfileBuilder::BuildExclusiveFunctionTrie", 1567 ScopeTimer sw("ProfileBuilder::BuildExclusiveFunctionTrie",
1545 FLAG_trace_profiler); 1568 FLAG_trace_profiler);
1546 ASSERT(tick_functions_); 1569 ASSERT(tick_functions_);
1547 for (intptr_t sample_index = 0; sample_index < samples_->length(); 1570 for (intptr_t sample_index = 0; sample_index < samples_->length();
1548 sample_index++) { 1571 sample_index++) {
1549 ProcessedSample* sample = samples_->At(sample_index); 1572 ProcessedSample* sample = samples_->At(sample_index);
1550 1573
1551 // Tick the root. 1574 // Tick the root.
1552 ProfileFunctionTrieNode* current = root; 1575 ProfileFunctionTrieNode* current = root;
1553 current->Tick(); 1576 current->Tick(sample);
1554
1555 // VM & User tags. 1577 // VM & User tags.
1556 current = AppendTags(sample->vm_tag(), sample->user_tag(), current); 1578 current =
1579 AppendTags(sample->vm_tag(), sample->user_tag(), current, sample);
1557 1580
1558 ResetKind(); 1581 ResetKind();
1559 1582
1560 if (!sample->first_frame_executing()) { 1583 if (!sample->first_frame_executing()) {
1561 current = AppendExitFrame(sample->vm_tag(), current); 1584 current = AppendExitFrame(sample->vm_tag(), current, sample);
1562 } 1585 }
1563 1586
1564 // Walk the sampled PCs. 1587 // Walk the sampled PCs.
1565 for (intptr_t frame_index = 0; frame_index < sample->length(); 1588 for (intptr_t frame_index = 0; frame_index < sample->length();
1566 frame_index++) { 1589 frame_index++) {
1567 ASSERT(sample->At(frame_index) != 0); 1590 ASSERT(sample->At(frame_index) != 0);
1568 current = ProcessFrame(current, sample_index, sample, frame_index); 1591 current = ProcessFrame(current, sample_index, sample, frame_index);
1569 } 1592 }
1570 1593
1571 TickExitFrameFunction(sample->vm_tag(), sample_index); 1594 TickExitFrameFunction(sample->vm_tag(), sample_index, sample);
1572 1595
1573 // Truncated tag. 1596 // Truncated tag.
1574 if (sample->truncated()) { 1597 if (sample->truncated()) {
1575 current = AppendTruncatedTag(current); 1598 current = AppendTruncatedTag(current, sample);
1576 InclusiveTickTruncatedTag(); 1599 InclusiveTickTruncatedTag(sample);
1577 } 1600 }
1578 } 1601 }
1579 } 1602 }
1580 1603
1581 ProfileFunctionTrieNode* ProcessFrame(ProfileFunctionTrieNode* current, 1604 ProfileFunctionTrieNode* ProcessFrame(ProfileFunctionTrieNode* current,
1582 intptr_t sample_index, 1605 intptr_t sample_index,
1583 ProcessedSample* sample, 1606 ProcessedSample* sample,
1584 intptr_t frame_index) { 1607 intptr_t frame_index) {
1585 const uword pc = sample->At(frame_index); 1608 const uword pc = sample->At(frame_index);
1586 ProfileCode* profile_code = GetProfileCode(pc, sample->timestamp()); 1609 ProfileCode* profile_code = GetProfileCode(pc, sample->timestamp());
(...skipping 17 matching lines...) Expand all
1604 name.ToCString(), 1627 name.ToCString(),
1605 (*inlined_token_positions)[i].ToCString()); 1628 (*inlined_token_positions)[i].ToCString());
1606 } 1629 }
1607 } 1630 }
1608 } 1631 }
1609 1632
1610 if (code.IsNull() || (inlined_functions == NULL) || 1633 if (code.IsNull() || (inlined_functions == NULL) ||
1611 (inlined_functions->length() <= 1)) { 1634 (inlined_functions->length() <= 1)) {
1612 // No inlined functions. 1635 // No inlined functions.
1613 if (inclusive_tree_) { 1636 if (inclusive_tree_) {
1614 current = AppendKind(code, current); 1637 current = AppendKind(code, current, sample);
1615 } 1638 }
1616 current = ProcessFunction(current, sample_index, sample, frame_index, 1639 current = ProcessFunction(current, sample_index, sample, frame_index,
1617 function, token_position, code_index); 1640 function, token_position, code_index);
1618 if (!inclusive_tree_) { 1641 if (!inclusive_tree_) {
1619 current = AppendKind(code, current); 1642 current = AppendKind(code, current, sample);
1620 } 1643 }
1621 return current; 1644 return current;
1622 } 1645 }
1623 1646
1647 // TODO(bkonyi) deal with this
1624 ASSERT(code.is_optimized()); 1648 ASSERT(code.is_optimized());
1625 1649
1626 if (inclusive_tree_) { 1650 if (inclusive_tree_) {
1627 for (intptr_t i = 0; i < inlined_functions->length(); i++) { 1651 for (intptr_t i = 0; i < inlined_functions->length(); i++) {
1628 const Function* inlined_function = (*inlined_functions)[i]; 1652 const Function* inlined_function = (*inlined_functions)[i];
1629 ASSERT(inlined_function != NULL); 1653 ASSERT(inlined_function != NULL);
1630 ASSERT(!inlined_function->IsNull()); 1654 ASSERT(!inlined_function->IsNull());
1631 TokenPosition inlined_token_position = (*inlined_token_positions)[i]; 1655 TokenPosition inlined_token_position = (*inlined_token_positions)[i];
1632 const bool inliner = i == 0; 1656 const bool inliner = i == 0;
1633 if (inliner) { 1657 if (inliner) {
1634 current = AppendKind(code, current); 1658 current = AppendKind(code, current, sample);
1635 } 1659 }
1636 current = ProcessInlinedFunction(current, sample_index, sample, 1660 current = ProcessInlinedFunction(current, sample_index, sample,
1637 frame_index, inlined_function, 1661 frame_index, inlined_function,
1638 inlined_token_position, code_index); 1662 inlined_token_position, code_index);
1639 if (inliner) { 1663 if (inliner) {
1640 current = AppendKind(kInlineStart, current); 1664 current = AppendKind(kInlineStart, current, sample);
1641 } 1665 }
1642 } 1666 }
1643 current = AppendKind(kInlineFinish, current); 1667 current = AppendKind(kInlineFinish, current, sample);
1644 } else { 1668 } else {
1645 // Append the inlined children. 1669 // Append the inlined children.
1646 current = AppendKind(kInlineFinish, current); 1670 current = AppendKind(kInlineFinish, current, sample);
1647 for (intptr_t i = inlined_functions->length() - 1; i >= 0; i--) { 1671 for (intptr_t i = inlined_functions->length() - 1; i >= 0; i--) {
1648 const Function* inlined_function = (*inlined_functions)[i]; 1672 const Function* inlined_function = (*inlined_functions)[i];
1649 ASSERT(inlined_function != NULL); 1673 ASSERT(inlined_function != NULL);
1650 ASSERT(!inlined_function->IsNull()); 1674 ASSERT(!inlined_function->IsNull());
1651 TokenPosition inlined_token_position = (*inlined_token_positions)[i]; 1675 TokenPosition inlined_token_position = (*inlined_token_positions)[i];
1652 const bool inliner = i == 0; 1676 const bool inliner = i == 0;
1653 if (inliner) { 1677 if (inliner) {
1654 current = AppendKind(kInlineStart, current); 1678 current = AppendKind(kInlineStart, current, sample);
1655 } 1679 }
1656 current = ProcessInlinedFunction(current, sample_index, sample, 1680 current = ProcessInlinedFunction(current, sample_index, sample,
1657 frame_index + i, inlined_function, 1681 frame_index + i, inlined_function,
1658 inlined_token_position, code_index); 1682 inlined_token_position, code_index);
1659 if (inliner) { 1683 if (inliner) {
1660 current = AppendKind(code, current); 1684 current = AppendKind(code, current, sample);
1661 } 1685 }
1662 } 1686 }
1663 } 1687 }
1664 1688
1665 return current; 1689 return current;
1666 } 1690 }
1667 1691
1668 ProfileFunctionTrieNode* ProcessInlinedFunction( 1692 ProfileFunctionTrieNode* ProcessInlinedFunction(
1669 ProfileFunctionTrieNode* current, 1693 ProfileFunctionTrieNode* current,
1670 intptr_t sample_index, 1694 intptr_t sample_index,
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1705 THR_Print("S[%" Pd "]F[%" Pd "] %s %s 0x%" Px "\n", sample_index, 1729 THR_Print("S[%" Pd "]F[%" Pd "] %s %s 0x%" Px "\n", sample_index,
1706 frame_index, function->Name(), token_position.ToCString(), 1730 frame_index, function->Name(), token_position.ToCString(),
1707 sample->At(frame_index)); 1731 sample->At(frame_index));
1708 } 1732 }
1709 function->Tick(IsExecutingFrame(sample, frame_index), sample_index, 1733 function->Tick(IsExecutingFrame(sample, frame_index), sample_index,
1710 token_position); 1734 token_position);
1711 } 1735 }
1712 function->AddProfileCode(code_index); 1736 function->AddProfileCode(code_index);
1713 current = current->GetChild(function->table_index()); 1737 current = current->GetChild(function->table_index());
1714 if (ShouldTickNode(sample, frame_index)) { 1738 if (ShouldTickNode(sample, frame_index)) {
1715 current->Tick(); 1739 current->Tick(sample, (frame_index == 0));
1716 } 1740 }
1717 current->AddCodeObjectIndex(code_index); 1741 current->AddCodeObjectIndex(code_index);
1718 return current; 1742 return current;
1719 } 1743 }
1720 1744
1721 // Tick the truncated tag's inclusive tick count. 1745 // Tick the truncated tag's inclusive tick count.
1722 void InclusiveTickTruncatedTag() { 1746 void InclusiveTickTruncatedTag(ProcessedSample* sample) {
1723 ProfileCodeTable* tag_table = profile_->tag_code_; 1747 ProfileCodeTable* tag_table = profile_->tag_code_;
1724 intptr_t index = tag_table->FindCodeIndexForPC(VMTag::kTruncatedTagId); 1748 intptr_t index = tag_table->FindCodeIndexForPC(VMTag::kTruncatedTagId);
1725 ASSERT(index >= 0); 1749 ASSERT(index >= 0);
1726 ProfileCode* code = tag_table->At(index); 1750 ProfileCode* code = tag_table->At(index);
1727 code->IncInclusiveTicks(); 1751 code->IncInclusiveTicks();
1728 ASSERT(code != NULL); 1752 ASSERT(code != NULL);
1729 ProfileFunction* function = code->function(); 1753 ProfileFunction* function = code->function();
1730 function->IncInclusiveTicks(); 1754 function->IncInclusiveTicks();
1731 } 1755 }
1732 1756
1733 1757
1734 // Tag append functions are overloaded for |ProfileCodeTrieNode| and 1758 // Tag append functions are overloaded for |ProfileCodeTrieNode| and
1735 // |ProfileFunctionTrieNode| types. 1759 // |ProfileFunctionTrieNode| types.
1736 1760
1737 // ProfileCodeTrieNode 1761 // ProfileCodeTrieNode
1738 ProfileCodeTrieNode* AppendUserTag(uword user_tag, 1762 ProfileCodeTrieNode* AppendUserTag(uword user_tag,
1739 ProfileCodeTrieNode* current) { 1763 ProfileCodeTrieNode* current,
1764 ProcessedSample* sample) {
1740 intptr_t user_tag_index = GetProfileCodeTagIndex(user_tag); 1765 intptr_t user_tag_index = GetProfileCodeTagIndex(user_tag);
1741 if (user_tag_index >= 0) { 1766 if (user_tag_index >= 0) {
1742 current = current->GetChild(user_tag_index); 1767 current = current->GetChild(user_tag_index);
1743 current->Tick(); 1768 current->Tick(sample);
1744 } 1769 }
1745 return current; 1770 return current;
1746 } 1771 }
1747 1772
1748 ProfileCodeTrieNode* AppendTruncatedTag(ProfileCodeTrieNode* current) { 1773 ProfileCodeTrieNode* AppendTruncatedTag(ProfileCodeTrieNode* current,
1774 ProcessedSample* sample) {
1749 intptr_t truncated_tag_index = 1775 intptr_t truncated_tag_index =
1750 GetProfileCodeTagIndex(VMTag::kTruncatedTagId); 1776 GetProfileCodeTagIndex(VMTag::kTruncatedTagId);
1751 ASSERT(truncated_tag_index >= 0); 1777 ASSERT(truncated_tag_index >= 0);
1752 current = current->GetChild(truncated_tag_index); 1778 current = current->GetChild(truncated_tag_index);
1753 current->Tick(); 1779 current->Tick(sample);
1754 return current; 1780 return current;
1755 } 1781 }
1756 1782
1757 ProfileCodeTrieNode* AppendVMTag(uword vm_tag, ProfileCodeTrieNode* current) { 1783 ProfileCodeTrieNode* AppendVMTag(uword vm_tag,
1784 ProfileCodeTrieNode* current,
1785 ProcessedSample* sample) {
1758 if (VMTag::IsNativeEntryTag(vm_tag)) { 1786 if (VMTag::IsNativeEntryTag(vm_tag)) {
1759 // Insert a dummy kNativeTagId node. 1787 // Insert a dummy kNativeTagId node.
1760 intptr_t tag_index = GetProfileCodeTagIndex(VMTag::kNativeTagId); 1788 intptr_t tag_index = GetProfileCodeTagIndex(VMTag::kNativeTagId);
1761 current = current->GetChild(tag_index); 1789 current = current->GetChild(tag_index);
1762 // Give the tag a tick. 1790 // Give the tag a tick.
1763 current->Tick(); 1791 current->Tick(sample);
1764 } else if (VMTag::IsRuntimeEntryTag(vm_tag)) { 1792 } else if (VMTag::IsRuntimeEntryTag(vm_tag)) {
1765 // Insert a dummy kRuntimeTagId node. 1793 // Insert a dummy kRuntimeTagId node.
1766 intptr_t tag_index = GetProfileCodeTagIndex(VMTag::kRuntimeTagId); 1794 intptr_t tag_index = GetProfileCodeTagIndex(VMTag::kRuntimeTagId);
1767 current = current->GetChild(tag_index); 1795 current = current->GetChild(tag_index);
1768 // Give the tag a tick. 1796 // Give the tag a tick.
1769 current->Tick(); 1797 current->Tick(sample);
1770 } else { 1798 } else {
1771 intptr_t tag_index = GetProfileCodeTagIndex(vm_tag); 1799 intptr_t tag_index = GetProfileCodeTagIndex(vm_tag);
1772 current = current->GetChild(tag_index); 1800 current = current->GetChild(tag_index);
1773 // Give the tag a tick. 1801 // Give the tag a tick.
1774 current->Tick(); 1802 current->Tick(sample);
1775 } 1803 }
1776 return current; 1804 return current;
1777 } 1805 }
1778 1806
1779 ProfileCodeTrieNode* AppendSpecificNativeRuntimeEntryVMTag( 1807 ProfileCodeTrieNode* AppendSpecificNativeRuntimeEntryVMTag(
1780 uword vm_tag, 1808 uword vm_tag,
1781 ProfileCodeTrieNode* current) { 1809 ProfileCodeTrieNode* current,
1810 ProcessedSample* sample) {
1782 // Only Native and Runtime entries have a second VM tag. 1811 // Only Native and Runtime entries have a second VM tag.
1783 if (!VMTag::IsNativeEntryTag(vm_tag) && !VMTag::IsRuntimeEntryTag(vm_tag)) { 1812 if (!VMTag::IsNativeEntryTag(vm_tag) && !VMTag::IsRuntimeEntryTag(vm_tag)) {
1784 return current; 1813 return current;
1785 } 1814 }
1786 intptr_t tag_index = GetProfileCodeTagIndex(vm_tag); 1815 intptr_t tag_index = GetProfileCodeTagIndex(vm_tag);
1787 current = current->GetChild(tag_index); 1816 current = current->GetChild(tag_index);
1788 // Give the tag a tick. 1817 // Give the tag a tick.
1789 current->Tick(); 1818 current->Tick(sample);
1790 return current; 1819 return current;
1791 } 1820 }
1792 1821
1793 uword ProfileInfoKindToVMTag(ProfileInfoKind kind) { 1822 uword ProfileInfoKindToVMTag(ProfileInfoKind kind) {
1794 switch (kind) { 1823 switch (kind) {
1795 case kNone: 1824 case kNone:
1796 return VMTag::kNoneCodeTagId; 1825 return VMTag::kNoneCodeTagId;
1797 case kOptimized: 1826 case kOptimized:
1798 return VMTag::kOptimizedCodeTagId; 1827 return VMTag::kOptimizedCodeTagId;
1799 case kUnoptimized: 1828 case kUnoptimized:
1800 return VMTag::kUnoptimizedCodeTagId; 1829 return VMTag::kUnoptimizedCodeTagId;
1801 case kNative: 1830 case kNative:
1802 return VMTag::kNativeCodeTagId; 1831 return VMTag::kNativeCodeTagId;
1803 case kInlineStart: 1832 case kInlineStart:
1804 return VMTag::kInlineStartCodeTagId; 1833 return VMTag::kInlineStartCodeTagId;
1805 case kInlineFinish: 1834 case kInlineFinish:
1806 return VMTag::kInlineEndCodeTagId; 1835 return VMTag::kInlineEndCodeTagId;
1807 default: 1836 default:
1808 UNIMPLEMENTED(); 1837 UNIMPLEMENTED();
1809 return VMTag::kInvalidTagId; 1838 return VMTag::kInvalidTagId;
1810 } 1839 }
1811 } 1840 }
1812 1841
1813 ProfileCodeTrieNode* AppendKind(ProfileInfoKind kind, 1842 ProfileCodeTrieNode* AppendKind(ProfileInfoKind kind,
1814 ProfileCodeTrieNode* current) { 1843 ProfileCodeTrieNode* current,
1844 ProcessedSample* sample) {
1815 if (!TagsEnabled(ProfilerService::kCodeTransitionTagsBit)) { 1845 if (!TagsEnabled(ProfilerService::kCodeTransitionTagsBit)) {
1816 // Only emit if debug tags are requested. 1846 // Only emit if debug tags are requested.
1817 return current; 1847 return current;
1818 } 1848 }
1819 if (kind != info_kind_) { 1849 if (kind != info_kind_) {
1820 info_kind_ = kind; 1850 info_kind_ = kind;
1821 intptr_t tag_index = GetProfileCodeTagIndex(ProfileInfoKindToVMTag(kind)); 1851 intptr_t tag_index = GetProfileCodeTagIndex(ProfileInfoKindToVMTag(kind));
1822 ASSERT(tag_index >= 0); 1852 ASSERT(tag_index >= 0);
1823 current = current->GetChild(tag_index); 1853 current = current->GetChild(tag_index);
1824 current->Tick(); 1854 current->Tick(sample);
1825 } 1855 }
1826 return current; 1856 return current;
1827 } 1857 }
1828 1858
1829 ProfileCodeTrieNode* AppendKind(const Code& code, 1859 ProfileCodeTrieNode* AppendKind(const Code& code,
1830 ProfileCodeTrieNode* current) { 1860 ProfileCodeTrieNode* current,
1861 ProcessedSample* sample) {
1831 if (code.IsNull()) { 1862 if (code.IsNull()) {
1832 return AppendKind(kNone, current); 1863 return AppendKind(kNone, current, sample);
1833 } else if (code.is_optimized()) { 1864 } else if (code.is_optimized()) {
1834 return AppendKind(kOptimized, current); 1865 return AppendKind(kOptimized, current, sample);
1835 } else { 1866 } else {
1836 return AppendKind(kUnoptimized, current); 1867 return AppendKind(kUnoptimized, current, sample);
1837 } 1868 }
1838 } 1869 }
1839 1870
1840 ProfileCodeTrieNode* AppendVMTags(uword vm_tag, 1871 ProfileCodeTrieNode* AppendVMTags(uword vm_tag,
1841 ProfileCodeTrieNode* current) { 1872 ProfileCodeTrieNode* current,
1842 current = AppendVMTag(vm_tag, current); 1873 ProcessedSample* sample) {
1843 current = AppendSpecificNativeRuntimeEntryVMTag(vm_tag, current); 1874 current = AppendVMTag(vm_tag, current, sample);
1875 current = AppendSpecificNativeRuntimeEntryVMTag(vm_tag, current, sample);
1844 return current; 1876 return current;
1845 } 1877 }
1846 1878
1847 void TickExitFrame(uword vm_tag, intptr_t serial) { 1879 void TickExitFrame(uword vm_tag, intptr_t serial, ProcessedSample* sample) {
1848 if (FLAG_profile_vm) { 1880 if (FLAG_profile_vm) {
1849 return; 1881 return;
1850 } 1882 }
1851 if (!VMTag::IsExitFrameTag(vm_tag)) { 1883 if (!VMTag::IsExitFrameTag(vm_tag)) {
1852 return; 1884 return;
1853 } 1885 }
1854 ProfileCodeTable* tag_table = profile_->tag_code_; 1886 ProfileCodeTable* tag_table = profile_->tag_code_;
1855 ProfileCode* code = tag_table->FindCodeForPC(vm_tag); 1887 ProfileCode* code = tag_table->FindCodeForPC(vm_tag);
1856 ASSERT(code != NULL); 1888 ASSERT(code != NULL);
1857 code->Tick(vm_tag, true, serial); 1889 code->Tick(vm_tag, true, serial);
1858 } 1890 }
1859 1891
1860 void TickExitFrameFunction(uword vm_tag, intptr_t serial) { 1892 void TickExitFrameFunction(uword vm_tag,
1893 intptr_t serial,
1894 ProcessedSample* sample) {
Cutch 2017/03/21 20:27:11 sample doesn't appear used here?
bkonyi 2017/03/22 21:25:21 Removed.
1861 if (FLAG_profile_vm) { 1895 if (FLAG_profile_vm) {
1862 return; 1896 return;
1863 } 1897 }
1864 if (!VMTag::IsExitFrameTag(vm_tag)) { 1898 if (!VMTag::IsExitFrameTag(vm_tag)) {
1865 return; 1899 return;
1866 } 1900 }
1867 ProfileCodeTable* tag_table = profile_->tag_code_; 1901 ProfileCodeTable* tag_table = profile_->tag_code_;
1868 ProfileCode* code = tag_table->FindCodeForPC(vm_tag); 1902 ProfileCode* code = tag_table->FindCodeForPC(vm_tag);
1869 ASSERT(code != NULL); 1903 ASSERT(code != NULL);
1870 ProfileFunction* function = code->function(); 1904 ProfileFunction* function = code->function();
1871 ASSERT(function != NULL); 1905 ASSERT(function != NULL);
1872 function->Tick(true, serial, TokenPosition::kNoSource); 1906 function->Tick(true, serial, TokenPosition::kNoSource);
1873 } 1907 }
1874 1908
1875 ProfileCodeTrieNode* AppendExitFrame(uword vm_tag, 1909 ProfileCodeTrieNode* AppendExitFrame(uword vm_tag,
1876 ProfileCodeTrieNode* current) { 1910 ProfileCodeTrieNode* current,
1911 ProcessedSample* sample) {
1877 if (FLAG_profile_vm) { 1912 if (FLAG_profile_vm) {
1878 return current; 1913 return current;
1879 } 1914 }
1880 1915
1881 if (!VMTag::IsExitFrameTag(vm_tag)) { 1916 if (!VMTag::IsExitFrameTag(vm_tag)) {
1882 return current; 1917 return current;
1883 } 1918 }
1884 1919
1885 if (VMTag::IsNativeEntryTag(vm_tag) || VMTag::IsRuntimeEntryTag(vm_tag)) { 1920 if (VMTag::IsNativeEntryTag(vm_tag) || VMTag::IsRuntimeEntryTag(vm_tag)) {
1886 current = AppendSpecificNativeRuntimeEntryVMTag(vm_tag, current); 1921 current = AppendSpecificNativeRuntimeEntryVMTag(vm_tag, current, sample);
1887 } else { 1922 } else {
1888 intptr_t tag_index = GetProfileCodeTagIndex(vm_tag); 1923 intptr_t tag_index = GetProfileCodeTagIndex(vm_tag);
1889 current = current->GetChild(tag_index); 1924 current = current->GetChild(tag_index);
1890 // Give the tag a tick. 1925 // Give the tag a tick.
1891 current->Tick(); 1926 current->Tick(sample);
1892 } 1927 }
1893 return current; 1928 return current;
1894 } 1929 }
1895 1930
1896 ProfileCodeTrieNode* AppendTags(uword vm_tag, 1931 ProfileCodeTrieNode* AppendTags(uword vm_tag,
1897 uword user_tag, 1932 uword user_tag,
1898 ProfileCodeTrieNode* current) { 1933 ProfileCodeTrieNode* current,
1934 ProcessedSample* sample) {
1899 if (FLAG_profile_vm) { 1935 if (FLAG_profile_vm) {
1900 // None. 1936 // None.
1901 if (tag_order() == Profile::kNoTags) { 1937 if (tag_order() == Profile::kNoTags) {
1902 return current; 1938 return current;
1903 } 1939 }
1904 // User first. 1940 // User first.
1905 if ((tag_order() == Profile::kUserVM) || 1941 if ((tag_order() == Profile::kUserVM) ||
1906 (tag_order() == Profile::kUser)) { 1942 (tag_order() == Profile::kUser)) {
1907 current = AppendUserTag(user_tag, current); 1943 current = AppendUserTag(user_tag, current, sample);
1908 // Only user. 1944 // Only user.
1909 if (tag_order() == Profile::kUser) { 1945 if (tag_order() == Profile::kUser) {
1910 return current; 1946 return current;
1911 } 1947 }
1912 return AppendVMTags(vm_tag, current); 1948 return AppendVMTags(vm_tag, current, sample);
1913 } 1949 }
1914 // VM first. 1950 // VM first.
1915 ASSERT((tag_order() == Profile::kVMUser) || 1951 ASSERT((tag_order() == Profile::kVMUser) ||
1916 (tag_order() == Profile::kVM)); 1952 (tag_order() == Profile::kVM));
1917 current = AppendVMTags(vm_tag, current); 1953 current = AppendVMTags(vm_tag, current, sample);
1918 // Only VM. 1954 // Only VM.
1919 if (tag_order() == Profile::kVM) { 1955 if (tag_order() == Profile::kVM) {
1920 return current; 1956 return current;
1921 } 1957 }
1922 return AppendUserTag(user_tag, current); 1958 return AppendUserTag(user_tag, current, sample);
1923 } 1959 }
1924 1960
1925 if (tag_order() == Profile::kNoTags) { 1961 if (tag_order() == Profile::kNoTags) {
1926 return current; 1962 return current;
1927 } 1963 }
1928 1964
1929 return AppendUserTag(user_tag, current); 1965 return AppendUserTag(user_tag, current, sample);
1930 } 1966 }
1931 1967
1932 // ProfileFunctionTrieNode 1968 // ProfileFunctionTrieNode
1933 void ResetKind() { info_kind_ = kNone; } 1969 void ResetKind() { info_kind_ = kNone; }
1934 1970
1935 ProfileFunctionTrieNode* AppendKind(ProfileInfoKind kind, 1971 ProfileFunctionTrieNode* AppendKind(ProfileInfoKind kind,
1936 ProfileFunctionTrieNode* current) { 1972 ProfileFunctionTrieNode* current,
1973 ProcessedSample* sample) {
1937 if (!TagsEnabled(ProfilerService::kCodeTransitionTagsBit)) { 1974 if (!TagsEnabled(ProfilerService::kCodeTransitionTagsBit)) {
1938 // Only emit if debug tags are requested. 1975 // Only emit if debug tags are requested.
1939 return current; 1976 return current;
1940 } 1977 }
1941 if (kind != info_kind_) { 1978 if (kind != info_kind_) {
1942 info_kind_ = kind; 1979 info_kind_ = kind;
1943 intptr_t tag_index = 1980 intptr_t tag_index =
1944 GetProfileFunctionTagIndex(ProfileInfoKindToVMTag(kind)); 1981 GetProfileFunctionTagIndex(ProfileInfoKindToVMTag(kind));
1945 ASSERT(tag_index >= 0); 1982 ASSERT(tag_index >= 0);
1946 current = current->GetChild(tag_index); 1983 current = current->GetChild(tag_index);
1947 current->Tick(); 1984 current->Tick(sample);
1948 } 1985 }
1949 return current; 1986 return current;
1950 } 1987 }
1951 1988
1952 ProfileFunctionTrieNode* AppendKind(const Code& code, 1989 ProfileFunctionTrieNode* AppendKind(const Code& code,
1953 ProfileFunctionTrieNode* current) { 1990 ProfileFunctionTrieNode* current,
1991 ProcessedSample* sample) {
1954 if (code.IsNull()) { 1992 if (code.IsNull()) {
1955 return AppendKind(kNone, current); 1993 return AppendKind(kNone, current, sample);
1956 } else if (code.is_optimized()) { 1994 } else if (code.is_optimized()) {
1957 return AppendKind(kOptimized, current); 1995 return AppendKind(kOptimized, current, sample);
1958 } else { 1996 } else {
1959 return AppendKind(kUnoptimized, current); 1997 return AppendKind(kUnoptimized, current, sample);
1960 } 1998 }
1961 } 1999 }
1962 2000
1963 ProfileFunctionTrieNode* AppendUserTag(uword user_tag, 2001 ProfileFunctionTrieNode* AppendUserTag(uword user_tag,
1964 ProfileFunctionTrieNode* current) { 2002 ProfileFunctionTrieNode* current,
2003 ProcessedSample* sample) {
1965 intptr_t user_tag_index = GetProfileFunctionTagIndex(user_tag); 2004 intptr_t user_tag_index = GetProfileFunctionTagIndex(user_tag);
1966 if (user_tag_index >= 0) { 2005 if (user_tag_index >= 0) {
1967 current = current->GetChild(user_tag_index); 2006 current = current->GetChild(user_tag_index);
1968 current->Tick(); 2007 current->Tick(sample);
1969 } 2008 }
1970 return current; 2009 return current;
1971 } 2010 }
1972 2011
1973 ProfileFunctionTrieNode* AppendTruncatedTag( 2012 ProfileFunctionTrieNode* AppendTruncatedTag(ProfileFunctionTrieNode* current,
1974 ProfileFunctionTrieNode* current) { 2013 ProcessedSample* sample) {
1975 intptr_t truncated_tag_index = 2014 intptr_t truncated_tag_index =
1976 GetProfileFunctionTagIndex(VMTag::kTruncatedTagId); 2015 GetProfileFunctionTagIndex(VMTag::kTruncatedTagId);
1977 ASSERT(truncated_tag_index >= 0); 2016 ASSERT(truncated_tag_index >= 0);
1978 current = current->GetChild(truncated_tag_index); 2017 current = current->GetChild(truncated_tag_index);
1979 current->Tick(); 2018 current->Tick(sample);
1980 return current; 2019 return current;
1981 } 2020 }
1982 2021
1983 ProfileFunctionTrieNode* AppendVMTag(uword vm_tag, 2022 ProfileFunctionTrieNode* AppendVMTag(uword vm_tag,
1984 ProfileFunctionTrieNode* current) { 2023 ProfileFunctionTrieNode* current,
2024 ProcessedSample* sample) {
1985 if (VMTag::IsNativeEntryTag(vm_tag)) { 2025 if (VMTag::IsNativeEntryTag(vm_tag)) {
1986 // Insert a dummy kNativeTagId node. 2026 // Insert a dummy kNativeTagId node.
1987 intptr_t tag_index = GetProfileFunctionTagIndex(VMTag::kNativeTagId); 2027 intptr_t tag_index = GetProfileFunctionTagIndex(VMTag::kNativeTagId);
1988 current = current->GetChild(tag_index); 2028 current = current->GetChild(tag_index);
1989 // Give the tag a tick. 2029 // Give the tag a tick.
1990 current->Tick(); 2030 current->Tick(sample);
1991 } else if (VMTag::IsRuntimeEntryTag(vm_tag)) { 2031 } else if (VMTag::IsRuntimeEntryTag(vm_tag)) {
1992 // Insert a dummy kRuntimeTagId node. 2032 // Insert a dummy kRuntimeTagId node.
1993 intptr_t tag_index = GetProfileFunctionTagIndex(VMTag::kRuntimeTagId); 2033 intptr_t tag_index = GetProfileFunctionTagIndex(VMTag::kRuntimeTagId);
1994 current = current->GetChild(tag_index); 2034 current = current->GetChild(tag_index);
1995 // Give the tag a tick. 2035 // Give the tag a tick.
1996 current->Tick(); 2036 current->Tick(sample);
1997 } else { 2037 } else {
1998 intptr_t tag_index = GetProfileFunctionTagIndex(vm_tag); 2038 intptr_t tag_index = GetProfileFunctionTagIndex(vm_tag);
1999 current = current->GetChild(tag_index); 2039 current = current->GetChild(tag_index);
2000 // Give the tag a tick. 2040 // Give the tag a tick.
2001 current->Tick(); 2041 current->Tick(sample);
2002 } 2042 }
2003 return current; 2043 return current;
2004 } 2044 }
2005 2045
2006 ProfileFunctionTrieNode* AppendSpecificNativeRuntimeEntryVMTag( 2046 ProfileFunctionTrieNode* AppendSpecificNativeRuntimeEntryVMTag(
2007 uword vm_tag, 2047 uword vm_tag,
2008 ProfileFunctionTrieNode* current) { 2048 ProfileFunctionTrieNode* current,
2049 ProcessedSample* sample) {
2009 // Only Native and Runtime entries have a second VM tag. 2050 // Only Native and Runtime entries have a second VM tag.
2010 if (!VMTag::IsNativeEntryTag(vm_tag) && !VMTag::IsRuntimeEntryTag(vm_tag)) { 2051 if (!VMTag::IsNativeEntryTag(vm_tag) && !VMTag::IsRuntimeEntryTag(vm_tag)) {
2011 return current; 2052 return current;
2012 } 2053 }
2013 intptr_t tag_index = GetProfileFunctionTagIndex(vm_tag); 2054 intptr_t tag_index = GetProfileFunctionTagIndex(vm_tag);
2014 current = current->GetChild(tag_index); 2055 current = current->GetChild(tag_index);
2015 // Give the tag a tick. 2056 // Give the tag a tick.
2016 current->Tick(); 2057 current->Tick(sample);
2017 return current; 2058 return current;
2018 } 2059 }
2019 2060
2020 ProfileFunctionTrieNode* AppendVMTags(uword vm_tag, 2061 ProfileFunctionTrieNode* AppendVMTags(uword vm_tag,
2021 ProfileFunctionTrieNode* current) { 2062 ProfileFunctionTrieNode* current,
2022 current = AppendVMTag(vm_tag, current); 2063 ProcessedSample* sample) {
2023 current = AppendSpecificNativeRuntimeEntryVMTag(vm_tag, current); 2064 current = AppendVMTag(vm_tag, current, sample);
2065 current = AppendSpecificNativeRuntimeEntryVMTag(vm_tag, current, sample);
2024 return current; 2066 return current;
2025 } 2067 }
2026 2068
2027 ProfileFunctionTrieNode* AppendExitFrame(uword vm_tag, 2069 ProfileFunctionTrieNode* AppendExitFrame(uword vm_tag,
2028 ProfileFunctionTrieNode* current) { 2070 ProfileFunctionTrieNode* current,
2071 ProcessedSample* sample) {
2029 if (FLAG_profile_vm) { 2072 if (FLAG_profile_vm) {
2030 return current; 2073 return current;
2031 } 2074 }
2032 2075
2033 if (!VMTag::IsExitFrameTag(vm_tag)) { 2076 if (!VMTag::IsExitFrameTag(vm_tag)) {
2034 return current; 2077 return current;
2035 } 2078 }
2036 if (VMTag::IsNativeEntryTag(vm_tag) || VMTag::IsRuntimeEntryTag(vm_tag)) { 2079 if (VMTag::IsNativeEntryTag(vm_tag) || VMTag::IsRuntimeEntryTag(vm_tag)) {
2037 current = AppendSpecificNativeRuntimeEntryVMTag(vm_tag, current); 2080 current = AppendSpecificNativeRuntimeEntryVMTag(vm_tag, current, sample);
2038 } else { 2081 } else {
2039 intptr_t tag_index = GetProfileFunctionTagIndex(vm_tag); 2082 intptr_t tag_index = GetProfileFunctionTagIndex(vm_tag);
2040 current = current->GetChild(tag_index); 2083 current = current->GetChild(tag_index);
2041 // Give the tag a tick. 2084 // Give the tag a tick.
2042 current->Tick(); 2085 current->Tick(sample);
2043 } 2086 }
2044 return current; 2087 return current;
2045 } 2088 }
2046 2089
2047 ProfileFunctionTrieNode* AppendTags(uword vm_tag, 2090 ProfileFunctionTrieNode* AppendTags(uword vm_tag,
2048 uword user_tag, 2091 uword user_tag,
2049 ProfileFunctionTrieNode* current) { 2092 ProfileFunctionTrieNode* current,
2093 ProcessedSample* sample) {
2050 if (FLAG_profile_vm) { 2094 if (FLAG_profile_vm) {
2051 // None. 2095 // None.
2052 if (tag_order() == Profile::kNoTags) { 2096 if (tag_order() == Profile::kNoTags) {
2053 return current; 2097 return current;
2054 } 2098 }
2055 // User first. 2099 // User first.
2056 if ((tag_order() == Profile::kUserVM) || 2100 if ((tag_order() == Profile::kUserVM) ||
2057 (tag_order() == Profile::kUser)) { 2101 (tag_order() == Profile::kUser)) {
2058 current = AppendUserTag(user_tag, current); 2102 current = AppendUserTag(user_tag, current, sample);
2059 // Only user. 2103 // Only user.
2060 if (tag_order() == Profile::kUser) { 2104 if (tag_order() == Profile::kUser) {
2061 return current; 2105 return current;
2062 } 2106 }
2063 return AppendVMTags(vm_tag, current); 2107 return AppendVMTags(vm_tag, current, sample);
2064 } 2108 }
2065 // VM first. 2109 // VM first.
2066 ASSERT((tag_order() == Profile::kVMUser) || 2110 ASSERT((tag_order() == Profile::kVMUser) ||
2067 (tag_order() == Profile::kVM)); 2111 (tag_order() == Profile::kVM));
2068 current = AppendVMTags(vm_tag, current); 2112 current = AppendVMTags(vm_tag, current, sample);
2069 // Only VM. 2113 // Only VM.
2070 if (tag_order() == Profile::kVM) { 2114 if (tag_order() == Profile::kVM) {
2071 return current; 2115 return current;
2072 } 2116 }
2073 return AppendUserTag(user_tag, current); 2117 return AppendUserTag(user_tag, current, sample);
2074 } 2118 }
2075 2119
2076 if (tag_order() == Profile::kNoTags) { 2120 if (tag_order() == Profile::kNoTags) {
2077 return current; 2121 return current;
2078 } 2122 }
2079 2123
2080 return AppendUserTag(user_tag, current); 2124 return AppendUserTag(user_tag, current, sample);
2081 } 2125 }
2082 2126
2083 intptr_t GetProfileCodeTagIndex(uword tag) { 2127 intptr_t GetProfileCodeTagIndex(uword tag) {
2084 ProfileCodeTable* tag_table = profile_->tag_code_; 2128 ProfileCodeTable* tag_table = profile_->tag_code_;
2085 intptr_t index = tag_table->FindCodeIndexForPC(tag); 2129 intptr_t index = tag_table->FindCodeIndexForPC(tag);
2086 ASSERT(index >= 0); 2130 ASSERT(index >= 0);
2087 ProfileCode* code = tag_table->At(index); 2131 ProfileCode* code = tag_table->At(index);
2088 ASSERT(code != NULL); 2132 ASSERT(code != NULL);
2089 return code->code_table_index(); 2133 return code->code_table_index();
2090 } 2134 }
(...skipping 629 matching lines...) Expand 10 before | Expand all | Expand 10 after
2720 (sample->allocation_cid() == cls_.id()); 2764 (sample->allocation_cid() == cls_.id());
2721 } 2765 }
2722 2766
2723 private: 2767 private:
2724 const Class& cls_; 2768 const Class& cls_;
2725 }; 2769 };
2726 2770
2727 2771
2728 class NativeAllocationSampleFilter : public SampleFilter { 2772 class NativeAllocationSampleFilter : public SampleFilter {
2729 public: 2773 public:
2730 NativeAllocationSampleFilter(intptr_t thread_task_mask, 2774 NativeAllocationSampleFilter(int64_t time_origin_micros,
2731 int64_t time_origin_micros,
2732 int64_t time_extent_micros) 2775 int64_t time_extent_micros)
2733 : SampleFilter(ILLEGAL_PORT, 2776 : SampleFilter(ILLEGAL_PORT,
2734 thread_task_mask, 2777 SampleFilter::kNoTaskFilter,
2735 time_origin_micros, 2778 time_origin_micros,
2736 time_extent_micros) {} 2779 time_extent_micros) {}
2737 bool FilterSample(Sample* sample) { 2780 bool FilterSample(Sample* sample) {
2738 return sample->is_native_allocation_sample(); 2781 return sample->is_native_allocation_sample() &&
2782 !MallocHooks::NativeAllocationFreed(
2783 reinterpret_cast<void*>(sample->native_allocation_address()));
2739 } 2784 }
2740 }; 2785 };
2741 2786
2742 2787
2743 void ProfilerService::PrintAllocationJSON(JSONStream* stream, 2788 void ProfilerService::PrintAllocationJSON(JSONStream* stream,
2744 Profile::TagOrder tag_order, 2789 Profile::TagOrder tag_order,
2745 const Class& cls, 2790 const Class& cls,
2746 int64_t time_origin_micros, 2791 int64_t time_origin_micros,
2747 int64_t time_extent_micros) { 2792 int64_t time_extent_micros) {
2748 Thread* thread = Thread::Current(); 2793 Thread* thread = Thread::Current();
2749 Isolate* isolate = thread->isolate(); 2794 Isolate* isolate = thread->isolate();
2750 ClassAllocationSampleFilter filter(isolate->main_port(), cls, 2795 ClassAllocationSampleFilter filter(isolate->main_port(), cls,
2751 Thread::kMutatorTask, time_origin_micros, 2796 Thread::kMutatorTask, time_origin_micros,
2752 time_extent_micros); 2797 time_extent_micros);
2753 const bool as_timeline = false; 2798 const bool as_timeline = false;
2754 PrintJSONImpl(thread, stream, tag_order, kNoExtraTags, &filter, as_timeline); 2799 PrintJSONImpl(thread, stream, tag_order, kNoExtraTags, &filter, as_timeline);
2755 } 2800 }
2756 2801
2757 2802
2758 void ProfilerService::PrintNativeAllocationJSON(JSONStream* stream, 2803 void ProfilerService::PrintNativeAllocationJSON(JSONStream* stream,
2759 Profile::TagOrder tag_order, 2804 Profile::TagOrder tag_order,
2760 int64_t time_origin_micros, 2805 int64_t time_origin_micros,
2761 int64_t time_extent_micros) { 2806 int64_t time_extent_micros) {
2762 Thread* thread = Thread::Current(); 2807 Thread* thread = Thread::Current();
2763 const intptr_t thread_task_mask = Thread::kMutatorTask | 2808 NativeAllocationSampleFilter filter(time_origin_micros, time_extent_micros);
2764 Thread::kCompilerTask |
2765 Thread::kSweeperTask | Thread::kMarkerTask;
2766 NativeAllocationSampleFilter filter(thread_task_mask, time_origin_micros,
2767 time_extent_micros);
2768 const bool as_timeline = false; 2809 const bool as_timeline = false;
2769 PrintJSONImpl(thread, stream, tag_order, kNoExtraTags, &filter, as_timeline); 2810 PrintJSONImpl(thread, stream, tag_order, kNoExtraTags, &filter, as_timeline);
2770 } 2811 }
2771 2812
2772 2813
2773 void ProfilerService::PrintTimelineJSON(JSONStream* stream, 2814 void ProfilerService::PrintTimelineJSON(JSONStream* stream,
2774 Profile::TagOrder tag_order, 2815 Profile::TagOrder tag_order,
2775 int64_t time_origin_micros, 2816 int64_t time_origin_micros,
2776 int64_t time_extent_micros) { 2817 int64_t time_extent_micros) {
2777 Thread* thread = Thread::Current(); 2818 Thread* thread = Thread::Current();
(...skipping 20 matching lines...) Expand all
2798 // Disable thread interrupts while processing the buffer. 2839 // Disable thread interrupts while processing the buffer.
2799 DisableThreadInterruptsScope dtis(thread); 2840 DisableThreadInterruptsScope dtis(thread);
2800 2841
2801 ClearProfileVisitor clear_profile(isolate); 2842 ClearProfileVisitor clear_profile(isolate);
2802 sample_buffer->VisitSamples(&clear_profile); 2843 sample_buffer->VisitSamples(&clear_profile);
2803 } 2844 }
2804 2845
2805 #endif // !PRODUCT 2846 #endif // !PRODUCT
2806 2847
2807 } // namespace dart 2848 } // namespace dart
OLDNEW
« runtime/vm/profiler_service.h ('K') | « runtime/vm/profiler_service.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698