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