| 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/native_symbol.h" | 8 #include "vm/native_symbol.h" |
| 9 #include "vm/object.h" | 9 #include "vm/object.h" |
| 10 #include "vm/os.h" | 10 #include "vm/os.h" |
| (...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 497 const char* tag_name = UserTags::TagName(start()); | 497 const char* tag_name = UserTags::TagName(start()); |
| 498 ASSERT(tag_name != NULL); | 498 ASSERT(tag_name != NULL); |
| 499 SetName(tag_name); | 499 SetName(tag_name); |
| 500 } else if (VMTag::IsVMTag(start()) || | 500 } else if (VMTag::IsVMTag(start()) || |
| 501 VMTag::IsRuntimeEntryTag(start()) || | 501 VMTag::IsRuntimeEntryTag(start()) || |
| 502 VMTag::IsNativeEntryTag(start())) { | 502 VMTag::IsNativeEntryTag(start())) { |
| 503 const char* tag_name = VMTag::TagName(start()); | 503 const char* tag_name = VMTag::TagName(start()); |
| 504 ASSERT(tag_name != NULL); | 504 ASSERT(tag_name != NULL); |
| 505 SetName(tag_name); | 505 SetName(tag_name); |
| 506 } else { | 506 } else { |
| 507 ASSERT(start() == 0); | 507 if (start() == VMTag::kRootTagId) { |
| 508 SetName("root"); | 508 SetName("Root"); |
| 509 } else { |
| 510 ASSERT(start() == VMTag::kTruncatedTagId); |
| 511 SetName("[Truncated]"); |
| 512 } |
| 509 } | 513 } |
| 510 } | 514 } |
| 511 function = table->AddTag(start(), name()); | 515 function = table->AddTag(start(), name()); |
| 512 } else { | 516 } else { |
| 513 UNREACHABLE(); | 517 UNREACHABLE(); |
| 514 } | 518 } |
| 515 ASSERT(function != NULL); | 519 ASSERT(function != NULL); |
| 516 // Register this CodeRegion with this function. | 520 // Register this CodeRegion with this function. |
| 517 function->AddCodeObjectIndex(code_table_index()); | 521 function->AddCodeObjectIndex(code_table_index()); |
| 518 profile_function_ = function; | 522 profile_function_ = function; |
| (...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1163 dead_code_table_(dead_code_table), | 1167 dead_code_table_(dead_code_table), |
| 1164 tag_code_table_(tag_code_table), | 1168 tag_code_table_(tag_code_table), |
| 1165 function_table_(function_table) { | 1169 function_table_(function_table) { |
| 1166 ASSERT(isolate_ != NULL); | 1170 ASSERT(isolate_ != NULL); |
| 1167 ASSERT(live_code_table_ != NULL); | 1171 ASSERT(live_code_table_ != NULL); |
| 1168 ASSERT(dead_code_table_ != NULL); | 1172 ASSERT(dead_code_table_ != NULL); |
| 1169 ASSERT(tag_code_table_ != NULL); | 1173 ASSERT(tag_code_table_ != NULL); |
| 1170 dead_code_table_offset_ = live_code_table_->Length(); | 1174 dead_code_table_offset_ = live_code_table_->Length(); |
| 1171 tag_code_table_offset_ = dead_code_table_offset_ + | 1175 tag_code_table_offset_ = dead_code_table_offset_ + |
| 1172 dead_code_table_->Length(); | 1176 dead_code_table_->Length(); |
| 1173 intptr_t root_index = tag_code_table_->FindIndex(0); | 1177 |
| 1174 // Verify that the "0" tag does not exist. | 1178 const Code& null_code = Code::ZoneHandle(); |
| 1179 |
| 1180 // Create the truncated tag. |
| 1181 intptr_t truncated_index = |
| 1182 tag_code_table_->FindIndex(VMTag::kTruncatedTagId); |
| 1183 ASSERT(truncated_index < 0); |
| 1184 CodeRegion* truncated = |
| 1185 new CodeRegion(CodeRegion::kTagCode, |
| 1186 VMTag::kTruncatedTagId, |
| 1187 VMTag::kTruncatedTagId + 1, |
| 1188 0, |
| 1189 null_code); |
| 1190 truncated_index = tag_code_table_->InsertCodeRegion(truncated); |
| 1191 ASSERT(truncated_index >= 0); |
| 1192 truncated->set_creation_serial(0); |
| 1193 |
| 1194 // Create the root tag. |
| 1195 intptr_t root_index = tag_code_table_->FindIndex(VMTag::kRootTagId); |
| 1175 ASSERT(root_index < 0); | 1196 ASSERT(root_index < 0); |
| 1176 // Insert the dummy tag CodeRegion as the root. | 1197 CodeRegion* root = new CodeRegion(CodeRegion::kTagCode, |
| 1177 const Code& null_code = Code::ZoneHandle(); | 1198 VMTag::kRootTagId, |
| 1178 CodeRegion* region = | 1199 VMTag::kRootTagId + 1, |
| 1179 new CodeRegion(CodeRegion::kTagCode, 0, 1, 0, null_code); | 1200 0, |
| 1180 root_index = tag_code_table_->InsertCodeRegion(region); | 1201 null_code); |
| 1202 root_index = tag_code_table_->InsertCodeRegion(root); |
| 1181 ASSERT(root_index >= 0); | 1203 ASSERT(root_index >= 0); |
| 1182 region->set_creation_serial(0); | 1204 root->set_creation_serial(0); |
| 1183 } | 1205 } |
| 1184 | 1206 |
| 1185 void Map() { | 1207 void Map() { |
| 1186 // Calculate final indexes in code table for each CodeRegion. | 1208 // Calculate final indexes in code table for each CodeRegion. |
| 1187 for (intptr_t i = 0; i < live_code_table_->Length(); i++) { | 1209 for (intptr_t i = 0; i < live_code_table_->Length(); i++) { |
| 1188 const intptr_t index = i; | 1210 const intptr_t index = i; |
| 1189 CodeRegion* region = live_code_table_->At(i); | 1211 CodeRegion* region = live_code_table_->At(i); |
| 1190 ASSERT(region != NULL); | 1212 ASSERT(region != NULL); |
| 1191 region->set_code_table_index(index); | 1213 region->set_code_table_index(index); |
| 1192 } | 1214 } |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1392 function_table_(function_table), | 1414 function_table_(function_table), |
| 1393 inclusive_(false), | 1415 inclusive_(false), |
| 1394 trace_(false), | 1416 trace_(false), |
| 1395 trace_code_filter_(NULL) { | 1417 trace_code_filter_(NULL) { |
| 1396 ASSERT(live_code_table_ != NULL); | 1418 ASSERT(live_code_table_ != NULL); |
| 1397 ASSERT(dead_code_table_ != NULL); | 1419 ASSERT(dead_code_table_ != NULL); |
| 1398 ASSERT(tag_code_table_ != NULL); | 1420 ASSERT(tag_code_table_ != NULL); |
| 1399 ASSERT(function_table_ != NULL); | 1421 ASSERT(function_table_ != NULL); |
| 1400 set_tag_order(ProfilerService::kUserVM); | 1422 set_tag_order(ProfilerService::kUserVM); |
| 1401 | 1423 |
| 1402 intptr_t root_index = tag_code_table_->FindIndex(0); | 1424 // Verify that the truncated tag exists. |
| 1403 // Verify that the "0" tag does exist. | 1425 ASSERT(tag_code_table_->FindIndex(VMTag::kTruncatedTagId) >= 0); |
| 1426 |
| 1427 // Verify that the root tag exists. |
| 1428 intptr_t root_index = tag_code_table_->FindIndex(VMTag::kRootTagId); |
| 1404 ASSERT(root_index >= 0); | 1429 ASSERT(root_index >= 0); |
| 1430 |
| 1431 // Setup root. |
| 1405 CodeRegion* region = tag_code_table_->At(root_index); | 1432 CodeRegion* region = tag_code_table_->At(root_index); |
| 1406 ASSERT(region != NULL); | 1433 ASSERT(region != NULL); |
| 1407 ProfileFunction* function = region->function(); | 1434 ProfileFunction* function = region->function(); |
| 1408 ASSERT(function != NULL); | 1435 ASSERT(function != NULL); |
| 1409 | 1436 |
| 1410 exclusive_root_ = new ProfileFunctionTrieNode(function->index()); | 1437 exclusive_root_ = new ProfileFunctionTrieNode(function->index()); |
| 1411 inclusive_root_ = new ProfileFunctionTrieNode(function->index()); | 1438 inclusive_root_ = new ProfileFunctionTrieNode(function->index()); |
| 1412 } | 1439 } |
| 1413 | 1440 |
| 1414 void VisitSample(Sample* sample) { | 1441 void VisitSample(Sample* sample) { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1432 | 1459 |
| 1433 void set_tag_order(ProfilerService::TagOrder tag_order) { | 1460 void set_tag_order(ProfilerService::TagOrder tag_order) { |
| 1434 tag_order_ = tag_order; | 1461 tag_order_ = tag_order; |
| 1435 } | 1462 } |
| 1436 | 1463 |
| 1437 private: | 1464 private: |
| 1438 void ProcessSampleInclusive(Sample* sample) { | 1465 void ProcessSampleInclusive(Sample* sample) { |
| 1439 // Give the root a tick. | 1466 // Give the root a tick. |
| 1440 inclusive_root_->Tick(); | 1467 inclusive_root_->Tick(); |
| 1441 ProfileFunctionTrieNode* current = inclusive_root_; | 1468 ProfileFunctionTrieNode* current = inclusive_root_; |
| 1442 current = ProcessTags(sample, current); | 1469 current = AppendTags(sample, current); |
| 1470 if (sample->truncated_trace()) { |
| 1471 current = AppendTruncatedTag(current); |
| 1472 } |
| 1443 // Walk the sampled PCs. | 1473 // Walk the sampled PCs. |
| 1444 for (intptr_t i = FLAG_profile_depth - 1; i >= 0; i--) { | 1474 for (intptr_t i = FLAG_profile_depth - 1; i >= 0; i--) { |
| 1445 if (sample->At(i) == 0) { | 1475 if (sample->At(i) == 0) { |
| 1446 continue; | 1476 continue; |
| 1447 } | 1477 } |
| 1448 // If we aren't sampled out of an exit frame and this is the top | 1478 // If we aren't sampled out of an exit frame and this is the top |
| 1449 // frame. | 1479 // frame. |
| 1450 bool exclusive_tick = (i == 0) && !sample->exit_frame_sample(); | 1480 bool exclusive_tick = (i == 0) && !sample->exit_frame_sample(); |
| 1451 current = ProcessPC(sample->At(i), sample->timestamp(), current, | 1481 current = ProcessPC(sample->At(i), sample->timestamp(), current, |
| 1452 visited(), exclusive_tick, | 1482 visited(), exclusive_tick, |
| 1453 sample->missing_frame_inserted()); | 1483 sample->missing_frame_inserted()); |
| 1454 } | 1484 } |
| 1455 } | 1485 } |
| 1456 | 1486 |
| 1457 void ProcessSampleExclusive(Sample* sample) { | 1487 void ProcessSampleExclusive(Sample* sample) { |
| 1458 // Give the root a tick. | 1488 // Give the root a tick. |
| 1459 exclusive_root_->Tick(); | 1489 exclusive_root_->Tick(); |
| 1460 ProfileFunctionTrieNode* current = exclusive_root_; | 1490 ProfileFunctionTrieNode* current = exclusive_root_; |
| 1461 current = ProcessTags(sample, current); | 1491 current = AppendTags(sample, current); |
| 1462 // Walk the sampled PCs. | 1492 // Walk the sampled PCs. |
| 1463 for (intptr_t i = 0; i < FLAG_profile_depth; i++) { | 1493 for (intptr_t i = 0; i < FLAG_profile_depth; i++) { |
| 1464 if (sample->At(i) == 0) { | 1494 if (sample->At(i) == 0) { |
| 1465 break; | 1495 break; |
| 1466 } | 1496 } |
| 1467 // If we aren't sampled out of an exit frame and this is the top | 1497 // If we aren't sampled out of an exit frame and this is the top |
| 1468 // frame. | 1498 // frame. |
| 1469 bool exclusive_tick = (i == 0) && !sample->exit_frame_sample(); | 1499 bool exclusive_tick = (i == 0) && !sample->exit_frame_sample(); |
| 1470 current = ProcessPC(sample->At(i), sample->timestamp(), current, | 1500 current = ProcessPC(sample->At(i), sample->timestamp(), current, |
| 1471 visited(), exclusive_tick, | 1501 visited(), exclusive_tick, |
| 1472 sample->missing_frame_inserted()); | 1502 sample->missing_frame_inserted()); |
| 1473 } | 1503 } |
| 1504 if (sample->truncated_trace()) { |
| 1505 current = AppendTruncatedTag(current); |
| 1506 } |
| 1474 } | 1507 } |
| 1475 | 1508 |
| 1476 ProfileFunctionTrieNode* ProcessUserTags(Sample* sample, | 1509 ProfileFunctionTrieNode* AppendUserTag(Sample* sample, |
| 1477 ProfileFunctionTrieNode* current) { | 1510 ProfileFunctionTrieNode* current) { |
| 1478 intptr_t user_tag_index = FindTagIndex(sample->user_tag()); | 1511 intptr_t user_tag_index = FindTagIndex(sample->user_tag()); |
| 1479 if (user_tag_index >= 0) { | 1512 if (user_tag_index >= 0) { |
| 1480 current = current->GetChild(user_tag_index); | 1513 current = current->GetChild(user_tag_index); |
| 1481 // Give the tag a tick. | 1514 // Give the tag a tick. |
| 1482 current->Tick(); | 1515 current->Tick(); |
| 1483 } | 1516 } |
| 1484 return current; | 1517 return current; |
| 1485 } | 1518 } |
| 1486 | 1519 |
| 1487 ProfileFunctionTrieNode* ProcessVMTags(Sample* sample, | 1520 |
| 1488 ProfileFunctionTrieNode* current) { | 1521 ProfileFunctionTrieNode* AppendTruncatedTag( |
| 1522 ProfileFunctionTrieNode* current) { |
| 1523 intptr_t truncated_tag_index = FindTagIndex(VMTag::kTruncatedTagId); |
| 1524 ASSERT(truncated_tag_index >= 0); |
| 1525 current = current->GetChild(truncated_tag_index); |
| 1526 current->Tick(); |
| 1527 return current; |
| 1528 } |
| 1529 |
| 1530 |
| 1531 ProfileFunctionTrieNode* AppendVMTag(Sample* sample, |
| 1532 ProfileFunctionTrieNode* current) { |
| 1489 if (VMTag::IsNativeEntryTag(sample->vm_tag())) { | 1533 if (VMTag::IsNativeEntryTag(sample->vm_tag())) { |
| 1490 // Insert a dummy kNativeTagId node. | 1534 // Insert a dummy kNativeTagId node. |
| 1491 intptr_t tag_index = FindTagIndex(VMTag::kNativeTagId); | 1535 intptr_t tag_index = FindTagIndex(VMTag::kNativeTagId); |
| 1492 current = current->GetChild(tag_index); | 1536 current = current->GetChild(tag_index); |
| 1493 // Give the tag a tick. | 1537 // Give the tag a tick. |
| 1494 current->Tick(); | 1538 current->Tick(); |
| 1495 } else if (VMTag::IsRuntimeEntryTag(sample->vm_tag())) { | 1539 } else if (VMTag::IsRuntimeEntryTag(sample->vm_tag())) { |
| 1496 // Insert a dummy kRuntimeTagId node. | 1540 // Insert a dummy kRuntimeTagId node. |
| 1497 intptr_t tag_index = FindTagIndex(VMTag::kRuntimeTagId); | 1541 intptr_t tag_index = FindTagIndex(VMTag::kRuntimeTagId); |
| 1498 current = current->GetChild(tag_index); | 1542 current = current->GetChild(tag_index); |
| 1499 // Give the tag a tick. | 1543 // Give the tag a tick. |
| 1500 current->Tick(); | 1544 current->Tick(); |
| 1545 } else { |
| 1546 intptr_t tag_index = FindTagIndex(sample->vm_tag()); |
| 1547 current = current->GetChild(tag_index); |
| 1548 // Give the tag a tick. |
| 1549 current->Tick(); |
| 1501 } | 1550 } |
| 1551 return current; |
| 1552 } |
| 1553 |
| 1554 ProfileFunctionTrieNode* AppendSpecificNativeRuntimeEntryVMTag( |
| 1555 Sample* sample, ProfileFunctionTrieNode* current) { |
| 1556 // Only Native and Runtime entries have a second VM tag. |
| 1557 if (!VMTag::IsNativeEntryTag(sample->vm_tag()) && |
| 1558 !VMTag::IsRuntimeEntryTag(sample->vm_tag())) { |
| 1559 return current; |
| 1560 } |
| 1502 intptr_t tag_index = FindTagIndex(sample->vm_tag()); | 1561 intptr_t tag_index = FindTagIndex(sample->vm_tag()); |
| 1503 current = current->GetChild(tag_index); | 1562 current = current->GetChild(tag_index); |
| 1504 // Give the tag a tick. | 1563 // Give the tag a tick. |
| 1505 current->Tick(); | 1564 current->Tick(); |
| 1506 return current; | 1565 return current; |
| 1507 } | 1566 } |
| 1508 | 1567 |
| 1509 ProfileFunctionTrieNode* ProcessTags(Sample* sample, | 1568 ProfileFunctionTrieNode* AppendVMTags(Sample* sample, |
| 1510 ProfileFunctionTrieNode* current) { | 1569 ProfileFunctionTrieNode* current) { |
| 1570 current = AppendVMTag(sample, current); |
| 1571 current = AppendSpecificNativeRuntimeEntryVMTag(sample, current); |
| 1572 return current; |
| 1573 } |
| 1574 |
| 1575 ProfileFunctionTrieNode* AppendTags(Sample* sample, |
| 1576 ProfileFunctionTrieNode* current) { |
| 1511 // None. | 1577 // None. |
| 1512 if (tag_order() == ProfilerService::kNoTags) { | 1578 if (tag_order() == ProfilerService::kNoTags) { |
| 1513 return current; | 1579 return current; |
| 1514 } | 1580 } |
| 1515 // User first. | 1581 // User first. |
| 1516 if ((tag_order() == ProfilerService::kUserVM) || | 1582 if ((tag_order() == ProfilerService::kUserVM) || |
| 1517 (tag_order() == ProfilerService::kUser)) { | 1583 (tag_order() == ProfilerService::kUser)) { |
| 1518 current = ProcessUserTags(sample, current); | 1584 current = AppendUserTag(sample, current); |
| 1519 // Only user. | 1585 // Only user. |
| 1520 if (tag_order() == ProfilerService::kUser) { | 1586 if (tag_order() == ProfilerService::kUser) { |
| 1521 return current; | 1587 return current; |
| 1522 } | 1588 } |
| 1523 return ProcessVMTags(sample, current); | 1589 return AppendVMTags(sample, current); |
| 1524 } | 1590 } |
| 1525 // VM first. | 1591 // VM first. |
| 1526 ASSERT((tag_order() == ProfilerService::kVMUser) || | 1592 ASSERT((tag_order() == ProfilerService::kVMUser) || |
| 1527 (tag_order() == ProfilerService::kVM)); | 1593 (tag_order() == ProfilerService::kVM)); |
| 1528 current = ProcessVMTags(sample, current); | 1594 current = AppendVMTags(sample, current); |
| 1529 // Only VM. | 1595 // Only VM. |
| 1530 if (tag_order() == ProfilerService::kVM) { | 1596 if (tag_order() == ProfilerService::kVM) { |
| 1531 return current; | 1597 return current; |
| 1532 } | 1598 } |
| 1533 return ProcessUserTags(sample, current); | 1599 return AppendUserTag(sample, current); |
| 1534 } | 1600 } |
| 1535 | 1601 |
| 1536 intptr_t FindTagIndex(uword tag) const { | 1602 intptr_t FindTagIndex(uword tag) const { |
| 1537 if (tag == 0) { | 1603 if (tag == 0) { |
| 1538 UNREACHABLE(); | 1604 UNREACHABLE(); |
| 1539 return -1; | 1605 return -1; |
| 1540 } | 1606 } |
| 1541 intptr_t index = tag_code_table_->FindIndex(tag); | 1607 intptr_t index = tag_code_table_->FindIndex(tag); |
| 1542 if (index < 0) { | 1608 if (index < 0) { |
| 1543 UNREACHABLE(); | 1609 UNREACHABLE(); |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1789 CodeRegionTable* tag_code_table) | 1855 CodeRegionTable* tag_code_table) |
| 1790 : SampleVisitor(isolate), | 1856 : SampleVisitor(isolate), |
| 1791 live_code_table_(live_code_table), | 1857 live_code_table_(live_code_table), |
| 1792 dead_code_table_(dead_code_table), | 1858 dead_code_table_(dead_code_table), |
| 1793 tag_code_table_(tag_code_table) { | 1859 tag_code_table_(tag_code_table) { |
| 1794 ASSERT(live_code_table_ != NULL); | 1860 ASSERT(live_code_table_ != NULL); |
| 1795 ASSERT(dead_code_table_ != NULL); | 1861 ASSERT(dead_code_table_ != NULL); |
| 1796 ASSERT(tag_code_table_ != NULL); | 1862 ASSERT(tag_code_table_ != NULL); |
| 1797 set_tag_order(ProfilerService::kUserVM); | 1863 set_tag_order(ProfilerService::kUserVM); |
| 1798 | 1864 |
| 1799 intptr_t root_index = tag_code_table_->FindIndex(0); | 1865 // Verify that the truncated tag exists. |
| 1800 // Verify that the "0" (root) tag does exist. | 1866 ASSERT(tag_code_table_->FindIndex(VMTag::kTruncatedTagId) >= 0); |
| 1867 |
| 1868 // Verify that the root tag exists. |
| 1869 intptr_t root_index = tag_code_table_->FindIndex(VMTag::kRootTagId); |
| 1801 ASSERT(root_index >= 0); | 1870 ASSERT(root_index >= 0); |
| 1802 CodeRegion* region = tag_code_table_->At(root_index); | 1871 CodeRegion* region = tag_code_table_->At(root_index); |
| 1803 ASSERT(region != NULL); | 1872 ASSERT(region != NULL); |
| 1804 | 1873 |
| 1805 exclusive_root_ = new CodeRegionTrieNode(region->code_table_index()); | 1874 exclusive_root_ = new CodeRegionTrieNode(region->code_table_index()); |
| 1806 inclusive_root_ = new CodeRegionTrieNode(region->code_table_index()); | 1875 inclusive_root_ = new CodeRegionTrieNode(region->code_table_index()); |
| 1807 } | 1876 } |
| 1808 | 1877 |
| 1809 void VisitSample(Sample* sample) { | 1878 void VisitSample(Sample* sample) { |
| 1810 ProcessSampleExclusive(sample); | 1879 ProcessSampleExclusive(sample); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1825 | 1894 |
| 1826 void set_tag_order(ProfilerService::TagOrder tag_order) { | 1895 void set_tag_order(ProfilerService::TagOrder tag_order) { |
| 1827 tag_order_ = tag_order; | 1896 tag_order_ = tag_order; |
| 1828 } | 1897 } |
| 1829 | 1898 |
| 1830 private: | 1899 private: |
| 1831 void ProcessSampleInclusive(Sample* sample) { | 1900 void ProcessSampleInclusive(Sample* sample) { |
| 1832 // Give the root a tick. | 1901 // Give the root a tick. |
| 1833 inclusive_root_->Tick(); | 1902 inclusive_root_->Tick(); |
| 1834 CodeRegionTrieNode* current = inclusive_root_; | 1903 CodeRegionTrieNode* current = inclusive_root_; |
| 1835 current = ProcessTags(sample, current); | 1904 current = AppendTags(sample, current); |
| 1905 if (sample->truncated_trace()) { |
| 1906 current = AppendTruncatedTag(current); |
| 1907 } |
| 1836 // Walk the sampled PCs. | 1908 // Walk the sampled PCs. |
| 1837 for (intptr_t i = FLAG_profile_depth - 1; i >= 0; i--) { | 1909 for (intptr_t i = FLAG_profile_depth - 1; i >= 0; i--) { |
| 1838 if (sample->At(i) == 0) { | 1910 if (sample->At(i) == 0) { |
| 1839 continue; | 1911 continue; |
| 1840 } | 1912 } |
| 1841 intptr_t index = FindFinalIndex(sample->At(i), sample->timestamp()); | 1913 intptr_t index = FindFinalIndex(sample->At(i), sample->timestamp()); |
| 1842 if (index < 0) { | 1914 if (index < 0) { |
| 1843 continue; | 1915 continue; |
| 1844 } | 1916 } |
| 1845 current = current->GetChild(index); | 1917 current = current->GetChild(index); |
| 1846 current->Tick(); | 1918 current->Tick(); |
| 1847 } | 1919 } |
| 1848 } | 1920 } |
| 1849 | 1921 |
| 1850 void ProcessSampleExclusive(Sample* sample) { | 1922 void ProcessSampleExclusive(Sample* sample) { |
| 1851 // Give the root a tick. | 1923 // Give the root a tick. |
| 1852 exclusive_root_->Tick(); | 1924 exclusive_root_->Tick(); |
| 1853 CodeRegionTrieNode* current = exclusive_root_; | 1925 CodeRegionTrieNode* current = exclusive_root_; |
| 1854 current = ProcessTags(sample, current); | 1926 current = AppendTags(sample, current); |
| 1855 // Walk the sampled PCs. | 1927 // Walk the sampled PCs. |
| 1856 for (intptr_t i = 0; i < FLAG_profile_depth; i++) { | 1928 for (intptr_t i = 0; i < FLAG_profile_depth; i++) { |
| 1857 if (sample->At(i) == 0) { | 1929 if (sample->At(i) == 0) { |
| 1858 break; | 1930 break; |
| 1859 } | 1931 } |
| 1860 intptr_t index = FindFinalIndex(sample->At(i), sample->timestamp()); | 1932 intptr_t index = FindFinalIndex(sample->At(i), sample->timestamp()); |
| 1861 if (index < 0) { | 1933 if (index < 0) { |
| 1862 continue; | 1934 continue; |
| 1863 } | 1935 } |
| 1864 current = current->GetChild(index); | 1936 current = current->GetChild(index); |
| 1865 current->Tick(); | 1937 current->Tick(); |
| 1866 } | 1938 } |
| 1939 if (sample->truncated_trace()) { |
| 1940 current = AppendTruncatedTag(current); |
| 1941 } |
| 1867 } | 1942 } |
| 1868 | 1943 |
| 1869 CodeRegionTrieNode* ProcessUserTags(Sample* sample, | 1944 CodeRegionTrieNode* AppendUserTag(Sample* sample, |
| 1870 CodeRegionTrieNode* current) { | 1945 CodeRegionTrieNode* current) { |
| 1871 intptr_t user_tag_index = FindTagIndex(sample->user_tag()); | 1946 intptr_t user_tag_index = FindTagIndex(sample->user_tag()); |
| 1872 if (user_tag_index >= 0) { | 1947 if (user_tag_index >= 0) { |
| 1873 current = current->GetChild(user_tag_index); | 1948 current = current->GetChild(user_tag_index); |
| 1874 // Give the tag a tick. | 1949 // Give the tag a tick. |
| 1875 current->Tick(); | 1950 current->Tick(); |
| 1876 } | 1951 } |
| 1877 return current; | 1952 return current; |
| 1878 } | 1953 } |
| 1879 | 1954 |
| 1880 CodeRegionTrieNode* ProcessVMTags(Sample* sample, | 1955 CodeRegionTrieNode* AppendTruncatedTag(CodeRegionTrieNode* current) { |
| 1881 CodeRegionTrieNode* current) { | 1956 intptr_t truncated_tag_index = FindTagIndex(VMTag::kTruncatedTagId); |
| 1957 ASSERT(truncated_tag_index >= 0); |
| 1958 current = current->GetChild(truncated_tag_index); |
| 1959 current->Tick(); |
| 1960 return current; |
| 1961 } |
| 1962 |
| 1963 CodeRegionTrieNode* AppendVMTag(Sample* sample, |
| 1964 CodeRegionTrieNode* current) { |
| 1882 if (VMTag::IsNativeEntryTag(sample->vm_tag())) { | 1965 if (VMTag::IsNativeEntryTag(sample->vm_tag())) { |
| 1883 // Insert a dummy kNativeTagId node. | 1966 // Insert a dummy kNativeTagId node. |
| 1884 intptr_t tag_index = FindTagIndex(VMTag::kNativeTagId); | 1967 intptr_t tag_index = FindTagIndex(VMTag::kNativeTagId); |
| 1885 current = current->GetChild(tag_index); | 1968 current = current->GetChild(tag_index); |
| 1886 // Give the tag a tick. | 1969 // Give the tag a tick. |
| 1887 current->Tick(); | 1970 current->Tick(); |
| 1888 } else if (VMTag::IsRuntimeEntryTag(sample->vm_tag())) { | 1971 } else if (VMTag::IsRuntimeEntryTag(sample->vm_tag())) { |
| 1889 // Insert a dummy kRuntimeTagId node. | 1972 // Insert a dummy kRuntimeTagId node. |
| 1890 intptr_t tag_index = FindTagIndex(VMTag::kRuntimeTagId); | 1973 intptr_t tag_index = FindTagIndex(VMTag::kRuntimeTagId); |
| 1891 current = current->GetChild(tag_index); | 1974 current = current->GetChild(tag_index); |
| 1892 // Give the tag a tick. | 1975 // Give the tag a tick. |
| 1893 current->Tick(); | 1976 current->Tick(); |
| 1977 } else { |
| 1978 intptr_t tag_index = FindTagIndex(sample->vm_tag()); |
| 1979 current = current->GetChild(tag_index); |
| 1980 // Give the tag a tick. |
| 1981 current->Tick(); |
| 1894 } | 1982 } |
| 1983 return current; |
| 1984 } |
| 1985 |
| 1986 CodeRegionTrieNode* AppendSpecificNativeRuntimeEntryVMTag( |
| 1987 Sample* sample, CodeRegionTrieNode* current) { |
| 1988 // Only Native and Runtime entries have a second VM tag. |
| 1989 if (!VMTag::IsNativeEntryTag(sample->vm_tag()) && |
| 1990 !VMTag::IsRuntimeEntryTag(sample->vm_tag())) { |
| 1991 return current; |
| 1992 } |
| 1895 intptr_t tag_index = FindTagIndex(sample->vm_tag()); | 1993 intptr_t tag_index = FindTagIndex(sample->vm_tag()); |
| 1896 current = current->GetChild(tag_index); | 1994 current = current->GetChild(tag_index); |
| 1897 // Give the tag a tick. | 1995 // Give the tag a tick. |
| 1898 current->Tick(); | 1996 current->Tick(); |
| 1899 return current; | 1997 return current; |
| 1900 } | 1998 } |
| 1901 | 1999 |
| 1902 CodeRegionTrieNode* ProcessTags(Sample* sample, CodeRegionTrieNode* current) { | 2000 CodeRegionTrieNode* AppendVMTags(Sample* sample, |
| 2001 CodeRegionTrieNode* current) { |
| 2002 current = AppendVMTag(sample, current); |
| 2003 current = AppendSpecificNativeRuntimeEntryVMTag(sample, current); |
| 2004 return current; |
| 2005 } |
| 2006 |
| 2007 CodeRegionTrieNode* AppendTags(Sample* sample, CodeRegionTrieNode* current) { |
| 1903 // None. | 2008 // None. |
| 1904 if (tag_order() == ProfilerService::kNoTags) { | 2009 if (tag_order() == ProfilerService::kNoTags) { |
| 1905 return current; | 2010 return current; |
| 1906 } | 2011 } |
| 1907 // User first. | 2012 // User first. |
| 1908 if ((tag_order() == ProfilerService::kUserVM) || | 2013 if ((tag_order() == ProfilerService::kUserVM) || |
| 1909 (tag_order() == ProfilerService::kUser)) { | 2014 (tag_order() == ProfilerService::kUser)) { |
| 1910 current = ProcessUserTags(sample, current); | 2015 current = AppendUserTag(sample, current); |
| 1911 // Only user. | 2016 // Only user. |
| 1912 if (tag_order() == ProfilerService::kUser) { | 2017 if (tag_order() == ProfilerService::kUser) { |
| 1913 return current; | 2018 return current; |
| 1914 } | 2019 } |
| 1915 return ProcessVMTags(sample, current); | 2020 return AppendVMTags(sample, current); |
| 1916 } | 2021 } |
| 1917 // VM first. | 2022 // VM first. |
| 1918 ASSERT((tag_order() == ProfilerService::kVMUser) || | 2023 ASSERT((tag_order() == ProfilerService::kVMUser) || |
| 1919 (tag_order() == ProfilerService::kVM)); | 2024 (tag_order() == ProfilerService::kVM)); |
| 1920 current = ProcessVMTags(sample, current); | 2025 current = AppendVMTags(sample, current); |
| 1921 // Only VM. | 2026 // Only VM. |
| 1922 if (tag_order() == ProfilerService::kVM) { | 2027 if (tag_order() == ProfilerService::kVM) { |
| 1923 return current; | 2028 return current; |
| 1924 } | 2029 } |
| 1925 return ProcessUserTags(sample, current); | 2030 return AppendUserTag(sample, current); |
| 1926 } | 2031 } |
| 1927 | 2032 |
| 1928 intptr_t FindTagIndex(uword tag) const { | 2033 intptr_t FindTagIndex(uword tag) const { |
| 1929 if (tag == 0) { | 2034 if (tag == 0) { |
| 1930 UNREACHABLE(); | 2035 UNREACHABLE(); |
| 1931 return -1; | 2036 return -1; |
| 1932 } | 2037 } |
| 1933 intptr_t index = tag_code_table_->FindIndex(tag); | 2038 intptr_t index = tag_code_table_->FindIndex(tag); |
| 1934 if (index < 0) { | 2039 if (index < 0) { |
| 1935 UNREACHABLE(); | 2040 UNREACHABLE(); |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2172 ASSERT(sample_buffer != NULL); | 2277 ASSERT(sample_buffer != NULL); |
| 2173 | 2278 |
| 2174 ClearProfileVisitor clear_profile(isolate); | 2279 ClearProfileVisitor clear_profile(isolate); |
| 2175 sample_buffer->VisitSamples(&clear_profile); | 2280 sample_buffer->VisitSamples(&clear_profile); |
| 2176 | 2281 |
| 2177 // Enable profile interrupts. | 2282 // Enable profile interrupts. |
| 2178 Profiler::BeginExecution(isolate); | 2283 Profiler::BeginExecution(isolate); |
| 2179 } | 2284 } |
| 2180 | 2285 |
| 2181 } // namespace dart | 2286 } // namespace dart |
| OLD | NEW |