| OLD | NEW | 
|     1 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file |     1 // Copyright (c) 2013, 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 "platform/utils.h" |     5 #include "platform/utils.h" | 
|     6  |     6  | 
|     7 #include "vm/allocation.h" |     7 #include "vm/allocation.h" | 
|     8 #include "vm/atomic.h" |     8 #include "vm/atomic.h" | 
|     9 #include "vm/code_patcher.h" |     9 #include "vm/code_patcher.h" | 
|    10 #include "vm/isolate.h" |    10 #include "vm/isolate.h" | 
| (...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   559       } |   559       } | 
|   560       PrintCollectedCode(&obj); |   560       PrintCollectedCode(&obj); | 
|   561     } else if (kind() == kReusedCode) { |   561     } else if (kind() == kReusedCode) { | 
|   562       if (name() == NULL) { |   562       if (name() == NULL) { | 
|   563         // Lazily set generated name. |   563         // Lazily set generated name. | 
|   564         GenerateAndSetSymbolName("[Reused]"); |   564         GenerateAndSetSymbolName("[Reused]"); | 
|   565       } |   565       } | 
|   566       PrintOverwrittenCode(&obj); |   566       PrintOverwrittenCode(&obj); | 
|   567     } else if (kind() == kTagCode) { |   567     } else if (kind() == kTagCode) { | 
|   568       if (name() == NULL) { |   568       if (name() == NULL) { | 
|   569         const char* tag_name = start() == 0 ? "root" : VMTag::TagName(start()); |   569         if (UserTags::IsUserTag(start())) { | 
|   570         ASSERT(tag_name != NULL); |   570           const char* tag_name = UserTags::TagName(start()); | 
|   571         SetName(tag_name); |   571           ASSERT(tag_name != NULL); | 
 |   572           SetName(tag_name); | 
 |   573         } else if (VMTag::IsVMTag(start()) || | 
 |   574                    VMTag::IsRuntimeEntryTag(start()) || | 
 |   575                    VMTag::IsNativeEntryTag(start())) { | 
 |   576           const char* tag_name = VMTag::TagName(start()); | 
 |   577           ASSERT(tag_name != NULL); | 
 |   578           SetName(tag_name); | 
 |   579         } else { | 
 |   580           ASSERT(start() == 0); | 
 |   581           SetName("root"); | 
 |   582         } | 
|   572       } |   583       } | 
|   573       PrintTagCode(&obj); |   584       PrintTagCode(&obj); | 
|   574     } else { |   585     } else { | 
|   575       ASSERT(kind() == kNativeCode); |   586       ASSERT(kind() == kNativeCode); | 
|   576       if (name() == NULL) { |   587       if (name() == NULL) { | 
|   577         // Lazily set generated name. |   588         // Lazily set generated name. | 
|   578         GenerateAndSetSymbolName("[Native]"); |   589         GenerateAndSetSymbolName("[Native]"); | 
|   579       } |   590       } | 
|   580       PrintNativeCode(&obj); |   591       PrintNativeCode(&obj); | 
|   581     } |   592     } | 
| (...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   927     if (timestamp < min_time_) { |   938     if (timestamp < min_time_) { | 
|   928       min_time_ = timestamp; |   939       min_time_ = timestamp; | 
|   929     } |   940     } | 
|   930     // Make sure VM tag is created. |   941     // Make sure VM tag is created. | 
|   931     if (VMTag::IsNativeEntryTag(sample->vm_tag())) { |   942     if (VMTag::IsNativeEntryTag(sample->vm_tag())) { | 
|   932       CreateTag(VMTag::kNativeTagId); |   943       CreateTag(VMTag::kNativeTagId); | 
|   933     } else if (VMTag::IsRuntimeEntryTag(sample->vm_tag())) { |   944     } else if (VMTag::IsRuntimeEntryTag(sample->vm_tag())) { | 
|   934       CreateTag(VMTag::kRuntimeTagId); |   945       CreateTag(VMTag::kRuntimeTagId); | 
|   935     } |   946     } | 
|   936     CreateTag(sample->vm_tag()); |   947     CreateTag(sample->vm_tag()); | 
 |   948     // Make sure user tag is created. | 
 |   949     CreateUserTag(sample->user_tag()); | 
|   937     // Exclusive tick for bottom frame. |   950     // Exclusive tick for bottom frame. | 
|   938     Tick(sample->At(0), true, timestamp); |   951     Tick(sample->At(0), true, timestamp); | 
|   939     // Inclusive tick for all frames. |   952     // Inclusive tick for all frames. | 
|   940     for (intptr_t i = 0; i < FLAG_profile_depth; i++) { |   953     for (intptr_t i = 0; i < FLAG_profile_depth; i++) { | 
|   941       if (sample->At(i) == 0) { |   954       if (sample->At(i) == 0) { | 
|   942         break; |   955         break; | 
|   943       } |   956       } | 
|   944       frames_++; |   957       frames_++; | 
|   945       Tick(sample->At(i), false, timestamp); |   958       Tick(sample->At(i), false, timestamp); | 
|   946     } |   959     } | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
|   962     } |   975     } | 
|   963     CodeRegion* region = new CodeRegion(CodeRegion::kTagCode, |   976     CodeRegion* region = new CodeRegion(CodeRegion::kTagCode, | 
|   964                                         tag, |   977                                         tag, | 
|   965                                         tag + 1, |   978                                         tag + 1, | 
|   966                                         0); |   979                                         0); | 
|   967     index = tag_code_table_->InsertCodeRegion(region); |   980     index = tag_code_table_->InsertCodeRegion(region); | 
|   968     ASSERT(index >= 0); |   981     ASSERT(index >= 0); | 
|   969     region->set_creation_serial(visited()); |   982     region->set_creation_serial(visited()); | 
|   970   } |   983   } | 
|   971  |   984  | 
 |   985   void CreateUserTag(uword tag) { | 
 |   986     if (tag == 0) { | 
 |   987       // None set. | 
 |   988       return; | 
 |   989     } | 
 |   990     intptr_t index = tag_code_table_->FindIndex(tag); | 
 |   991     if (index >= 0) { | 
 |   992       // Already created. | 
 |   993       return; | 
 |   994     } | 
 |   995     CodeRegion* region = new CodeRegion(CodeRegion::kTagCode, | 
 |   996                                         tag, | 
 |   997                                         tag + 1, | 
 |   998                                         0); | 
 |   999     index = tag_code_table_->InsertCodeRegion(region); | 
 |  1000     ASSERT(index >= 0); | 
 |  1001     region->set_creation_serial(visited()); | 
 |  1002   } | 
 |  1003  | 
|   972   void Tick(uword pc, bool exclusive, int64_t timestamp) { |  1004   void Tick(uword pc, bool exclusive, int64_t timestamp) { | 
|   973     CodeRegionTable::TickResult r; |  1005     CodeRegionTable::TickResult r; | 
|   974     intptr_t serial = exclusive ? -1 : visited(); |  1006     intptr_t serial = exclusive ? -1 : visited(); | 
|   975     r = live_code_table_->Tick(pc, exclusive, serial, timestamp); |  1007     r = live_code_table_->Tick(pc, exclusive, serial, timestamp); | 
|   976     if (r == CodeRegionTable::kTicked) { |  1008     if (r == CodeRegionTable::kTicked) { | 
|   977       // Live code found and ticked. |  1009       // Live code found and ticked. | 
|   978       return; |  1010       return; | 
|   979     } |  1011     } | 
|   980     if (r == CodeRegionTable::kNewerCode) { |  1012     if (r == CodeRegionTable::kNewerCode) { | 
|   981       // Code has been overwritten by newer code. |  1013       // Code has been overwritten by newer code. | 
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1101     root_ = new CodeRegionTrieNode(tag_code_table_offset_ + root_index); |  1133     root_ = new CodeRegionTrieNode(tag_code_table_offset_ + root_index); | 
|  1102     // Use tags by default. |  1134     // Use tags by default. | 
|  1103     set_use_tags(true); |  1135     set_use_tags(true); | 
|  1104   } |  1136   } | 
|  1105  |  1137  | 
|  1106   void VisitSample(Sample* sample) { |  1138   void VisitSample(Sample* sample) { | 
|  1107     // Give the root a tick. |  1139     // Give the root a tick. | 
|  1108     root_->Tick(); |  1140     root_->Tick(); | 
|  1109     CodeRegionTrieNode* current = root_; |  1141     CodeRegionTrieNode* current = root_; | 
|  1110     if (use_tags()) { |  1142     if (use_tags()) { | 
 |  1143       intptr_t user_tag_index = FindTagIndex(sample->user_tag()); | 
 |  1144       if (user_tag_index >= 0) { | 
 |  1145         current = current->GetChild(user_tag_index); | 
 |  1146         // Give the tag a tick. | 
 |  1147         current->Tick(); | 
 |  1148       } | 
|  1111       if (VMTag::IsNativeEntryTag(sample->vm_tag())) { |  1149       if (VMTag::IsNativeEntryTag(sample->vm_tag())) { | 
|  1112         // Insert a dummy kNativeTagId node. |  1150         // Insert a dummy kNativeTagId node. | 
|  1113         intptr_t tag_index = FindTagIndex(VMTag::kNativeTagId); |  1151         intptr_t tag_index = FindTagIndex(VMTag::kNativeTagId); | 
|  1114         current = current->GetChild(tag_index); |  1152         current = current->GetChild(tag_index); | 
|  1115         // Give the tag a tick. |  1153         // Give the tag a tick. | 
|  1116         current->Tick(); |  1154         current->Tick(); | 
|  1117       } else if (VMTag::IsRuntimeEntryTag(sample->vm_tag())) { |  1155       } else if (VMTag::IsRuntimeEntryTag(sample->vm_tag())) { | 
|  1118         // Insert a dummy kRuntimeTagId node. |  1156         // Insert a dummy kRuntimeTagId node. | 
|  1119         intptr_t tag_index = FindTagIndex(VMTag::kRuntimeTagId); |  1157         intptr_t tag_index = FindTagIndex(VMTag::kRuntimeTagId); | 
|  1120         current = current->GetChild(tag_index); |  1158         current = current->GetChild(tag_index); | 
| (...skipping 23 matching lines...) Expand all  Loading... | 
|  1144   bool use_tags() const { |  1182   bool use_tags() const { | 
|  1145     return use_tags_; |  1183     return use_tags_; | 
|  1146   } |  1184   } | 
|  1147  |  1185  | 
|  1148   void set_use_tags(bool use_tags) { |  1186   void set_use_tags(bool use_tags) { | 
|  1149     use_tags_ = use_tags; |  1187     use_tags_ = use_tags; | 
|  1150   } |  1188   } | 
|  1151  |  1189  | 
|  1152  private: |  1190  private: | 
|  1153   intptr_t FindTagIndex(uword tag) const { |  1191   intptr_t FindTagIndex(uword tag) const { | 
 |  1192     if (tag == 0) { | 
 |  1193       return -1; | 
 |  1194     } | 
|  1154     intptr_t index = tag_code_table_->FindIndex(tag); |  1195     intptr_t index = tag_code_table_->FindIndex(tag); | 
 |  1196     if (index <= 0) { | 
 |  1197       return -1; | 
 |  1198     } | 
|  1155     ASSERT(index >= 0); |  1199     ASSERT(index >= 0); | 
|  1156     ASSERT((tag_code_table_->At(index))->contains(tag)); |  1200     ASSERT((tag_code_table_->At(index))->contains(tag)); | 
|  1157     return tag_code_table_offset_ + index; |  1201     return tag_code_table_offset_ + index; | 
|  1158   } |  1202   } | 
|  1159  |  1203  | 
|  1160   intptr_t FindFinalIndex(uword pc, int64_t timestamp) const { |  1204   intptr_t FindFinalIndex(uword pc, int64_t timestamp) const { | 
|  1161     intptr_t index = live_code_table_->FindIndex(pc); |  1205     intptr_t index = live_code_table_->FindIndex(pc); | 
|  1162     ASSERT(index >= 0); |  1206     ASSERT(index >= 0); | 
|  1163     CodeRegion* region = live_code_table_->At(index); |  1207     CodeRegion* region = live_code_table_->At(index); | 
|  1164     ASSERT(region->contains(pc)); |  1208     ASSERT(region->contains(pc)); | 
| (...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1516       // The stack pointer gives us a better lower bound than |  1560       // The stack pointer gives us a better lower bound than | 
|  1517       // the isolates stack limit. |  1561       // the isolates stack limit. | 
|  1518       lower_bound_ = original_sp_; |  1562       lower_bound_ = original_sp_; | 
|  1519     } |  1563     } | 
|  1520     int i = 0; |  1564     int i = 0; | 
|  1521     for (; i < FLAG_profile_depth; i++) { |  1565     for (; i < FLAG_profile_depth; i++) { | 
|  1522       if (FLAG_profile_verify_stack_walk) { |  1566       if (FLAG_profile_verify_stack_walk) { | 
|  1523         VerifyCodeAddress(heap, i, reinterpret_cast<uword>(pc)); |  1567         VerifyCodeAddress(heap, i, reinterpret_cast<uword>(pc)); | 
|  1524       } |  1568       } | 
|  1525       sample_->SetAt(i, reinterpret_cast<uword>(pc)); |  1569       sample_->SetAt(i, reinterpret_cast<uword>(pc)); | 
 |  1570       if (fp == NULL) { | 
 |  1571         return i + 1; | 
 |  1572       } | 
|  1526       if (!ValidFramePointer(fp)) { |  1573       if (!ValidFramePointer(fp)) { | 
|  1527         return i + 1; |  1574         return i + 1; | 
|  1528       } |  1575       } | 
|  1529       pc = CallerPC(fp); |  1576       pc = CallerPC(fp); | 
|  1530       previous_fp = fp; |  1577       previous_fp = fp; | 
|  1531       fp = CallerFP(fp); |  1578       fp = CallerFP(fp); | 
|  1532       intptr_t step = fp - previous_fp; |  1579       intptr_t step = fp - previous_fp; | 
|  1533       if ((step >= kMaxStep) || (fp <= previous_fp) || !ValidFramePointer(fp)) { |  1580       if (fp == NULL) { | 
 |  1581         return i + 1; | 
 |  1582       } | 
 |  1583       if ((step >= kMaxStep)) { | 
|  1534         // Frame pointer step is too large. |  1584         // Frame pointer step is too large. | 
 |  1585         return i + 1; | 
 |  1586       } | 
 |  1587       if ((fp <= previous_fp)) { | 
|  1535         // Frame pointer did not move to a higher address. |  1588         // Frame pointer did not move to a higher address. | 
 |  1589         return i + 1; | 
 |  1590       } | 
 |  1591       if (!ValidFramePointer(fp)) { | 
|  1536         // Frame pointer is outside of isolate stack bounds. |  1592         // Frame pointer is outside of isolate stack bounds. | 
|  1537         return i + 1; |  1593         return i + 1; | 
|  1538       } |  1594       } | 
|  1539       // Move the lower bound up. |  1595       // Move the lower bound up. | 
|  1540       lower_bound_ = reinterpret_cast<uword>(fp); |  1596       lower_bound_ = reinterpret_cast<uword>(fp); | 
|  1541     } |  1597     } | 
|  1542     return i; |  1598     return i; | 
|  1543   } |  1599   } | 
|  1544  |  1600  | 
|  1545  private: |  1601  private: | 
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1603   if (profiler_data == NULL) { |  1659   if (profiler_data == NULL) { | 
|  1604     return; |  1660     return; | 
|  1605   } |  1661   } | 
|  1606   SampleBuffer* sample_buffer = profiler_data->sample_buffer(); |  1662   SampleBuffer* sample_buffer = profiler_data->sample_buffer(); | 
|  1607   if (sample_buffer == NULL) { |  1663   if (sample_buffer == NULL) { | 
|  1608     return; |  1664     return; | 
|  1609   } |  1665   } | 
|  1610   Sample* sample = sample_buffer->ReserveSample(); |  1666   Sample* sample = sample_buffer->ReserveSample(); | 
|  1611   sample->Init(isolate, OS::GetCurrentTimeMicros(), state.tid); |  1667   sample->Init(isolate, OS::GetCurrentTimeMicros(), state.tid); | 
|  1612   sample->set_vm_tag(isolate->vm_tag()); |  1668   sample->set_vm_tag(isolate->vm_tag()); | 
 |  1669   sample->set_user_tag(isolate->user_tag()); | 
|  1613   if (FLAG_profile_native_stack) { |  1670   if (FLAG_profile_native_stack) { | 
|  1614     // Collect native and Dart frames. |  1671     // Collect native and Dart frames. | 
|  1615     uword stack_lower = 0; |  1672     uword stack_lower = 0; | 
|  1616     uword stack_upper = 0; |  1673     uword stack_upper = 0; | 
|  1617     isolate->GetStackBounds(&stack_lower, &stack_upper); |  1674     isolate->GetStackBounds(&stack_lower, &stack_upper); | 
|  1618     if ((stack_lower == 0) || (stack_upper == 0)) { |  1675     if ((stack_lower == 0) || (stack_upper == 0)) { | 
|  1619       stack_lower = 0; |  1676       stack_lower = 0; | 
|  1620       stack_upper = 0; |  1677       stack_upper = 0; | 
|  1621     } |  1678     } | 
|  1622     ProfilerNativeStackWalker stackWalker(sample, stack_lower, stack_upper, |  1679     ProfilerNativeStackWalker stackWalker(sample, stack_lower, stack_upper, | 
|  1623                                           state.pc, state.fp, state.sp); |  1680                                           state.pc, state.fp, state.sp); | 
|  1624     stackWalker.walk(isolate->heap()); |  1681     stackWalker.walk(isolate->heap()); | 
|  1625   } else { |  1682   } else { | 
|  1626     if (isolate->top_exit_frame_info() != 0) { |  1683     if (isolate->top_exit_frame_info() != 0) { | 
|  1627       ProfilerDartStackWalker stackWalker(sample); |  1684       ProfilerDartStackWalker stackWalker(sample); | 
|  1628       stackWalker.walk(); |  1685       stackWalker.walk(); | 
|  1629     } else { |  1686     } else { | 
|  1630       // TODO(johnmccutchan): Support collecting only Dart frames with |  1687       // TODO(johnmccutchan): Support collecting only Dart frames with | 
|  1631       // ProfilerNativeStackWalker. |  1688       // ProfilerNativeStackWalker. | 
|  1632     } |  1689     } | 
|  1633   } |  1690   } | 
|  1634 } |  1691 } | 
|  1635  |  1692  | 
|  1636 }  // namespace dart |  1693 }  // namespace dart | 
| OLD | NEW |