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

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

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