Chromium Code Reviews| 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/native_symbol.h" | 10 #include "vm/native_symbol.h" |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 139 if (function_.IsNull()) { | 139 if (function_.IsNull()) { |
| 140 // Some synthetic function. | 140 // Some synthetic function. |
| 141 return true; | 141 return true; |
| 142 } | 142 } |
| 143 return FLAG_show_invisible_frames || function_.is_visible(); | 143 return FLAG_show_invisible_frames || function_.is_visible(); |
| 144 } | 144 } |
| 145 | 145 |
| 146 | 146 |
| 147 void ProfileFunction::Tick(bool exclusive, | 147 void ProfileFunction::Tick(bool exclusive, |
| 148 intptr_t inclusive_serial, | 148 intptr_t inclusive_serial, |
| 149 TokenPosition token_position) { | 149 TokenPosition token_position, |
| 150 ProcessedSample* sample) { | |
| 150 if (exclusive) { | 151 if (exclusive) { |
| 151 exclusive_ticks_++; | 152 exclusive_ticks_++; |
| 153 AccumulateAllocation(sample->native_allocation_size_bytes(), true); | |
| 152 TickSourcePosition(token_position, exclusive); | 154 TickSourcePosition(token_position, exclusive); |
| 153 } | 155 } |
| 154 // Fall through and tick inclusive count too. | 156 // Fall through and tick inclusive count too. |
| 155 if (inclusive_serial_ == inclusive_serial) { | 157 if (inclusive_serial_ == inclusive_serial) { |
| 156 // Already ticked. | 158 // Already ticked. |
| 157 return; | 159 return; |
| 158 } | 160 } |
| 159 inclusive_serial_ = inclusive_serial; | 161 inclusive_serial_ = inclusive_serial; |
| 160 inclusive_ticks_++; | 162 inclusive_ticks_++; |
| 163 AccumulateAllocation(sample->native_allocation_size_bytes(), false); | |
| 161 TickSourcePosition(token_position, false); | 164 TickSourcePosition(token_position, false); |
| 162 } | 165 } |
| 163 | 166 |
| 164 | 167 |
| 165 void ProfileFunction::TickSourcePosition(TokenPosition token_position, | 168 void ProfileFunction::TickSourcePosition(TokenPosition token_position, |
| 166 bool exclusive) { | 169 bool exclusive) { |
| 167 intptr_t i = 0; | 170 intptr_t i = 0; |
| 168 for (; i < source_position_ticks_.length(); i++) { | 171 for (; i < source_position_ticks_.length(); i++) { |
| 169 ProfileFunctionSourcePosition& position = source_position_ticks_[i]; | 172 ProfileFunctionSourcePosition& position = source_position_ticks_[i]; |
| 170 if (position.token_pos().value() == token_position.value()) { | 173 if (position.token_pos().value() == token_position.value()) { |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 192 pfsp.Tick(exclusive); | 195 pfsp.Tick(exclusive); |
| 193 | 196 |
| 194 if (i < source_position_ticks_.length()) { | 197 if (i < source_position_ticks_.length()) { |
| 195 source_position_ticks_.InsertAt(i, pfsp); | 198 source_position_ticks_.InsertAt(i, pfsp); |
| 196 } else { | 199 } else { |
| 197 source_position_ticks_.Add(pfsp); | 200 source_position_ticks_.Add(pfsp); |
| 198 } | 201 } |
| 199 } | 202 } |
| 200 | 203 |
| 201 | 204 |
| 205 static intptr_t SumAllocations(const AllocationHashMap& map) { | |
| 206 uintptr_t sum = 0; | |
| 207 AllocationHashMap::Iterator iter = map.GetIterator(); | |
| 208 AllocationKeyValueTrait::Pair* pair = iter.Next(); | |
| 209 | |
| 210 while (pair != NULL) { | |
| 211 sum += pair->value * pair->key; | |
| 212 pair = iter.Next(); | |
| 213 } | |
| 214 | |
| 215 return sum; | |
| 216 } | |
| 217 | |
| 218 | |
| 219 static void AccumulateAllocationHelper(AllocationHashMap* map, | |
|
Cutch
2017/03/16 20:38:16
I don't see why this code is necessary?
bkonyi
2017/03/16 20:48:40
So, currently, I'm tracking the inclusive/exclusiv
bkonyi
2017/03/21 01:53:23
Removed.
| |
| 220 intptr_t allocation_size) { | |
| 221 ASSERT(map != NULL); | |
| 222 AllocationKeyValueTrait::Pair* allocation = map->Lookup(allocation_size); | |
| 223 if (allocation == NULL) { | |
| 224 map->Insert(AllocationKeyValueTrait::Pair(allocation_size, 1)); | |
| 225 return; | |
| 226 } | |
| 227 ++allocation->value; | |
| 228 } | |
| 229 | |
| 230 | |
| 231 void ProfileFunction::AccumulateAllocation(intptr_t allocation_size, | |
| 232 bool exclusive) { | |
| 233 if (exclusive) { | |
| 234 AccumulateAllocationHelper(&exclusive_native_allocations_, allocation_size); | |
| 235 } else { | |
| 236 AccumulateAllocationHelper(&inclusive_native_allocations_, allocation_size); | |
| 237 } | |
| 238 } | |
| 239 | |
| 240 | |
| 202 const char* ProfileFunction::KindToCString(Kind kind) { | 241 const char* ProfileFunction::KindToCString(Kind kind) { |
| 203 switch (kind) { | 242 switch (kind) { |
| 204 case kDartFunction: | 243 case kDartFunction: |
| 205 return "Dart"; | 244 return "Dart"; |
| 206 case kNativeFunction: | 245 case kNativeFunction: |
| 207 return "Native"; | 246 return "Native"; |
| 208 case kTagFunction: | 247 case kTagFunction: |
| 209 return "Tag"; | 248 return "Tag"; |
| 210 case kStubFunction: | 249 case kStubFunction: |
| 211 return "Stub"; | 250 return "Stub"; |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 223 func->AddProperty("name", name()); | 262 func->AddProperty("name", name()); |
| 224 func->AddProperty("_kind", KindToCString(kind())); | 263 func->AddProperty("_kind", KindToCString(kind())); |
| 225 } | 264 } |
| 226 | 265 |
| 227 | 266 |
| 228 void ProfileFunction::PrintToJSONArray(JSONArray* functions) { | 267 void ProfileFunction::PrintToJSONArray(JSONArray* functions) { |
| 229 JSONObject obj(functions); | 268 JSONObject obj(functions); |
| 230 obj.AddProperty("kind", KindToCString(kind())); | 269 obj.AddProperty("kind", KindToCString(kind())); |
| 231 obj.AddPropertyF("inclusiveTicks", "%" Pd "", inclusive_ticks()); | 270 obj.AddPropertyF("inclusiveTicks", "%" Pd "", inclusive_ticks()); |
| 232 obj.AddPropertyF("exclusiveTicks", "%" Pd "", exclusive_ticks()); | 271 obj.AddPropertyF("exclusiveTicks", "%" Pd "", exclusive_ticks()); |
| 272 | |
| 273 obj.AddPropertyF("inclusiveNativeAllocations", "%" Pd "", | |
| 274 SumAllocations(inclusive_native_allocations_)); | |
| 275 obj.AddPropertyF("exclusiveNativeAllocations", "%" Pd "", | |
| 276 SumAllocations(exclusive_native_allocations_)); | |
| 277 | |
| 233 if (kind() == kDartFunction) { | 278 if (kind() == kDartFunction) { |
| 234 ASSERT(!function_.IsNull()); | 279 ASSERT(!function_.IsNull()); |
| 235 obj.AddProperty("function", function_); | 280 obj.AddProperty("function", function_); |
| 236 } else { | 281 } else { |
| 237 JSONObject func(&obj, "function"); | 282 JSONObject func(&obj, "function"); |
| 238 PrintToJSONObject(&func); | 283 PrintToJSONObject(&func); |
| 239 } | 284 } |
| 240 { | 285 { |
| 241 JSONArray codes(&obj, "codes"); | 286 JSONArray codes(&obj, "codes"); |
| 242 for (intptr_t i = 0; i < profile_codes_.length(); i++) { | 287 for (intptr_t i = 0; i < profile_codes_.length(); i++) { |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 337 | 382 |
| 338 void ProfileCode::GenerateAndSetSymbolName(const char* prefix) { | 383 void ProfileCode::GenerateAndSetSymbolName(const char* prefix) { |
| 339 const intptr_t kBuffSize = 512; | 384 const intptr_t kBuffSize = 512; |
| 340 char buff[kBuffSize]; | 385 char buff[kBuffSize]; |
| 341 OS::SNPrint(&buff[0], kBuffSize - 1, "%s [%" Px ", %" Px ")", prefix, start(), | 386 OS::SNPrint(&buff[0], kBuffSize - 1, "%s [%" Px ", %" Px ")", prefix, start(), |
| 342 end()); | 387 end()); |
| 343 SetName(buff); | 388 SetName(buff); |
| 344 } | 389 } |
| 345 | 390 |
| 346 | 391 |
| 347 void ProfileCode::Tick(uword pc, bool exclusive, intptr_t serial) { | 392 void ProfileCode::Tick(uword pc, |
| 393 bool exclusive, | |
| 394 intptr_t serial, | |
| 395 ProcessedSample* sample) { | |
| 348 // If exclusive is set, tick it. | 396 // If exclusive is set, tick it. |
| 349 if (exclusive) { | 397 if (exclusive) { |
| 350 exclusive_ticks_++; | 398 exclusive_ticks_++; |
| 399 AccumulateAllocation(sample->native_allocation_size_bytes(), true); | |
| 351 TickAddress(pc, true); | 400 TickAddress(pc, true); |
| 352 } | 401 } |
| 353 // Fall through and tick inclusive count too. | 402 // Fall through and tick inclusive count too. |
| 354 if (inclusive_serial_ == serial) { | 403 if (inclusive_serial_ == serial) { |
| 355 // Already gave inclusive tick for this sample. | 404 // Already gave inclusive tick for this sample. |
| 356 return; | 405 return; |
| 357 } | 406 } |
| 407 | |
| 408 AccumulateAllocation(sample->native_allocation_size_bytes(), false); | |
| 409 | |
| 358 inclusive_serial_ = serial; | 410 inclusive_serial_ = serial; |
| 359 inclusive_ticks_++; | 411 inclusive_ticks_++; |
| 360 TickAddress(pc, false); | 412 TickAddress(pc, false); |
| 361 } | 413 } |
| 362 | 414 |
| 363 | 415 |
| 364 void ProfileCode::TickAddress(uword pc, bool exclusive) { | 416 void ProfileCode::TickAddress(uword pc, bool exclusive) { |
| 365 const intptr_t length = address_ticks_.length(); | 417 const intptr_t length = address_ticks_.length(); |
| 366 | 418 |
| 367 intptr_t i = 0; | 419 intptr_t i = 0; |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 385 if (i < length) { | 437 if (i < length) { |
| 386 // Insert at i. | 438 // Insert at i. |
| 387 address_ticks_.InsertAt(i, entry); | 439 address_ticks_.InsertAt(i, entry); |
| 388 } else { | 440 } else { |
| 389 // Add to end. | 441 // Add to end. |
| 390 address_ticks_.Add(entry); | 442 address_ticks_.Add(entry); |
| 391 } | 443 } |
| 392 } | 444 } |
| 393 | 445 |
| 394 | 446 |
| 447 void ProfileCode::AccumulateAllocation(intptr_t allocation_size, | |
| 448 bool exclusive) { | |
| 449 if (exclusive) { | |
| 450 AccumulateAllocationHelper(&exclusive_native_allocations_, allocation_size); | |
| 451 } else { | |
| 452 AccumulateAllocationHelper(&inclusive_native_allocations_, allocation_size); | |
| 453 } | |
| 454 } | |
| 455 | |
| 456 | |
| 395 void ProfileCode::PrintNativeCode(JSONObject* profile_code_obj) { | 457 void ProfileCode::PrintNativeCode(JSONObject* profile_code_obj) { |
| 396 ASSERT(kind() == kNativeCode); | 458 ASSERT(kind() == kNativeCode); |
| 397 JSONObject obj(profile_code_obj, "code"); | 459 JSONObject obj(profile_code_obj, "code"); |
| 398 obj.AddProperty("type", "@Code"); | 460 obj.AddProperty("type", "@Code"); |
| 399 obj.AddProperty("kind", "Native"); | 461 obj.AddProperty("kind", "Native"); |
| 400 obj.AddProperty("name", name()); | 462 obj.AddProperty("name", name()); |
| 401 obj.AddProperty("_optimized", false); | 463 obj.AddProperty("_optimized", false); |
| 402 obj.AddPropertyF("start", "%" Px "", start()); | 464 obj.AddPropertyF("start", "%" Px "", start()); |
| 403 obj.AddPropertyF("end", "%" Px "", end()); | 465 obj.AddPropertyF("end", "%" Px "", end()); |
| 404 { | 466 { |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 480 UNREACHABLE(); | 542 UNREACHABLE(); |
| 481 return NULL; | 543 return NULL; |
| 482 } | 544 } |
| 483 | 545 |
| 484 | 546 |
| 485 void ProfileCode::PrintToJSONArray(JSONArray* codes) { | 547 void ProfileCode::PrintToJSONArray(JSONArray* codes) { |
| 486 JSONObject obj(codes); | 548 JSONObject obj(codes); |
| 487 obj.AddProperty("kind", ProfileCode::KindToCString(kind())); | 549 obj.AddProperty("kind", ProfileCode::KindToCString(kind())); |
| 488 obj.AddPropertyF("inclusiveTicks", "%" Pd "", inclusive_ticks()); | 550 obj.AddPropertyF("inclusiveTicks", "%" Pd "", inclusive_ticks()); |
| 489 obj.AddPropertyF("exclusiveTicks", "%" Pd "", exclusive_ticks()); | 551 obj.AddPropertyF("exclusiveTicks", "%" Pd "", exclusive_ticks()); |
| 552 obj.AddPropertyF("inclusiveNativeAllocations", "%" Pd "", | |
| 553 SumAllocations(inclusive_native_allocations_)); | |
| 554 obj.AddPropertyF("exclusiveNativeAllocations", "%" Pd "", | |
| 555 SumAllocations(exclusive_native_allocations_)); | |
| 490 if (kind() == kDartCode) { | 556 if (kind() == kDartCode) { |
| 491 ASSERT(!code_.IsNull()); | 557 ASSERT(!code_.IsNull()); |
| 492 obj.AddProperty("code", code_); | 558 obj.AddProperty("code", code_); |
| 493 } else if (kind() == kCollectedCode) { | 559 } else if (kind() == kCollectedCode) { |
| 494 PrintCollectedCode(&obj); | 560 PrintCollectedCode(&obj); |
| 495 } else if (kind() == kReusedCode) { | 561 } else if (kind() == kReusedCode) { |
| 496 PrintOverwrittenCode(&obj); | 562 PrintOverwrittenCode(&obj); |
| 497 } else if (kind() == kTagCode) { | 563 } else if (kind() == kTagCode) { |
| 498 PrintTagCode(&obj); | 564 PrintTagCode(&obj); |
| 499 } else { | 565 } else { |
| (...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 856 !b->Contains(a->start()) && !b->Contains(a->end() - 1)); | 922 !b->Contains(a->start()) && !b->Contains(a->end() - 1)); |
| 857 } | 923 } |
| 858 } | 924 } |
| 859 } | 925 } |
| 860 | 926 |
| 861 ZoneGrowableArray<ProfileCode*> table_; | 927 ZoneGrowableArray<ProfileCode*> table_; |
| 862 }; | 928 }; |
| 863 | 929 |
| 864 | 930 |
| 865 ProfileTrieNode::ProfileTrieNode(intptr_t table_index) | 931 ProfileTrieNode::ProfileTrieNode(intptr_t table_index) |
| 866 : table_index_(table_index), count_(0), children_(0), frame_id_(-1) { | 932 : table_index_(table_index), |
| 933 count_(0), | |
| 934 exclusive_allocations_(0), | |
| 935 inclusive_allocations_(0), | |
| 936 children_(0), | |
| 937 frame_id_(-1) { | |
| 867 ASSERT(table_index_ >= 0); | 938 ASSERT(table_index_ >= 0); |
| 868 } | 939 } |
| 869 | 940 |
| 870 | 941 |
| 871 ProfileTrieNode::~ProfileTrieNode() {} | 942 ProfileTrieNode::~ProfileTrieNode() {} |
| 872 | 943 |
| 873 | 944 |
| 874 void ProfileTrieNode::SortChildren() { | 945 void ProfileTrieNode::SortChildren() { |
| 875 children_.Sort(ProfileTrieNodeCompare); | 946 children_.Sort(ProfileTrieNodeCompare); |
| 876 // Recurse. | 947 // Recurse. |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 897 | 968 |
| 898 void PrintToJSONArray(JSONArray* array) const { | 969 void PrintToJSONArray(JSONArray* array) const { |
| 899 ASSERT(array != NULL); | 970 ASSERT(array != NULL); |
| 900 // Write CodeRegion index. | 971 // Write CodeRegion index. |
| 901 array->AddValue(table_index()); | 972 array->AddValue(table_index()); |
| 902 // Write count. | 973 // Write count. |
| 903 array->AddValue(count()); | 974 array->AddValue(count()); |
| 904 // Write number of children. | 975 // Write number of children. |
| 905 intptr_t child_count = NumChildren(); | 976 intptr_t child_count = NumChildren(); |
| 906 array->AddValue(child_count); | 977 array->AddValue(child_count); |
| 978 // Write inclusive allocations. | |
| 979 array->AddValue64(inclusive_allocations_); | |
| 980 // Write exclusive allocations. | |
| 981 array->AddValue64(exclusive_allocations_); | |
| 907 // Recurse. | 982 // Recurse. |
| 908 for (intptr_t i = 0; i < child_count; i++) { | 983 for (intptr_t i = 0; i < child_count; i++) { |
| 909 children_[i]->PrintToJSONArray(array); | 984 children_[i]->PrintToJSONArray(array); |
| 910 } | 985 } |
| 911 } | 986 } |
| 912 | 987 |
| 913 ProfileCodeTrieNode* GetChild(intptr_t child_table_index) { | 988 ProfileCodeTrieNode* GetChild(intptr_t child_table_index) { |
| 914 const intptr_t length = NumChildren(); | 989 const intptr_t length = NumChildren(); |
| 915 intptr_t i = 0; | 990 intptr_t i = 0; |
| 916 while (i < length) { | 991 while (i < length) { |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 958 public: | 1033 public: |
| 959 explicit ProfileFunctionTrieNode(intptr_t table_index) | 1034 explicit ProfileFunctionTrieNode(intptr_t table_index) |
| 960 : ProfileTrieNode(table_index), code_objects_(1) {} | 1035 : ProfileTrieNode(table_index), code_objects_(1) {} |
| 961 | 1036 |
| 962 void PrintToJSONArray(JSONArray* array) const { | 1037 void PrintToJSONArray(JSONArray* array) const { |
| 963 ASSERT(array != NULL); | 1038 ASSERT(array != NULL); |
| 964 // Write CodeRegion index. | 1039 // Write CodeRegion index. |
| 965 array->AddValue(table_index()); | 1040 array->AddValue(table_index()); |
| 966 // Write count. | 1041 // Write count. |
| 967 array->AddValue(count()); | 1042 array->AddValue(count()); |
| 1043 // Write inclusive allocations. | |
| 1044 array->AddValue64(inclusive_allocations_); | |
| 1045 // Write exclusive allocations. | |
| 1046 array->AddValue64(exclusive_allocations_); | |
| 968 // Write number of code objects. | 1047 // Write number of code objects. |
| 969 intptr_t code_count = code_objects_.length(); | 1048 intptr_t code_count = code_objects_.length(); |
| 970 array->AddValue(code_count); | 1049 array->AddValue(code_count); |
| 971 // Write each code object index and ticks. | 1050 // Write each code object index and ticks. |
| 972 for (intptr_t i = 0; i < code_count; i++) { | 1051 for (intptr_t i = 0; i < code_count; i++) { |
| 973 array->AddValue(code_objects_[i].index()); | 1052 array->AddValue(code_objects_[i].index()); |
| 974 array->AddValue(code_objects_[i].ticks()); | 1053 array->AddValue(code_objects_[i].ticks()); |
| 975 } | 1054 } |
| 976 // Write number of children. | 1055 // Write number of children. |
| 977 intptr_t child_count = children_.length(); | 1056 intptr_t child_count = children_.length(); |
| (...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1313 RegisterProfileCodeTag(sample->user_tag()); | 1392 RegisterProfileCodeTag(sample->user_tag()); |
| 1314 | 1393 |
| 1315 // Make sure that a ProfileCode objects exist for all pcs in the sample | 1394 // Make sure that a ProfileCode objects exist for all pcs in the sample |
| 1316 // and tick each one. | 1395 // and tick each one. |
| 1317 for (intptr_t frame_index = 0; frame_index < sample->length(); | 1396 for (intptr_t frame_index = 0; frame_index < sample->length(); |
| 1318 frame_index++) { | 1397 frame_index++) { |
| 1319 const uword pc = sample->At(frame_index); | 1398 const uword pc = sample->At(frame_index); |
| 1320 ASSERT(pc != 0); | 1399 ASSERT(pc != 0); |
| 1321 ProfileCode* code = FindOrRegisterProfileCode(pc, timestamp); | 1400 ProfileCode* code = FindOrRegisterProfileCode(pc, timestamp); |
| 1322 ASSERT(code != NULL); | 1401 ASSERT(code != NULL); |
| 1323 code->Tick(pc, IsExecutingFrame(sample, frame_index), sample_index); | 1402 code->Tick(pc, IsExecutingFrame(sample, frame_index), sample_index, |
| 1403 sample); | |
| 1324 } | 1404 } |
| 1325 | 1405 |
| 1326 TickExitFrame(sample->vm_tag(), sample_index); | 1406 TickExitFrame(sample->vm_tag(), sample_index, sample); |
| 1327 } | 1407 } |
| 1328 SanitizeMinMaxTimes(); | 1408 SanitizeMinMaxTimes(); |
| 1329 } | 1409 } |
| 1330 | 1410 |
| 1331 void FinalizeCodeIndexes() { | 1411 void FinalizeCodeIndexes() { |
| 1332 ScopeTimer sw("ProfileBuilder::FinalizeCodeIndexes", FLAG_trace_profiler); | 1412 ScopeTimer sw("ProfileBuilder::FinalizeCodeIndexes", FLAG_trace_profiler); |
| 1333 ProfileCodeTable* live_table = profile_->live_code_; | 1413 ProfileCodeTable* live_table = profile_->live_code_; |
| 1334 ProfileCodeTable* dead_table = profile_->dead_code_; | 1414 ProfileCodeTable* dead_table = profile_->dead_code_; |
| 1335 ProfileCodeTable* tag_table = profile_->tag_code_; | 1415 ProfileCodeTable* tag_table = profile_->tag_code_; |
| 1336 const intptr_t dead_code_index_offset = live_table->length(); | 1416 const intptr_t dead_code_index_offset = live_table->length(); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1403 void BuildInclusiveCodeTrie(ProfileCodeTrieNode* root) { | 1483 void BuildInclusiveCodeTrie(ProfileCodeTrieNode* root) { |
| 1404 ScopeTimer sw("ProfileBuilder::BuildInclusiveCodeTrie", | 1484 ScopeTimer sw("ProfileBuilder::BuildInclusiveCodeTrie", |
| 1405 FLAG_trace_profiler); | 1485 FLAG_trace_profiler); |
| 1406 for (intptr_t sample_index = 0; sample_index < samples_->length(); | 1486 for (intptr_t sample_index = 0; sample_index < samples_->length(); |
| 1407 sample_index++) { | 1487 sample_index++) { |
| 1408 ProcessedSample* sample = samples_->At(sample_index); | 1488 ProcessedSample* sample = samples_->At(sample_index); |
| 1409 | 1489 |
| 1410 // Tick the root. | 1490 // Tick the root. |
| 1411 ProfileCodeTrieNode* current = root; | 1491 ProfileCodeTrieNode* current = root; |
| 1412 current->Tick(); | 1492 current->Tick(); |
| 1493 current->IncrementAllocation(sample->native_allocation_size_bytes(), | |
|
Cutch
2017/03/16 20:38:16
Refactor this so it follows the pattern you set el
bkonyi
2017/03/21 01:53:24
Done.
| |
| 1494 false); | |
| 1413 | 1495 |
| 1414 // VM & User tags. | 1496 // VM & User tags. |
| 1415 current = AppendTags(sample->vm_tag(), sample->user_tag(), current); | 1497 current = |
| 1498 AppendTags(sample->vm_tag(), sample->user_tag(), current, sample); | |
| 1416 | 1499 |
| 1417 ResetKind(); | 1500 ResetKind(); |
| 1418 | 1501 |
| 1419 // Truncated tag. | 1502 // Truncated tag. |
| 1420 if (sample->truncated()) { | 1503 if (sample->truncated()) { |
| 1421 current = AppendTruncatedTag(current); | 1504 current = AppendTruncatedTag(current, sample); |
| 1422 } | 1505 } |
| 1423 | 1506 |
| 1424 // Walk the sampled PCs. | 1507 // Walk the sampled PCs. |
| 1425 Code& code = Code::Handle(); | 1508 Code& code = Code::Handle(); |
| 1426 for (intptr_t frame_index = sample->length() - 1; frame_index >= 0; | 1509 for (intptr_t frame_index = sample->length() - 1; frame_index >= 0; |
| 1427 frame_index--) { | 1510 frame_index--) { |
| 1428 ASSERT(sample->At(frame_index) != 0); | 1511 ASSERT(sample->At(frame_index) != 0); |
| 1429 intptr_t index = | 1512 intptr_t index = |
| 1430 GetProfileCodeIndex(sample->At(frame_index), sample->timestamp()); | 1513 GetProfileCodeIndex(sample->At(frame_index), sample->timestamp()); |
| 1431 ASSERT(index >= 0); | 1514 ASSERT(index >= 0); |
| 1432 ProfileCode* profile_code = | 1515 ProfileCode* profile_code = |
| 1433 GetProfileCode(sample->At(frame_index), sample->timestamp()); | 1516 GetProfileCode(sample->At(frame_index), sample->timestamp()); |
| 1434 ASSERT(profile_code->code_table_index() == index); | 1517 ASSERT(profile_code->code_table_index() == index); |
| 1435 code ^= profile_code->code(); | 1518 code ^= profile_code->code(); |
| 1436 current = AppendKind(code, current); | 1519 current = AppendKind(code, current, sample); |
| 1437 current = current->GetChild(index); | 1520 current = current->GetChild(index); |
| 1438 current->Tick(); | 1521 current->Tick(); |
| 1522 current->IncrementAllocation(sample->native_allocation_size_bytes(), | |
|
Cutch
2017/03/16 20:38:16
ditto
bkonyi
2017/03/21 01:53:23
Done.
| |
| 1523 (frame_index == 0)); | |
| 1439 } | 1524 } |
| 1440 | 1525 |
| 1441 if (!sample->first_frame_executing()) { | 1526 if (!sample->first_frame_executing()) { |
| 1442 current = AppendExitFrame(sample->vm_tag(), current); | 1527 current = AppendExitFrame(sample->vm_tag(), current, sample); |
| 1443 } | 1528 } |
| 1444 } | 1529 } |
| 1445 } | 1530 } |
| 1446 | 1531 |
| 1447 void BuildExclusiveCodeTrie(ProfileCodeTrieNode* root) { | 1532 void BuildExclusiveCodeTrie(ProfileCodeTrieNode* root) { |
| 1448 ScopeTimer sw("ProfileBuilder::BuildExclusiveCodeTrie", | 1533 ScopeTimer sw("ProfileBuilder::BuildExclusiveCodeTrie", |
| 1449 FLAG_trace_profiler); | 1534 FLAG_trace_profiler); |
| 1450 for (intptr_t sample_index = 0; sample_index < samples_->length(); | 1535 for (intptr_t sample_index = 0; sample_index < samples_->length(); |
| 1451 sample_index++) { | 1536 sample_index++) { |
| 1452 ProcessedSample* sample = samples_->At(sample_index); | 1537 ProcessedSample* sample = samples_->At(sample_index); |
| 1453 | 1538 |
| 1454 // Tick the root. | 1539 // Tick the root. |
| 1455 ProfileCodeTrieNode* current = root; | 1540 ProfileCodeTrieNode* current = root; |
| 1456 current->Tick(); | 1541 current->Tick(); |
| 1457 | 1542 current->IncrementAllocation(sample->native_allocation_size_bytes(), |
|
Cutch
2017/03/16 20:38:16
ditto
bkonyi
2017/03/21 01:53:23
Done.
| |
| 1543 false); | |
| 1458 // VM & User tags. | 1544 // VM & User tags. |
| 1459 current = AppendTags(sample->vm_tag(), sample->user_tag(), current); | 1545 current = |
| 1546 AppendTags(sample->vm_tag(), sample->user_tag(), current, sample); | |
| 1460 | 1547 |
| 1461 ResetKind(); | 1548 ResetKind(); |
| 1462 | 1549 |
| 1463 if (!sample->first_frame_executing()) { | 1550 if (!sample->first_frame_executing()) { |
| 1464 current = AppendExitFrame(sample->vm_tag(), current); | 1551 current = AppendExitFrame(sample->vm_tag(), current, sample); |
| 1465 } | 1552 } |
| 1466 | 1553 |
| 1467 // Walk the sampled PCs. | 1554 // Walk the sampled PCs. |
| 1468 Code& code = Code::Handle(); | 1555 Code& code = Code::Handle(); |
| 1469 for (intptr_t frame_index = 0; frame_index < sample->length(); | 1556 for (intptr_t frame_index = 0; frame_index < sample->length(); |
| 1470 frame_index++) { | 1557 frame_index++) { |
| 1471 ASSERT(sample->At(frame_index) != 0); | 1558 ASSERT(sample->At(frame_index) != 0); |
| 1472 intptr_t index = | 1559 intptr_t index = |
| 1473 GetProfileCodeIndex(sample->At(frame_index), sample->timestamp()); | 1560 GetProfileCodeIndex(sample->At(frame_index), sample->timestamp()); |
| 1474 ASSERT(index >= 0); | 1561 ASSERT(index >= 0); |
| 1475 ProfileCode* profile_code = | 1562 ProfileCode* profile_code = |
| 1476 GetProfileCode(sample->At(frame_index), sample->timestamp()); | 1563 GetProfileCode(sample->At(frame_index), sample->timestamp()); |
| 1477 ASSERT(profile_code->code_table_index() == index); | 1564 ASSERT(profile_code->code_table_index() == index); |
| 1478 code ^= profile_code->code(); | 1565 code ^= profile_code->code(); |
| 1479 current = current->GetChild(index); | 1566 current = current->GetChild(index); |
| 1480 if (ShouldTickNode(sample, frame_index)) { | 1567 if (ShouldTickNode(sample, frame_index)) { |
| 1481 current->Tick(); | 1568 current->Tick(); |
| 1569 current->IncrementAllocation(sample->native_allocation_size_bytes(), | |
|
Cutch
2017/03/16 20:38:16
ditto
bkonyi
2017/03/21 01:53:24
Done.
| |
| 1570 (frame_index == 0)); | |
| 1482 } | 1571 } |
| 1483 current = AppendKind(code, current); | 1572 current = AppendKind(code, current, sample); |
| 1484 } | 1573 } |
| 1485 // Truncated tag. | 1574 // Truncated tag. |
| 1486 if (sample->truncated()) { | 1575 if (sample->truncated()) { |
| 1487 current = AppendTruncatedTag(current); | 1576 current = AppendTruncatedTag(current, sample); |
| 1488 } | 1577 } |
| 1489 } | 1578 } |
| 1490 } | 1579 } |
| 1491 | 1580 |
| 1492 void BuildFunctionTrie(Profile::TrieKind kind) { | 1581 void BuildFunctionTrie(Profile::TrieKind kind) { |
| 1493 ProfileFunctionTrieNode* root = new ProfileFunctionTrieNode( | 1582 ProfileFunctionTrieNode* root = new ProfileFunctionTrieNode( |
| 1494 GetProfileFunctionTagIndex(VMTag::kRootTagId)); | 1583 GetProfileFunctionTagIndex(VMTag::kRootTagId)); |
| 1495 // We tick the functions while building the trie, but, we don't want to do | 1584 // We tick the functions while building the trie, but, we don't want to do |
| 1496 // it for both tries, just the exclusive trie. | 1585 // it for both tries, just the exclusive trie. |
| 1497 inclusive_tree_ = IsInclusiveTrie(kind); | 1586 inclusive_tree_ = IsInclusiveTrie(kind); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 1509 ScopeTimer sw("ProfileBuilder::BuildInclusiveFunctionTrie", | 1598 ScopeTimer sw("ProfileBuilder::BuildInclusiveFunctionTrie", |
| 1510 FLAG_trace_profiler); | 1599 FLAG_trace_profiler); |
| 1511 ASSERT(!tick_functions_); | 1600 ASSERT(!tick_functions_); |
| 1512 for (intptr_t sample_index = 0; sample_index < samples_->length(); | 1601 for (intptr_t sample_index = 0; sample_index < samples_->length(); |
| 1513 sample_index++) { | 1602 sample_index++) { |
| 1514 ProcessedSample* sample = samples_->At(sample_index); | 1603 ProcessedSample* sample = samples_->At(sample_index); |
| 1515 | 1604 |
| 1516 // Tick the root. | 1605 // Tick the root. |
| 1517 ProfileFunctionTrieNode* current = root; | 1606 ProfileFunctionTrieNode* current = root; |
| 1518 current->Tick(); | 1607 current->Tick(); |
| 1519 | 1608 current->IncrementAllocation(sample->native_allocation_size_bytes(), |
| 1609 false); | |
| 1520 // VM & User tags. | 1610 // VM & User tags. |
| 1521 current = AppendTags(sample->vm_tag(), sample->user_tag(), current); | 1611 current = |
| 1612 AppendTags(sample->vm_tag(), sample->user_tag(), current, sample); | |
| 1522 | 1613 |
| 1523 // Truncated tag. | 1614 // Truncated tag. |
| 1524 if (sample->truncated()) { | 1615 if (sample->truncated()) { |
| 1525 current = AppendTruncatedTag(current); | 1616 current = AppendTruncatedTag(current, sample); |
| 1526 } | 1617 } |
| 1527 | 1618 |
| 1528 // Walk the sampled PCs. | 1619 // Walk the sampled PCs. |
| 1529 for (intptr_t frame_index = sample->length() - 1; frame_index >= 0; | 1620 for (intptr_t frame_index = sample->length() - 1; frame_index >= 0; |
| 1530 frame_index--) { | 1621 frame_index--) { |
| 1531 ASSERT(sample->At(frame_index) != 0); | 1622 ASSERT(sample->At(frame_index) != 0); |
| 1532 current = ProcessFrame(current, sample_index, sample, frame_index); | 1623 current = ProcessFrame(current, sample_index, sample, frame_index); |
| 1533 } | 1624 } |
| 1534 | 1625 |
| 1535 if (!sample->first_frame_executing()) { | 1626 if (!sample->first_frame_executing()) { |
| 1536 current = AppendExitFrame(sample->vm_tag(), current); | 1627 current = AppendExitFrame(sample->vm_tag(), current, sample); |
| 1537 } | 1628 } |
| 1538 | 1629 |
| 1539 sample->set_timeline_trie(current); | 1630 sample->set_timeline_trie(current); |
| 1540 } | 1631 } |
| 1541 } | 1632 } |
| 1542 | 1633 |
| 1543 void BuildExclusiveFunctionTrie(ProfileFunctionTrieNode* root) { | 1634 void BuildExclusiveFunctionTrie(ProfileFunctionTrieNode* root) { |
| 1544 ScopeTimer sw("ProfileBuilder::BuildExclusiveFunctionTrie", | 1635 ScopeTimer sw("ProfileBuilder::BuildExclusiveFunctionTrie", |
| 1545 FLAG_trace_profiler); | 1636 FLAG_trace_profiler); |
| 1546 ASSERT(tick_functions_); | 1637 ASSERT(tick_functions_); |
| 1547 for (intptr_t sample_index = 0; sample_index < samples_->length(); | 1638 for (intptr_t sample_index = 0; sample_index < samples_->length(); |
| 1548 sample_index++) { | 1639 sample_index++) { |
| 1549 ProcessedSample* sample = samples_->At(sample_index); | 1640 ProcessedSample* sample = samples_->At(sample_index); |
| 1550 | 1641 |
| 1551 // Tick the root. | 1642 // Tick the root. |
| 1552 ProfileFunctionTrieNode* current = root; | 1643 ProfileFunctionTrieNode* current = root; |
| 1553 current->Tick(); | 1644 current->Tick(); |
| 1554 | 1645 current->IncrementAllocation(sample->native_allocation_size_bytes(), |
| 1646 false); | |
| 1555 // VM & User tags. | 1647 // VM & User tags. |
| 1556 current = AppendTags(sample->vm_tag(), sample->user_tag(), current); | 1648 current = |
| 1649 AppendTags(sample->vm_tag(), sample->user_tag(), current, sample); | |
| 1557 | 1650 |
| 1558 ResetKind(); | 1651 ResetKind(); |
| 1559 | 1652 |
| 1560 if (!sample->first_frame_executing()) { | 1653 if (!sample->first_frame_executing()) { |
| 1561 current = AppendExitFrame(sample->vm_tag(), current); | 1654 current = AppendExitFrame(sample->vm_tag(), current, sample); |
| 1562 } | 1655 } |
| 1563 | 1656 |
| 1564 // Walk the sampled PCs. | 1657 // Walk the sampled PCs. |
| 1565 for (intptr_t frame_index = 0; frame_index < sample->length(); | 1658 for (intptr_t frame_index = 0; frame_index < sample->length(); |
| 1566 frame_index++) { | 1659 frame_index++) { |
| 1567 ASSERT(sample->At(frame_index) != 0); | 1660 ASSERT(sample->At(frame_index) != 0); |
| 1568 current = ProcessFrame(current, sample_index, sample, frame_index); | 1661 current = ProcessFrame(current, sample_index, sample, frame_index); |
| 1569 } | 1662 } |
| 1570 | 1663 |
| 1571 TickExitFrameFunction(sample->vm_tag(), sample_index); | 1664 TickExitFrameFunction(sample->vm_tag(), sample_index, sample); |
| 1572 | 1665 |
| 1573 // Truncated tag. | 1666 // Truncated tag. |
| 1574 if (sample->truncated()) { | 1667 if (sample->truncated()) { |
| 1575 current = AppendTruncatedTag(current); | 1668 current = AppendTruncatedTag(current, sample); |
| 1576 InclusiveTickTruncatedTag(); | 1669 InclusiveTickTruncatedTag(sample); |
| 1577 } | 1670 } |
| 1578 } | 1671 } |
| 1579 } | 1672 } |
| 1580 | 1673 |
| 1581 ProfileFunctionTrieNode* ProcessFrame(ProfileFunctionTrieNode* current, | 1674 ProfileFunctionTrieNode* ProcessFrame(ProfileFunctionTrieNode* current, |
| 1582 intptr_t sample_index, | 1675 intptr_t sample_index, |
| 1583 ProcessedSample* sample, | 1676 ProcessedSample* sample, |
| 1584 intptr_t frame_index) { | 1677 intptr_t frame_index) { |
| 1585 const uword pc = sample->At(frame_index); | 1678 const uword pc = sample->At(frame_index); |
| 1586 ProfileCode* profile_code = GetProfileCode(pc, sample->timestamp()); | 1679 ProfileCode* profile_code = GetProfileCode(pc, sample->timestamp()); |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 1604 name.ToCString(), | 1697 name.ToCString(), |
| 1605 (*inlined_token_positions)[i].ToCString()); | 1698 (*inlined_token_positions)[i].ToCString()); |
| 1606 } | 1699 } |
| 1607 } | 1700 } |
| 1608 } | 1701 } |
| 1609 | 1702 |
| 1610 if (code.IsNull() || (inlined_functions == NULL) || | 1703 if (code.IsNull() || (inlined_functions == NULL) || |
| 1611 (inlined_functions->length() <= 1)) { | 1704 (inlined_functions->length() <= 1)) { |
| 1612 // No inlined functions. | 1705 // No inlined functions. |
| 1613 if (inclusive_tree_) { | 1706 if (inclusive_tree_) { |
| 1614 current = AppendKind(code, current); | 1707 current = AppendKind(code, current, sample); |
| 1615 } | 1708 } |
| 1616 current = ProcessFunction(current, sample_index, sample, frame_index, | 1709 current = ProcessFunction(current, sample_index, sample, frame_index, |
| 1617 function, token_position, code_index); | 1710 function, token_position, code_index); |
| 1618 if (!inclusive_tree_) { | 1711 if (!inclusive_tree_) { |
| 1619 current = AppendKind(code, current); | 1712 current = AppendKind(code, current, sample); |
| 1620 } | 1713 } |
| 1621 return current; | 1714 return current; |
| 1622 } | 1715 } |
| 1623 | 1716 |
| 1717 // TODO(bkonyi) deal with this | |
|
bkonyi
2017/03/16 19:50:57
What needs to be done here again John?
Cutch
2017/03/16 20:38:16
You should figure out why the assumption that the
bkonyi
2017/03/21 01:53:24
Acknowledged.
| |
| 1624 ASSERT(code.is_optimized()); | 1718 ASSERT(code.is_optimized()); |
| 1625 | 1719 |
| 1626 if (inclusive_tree_) { | 1720 if (inclusive_tree_) { |
| 1627 for (intptr_t i = 0; i < inlined_functions->length(); i++) { | 1721 for (intptr_t i = 0; i < inlined_functions->length(); i++) { |
| 1628 const Function* inlined_function = (*inlined_functions)[i]; | 1722 const Function* inlined_function = (*inlined_functions)[i]; |
| 1629 ASSERT(inlined_function != NULL); | 1723 ASSERT(inlined_function != NULL); |
| 1630 ASSERT(!inlined_function->IsNull()); | 1724 ASSERT(!inlined_function->IsNull()); |
| 1631 TokenPosition inlined_token_position = (*inlined_token_positions)[i]; | 1725 TokenPosition inlined_token_position = (*inlined_token_positions)[i]; |
| 1632 const bool inliner = i == 0; | 1726 const bool inliner = i == 0; |
| 1633 if (inliner) { | 1727 if (inliner) { |
| 1634 current = AppendKind(code, current); | 1728 current = AppendKind(code, current, sample); |
| 1635 } | 1729 } |
| 1636 current = ProcessInlinedFunction(current, sample_index, sample, | 1730 current = ProcessInlinedFunction(current, sample_index, sample, |
| 1637 frame_index, inlined_function, | 1731 frame_index, inlined_function, |
| 1638 inlined_token_position, code_index); | 1732 inlined_token_position, code_index); |
| 1639 if (inliner) { | 1733 if (inliner) { |
| 1640 current = AppendKind(kInlineStart, current); | 1734 current = AppendKind(kInlineStart, current, sample); |
| 1641 } | 1735 } |
| 1642 } | 1736 } |
| 1643 current = AppendKind(kInlineFinish, current); | 1737 current = AppendKind(kInlineFinish, current, sample); |
| 1644 } else { | 1738 } else { |
| 1645 // Append the inlined children. | 1739 // Append the inlined children. |
| 1646 current = AppendKind(kInlineFinish, current); | 1740 current = AppendKind(kInlineFinish, current, sample); |
| 1647 for (intptr_t i = inlined_functions->length() - 1; i >= 0; i--) { | 1741 for (intptr_t i = inlined_functions->length() - 1; i >= 0; i--) { |
| 1648 const Function* inlined_function = (*inlined_functions)[i]; | 1742 const Function* inlined_function = (*inlined_functions)[i]; |
| 1649 ASSERT(inlined_function != NULL); | 1743 ASSERT(inlined_function != NULL); |
| 1650 ASSERT(!inlined_function->IsNull()); | 1744 ASSERT(!inlined_function->IsNull()); |
| 1651 TokenPosition inlined_token_position = (*inlined_token_positions)[i]; | 1745 TokenPosition inlined_token_position = (*inlined_token_positions)[i]; |
| 1652 const bool inliner = i == 0; | 1746 const bool inliner = i == 0; |
| 1653 if (inliner) { | 1747 if (inliner) { |
| 1654 current = AppendKind(kInlineStart, current); | 1748 current = AppendKind(kInlineStart, current, sample); |
| 1655 } | 1749 } |
| 1656 current = ProcessInlinedFunction(current, sample_index, sample, | 1750 current = ProcessInlinedFunction(current, sample_index, sample, |
| 1657 frame_index + i, inlined_function, | 1751 frame_index + i, inlined_function, |
| 1658 inlined_token_position, code_index); | 1752 inlined_token_position, code_index); |
| 1659 if (inliner) { | 1753 if (inliner) { |
| 1660 current = AppendKind(code, current); | 1754 current = AppendKind(code, current, sample); |
| 1661 } | 1755 } |
| 1662 } | 1756 } |
| 1663 } | 1757 } |
| 1664 | 1758 |
| 1665 return current; | 1759 return current; |
| 1666 } | 1760 } |
| 1667 | 1761 |
| 1668 ProfileFunctionTrieNode* ProcessInlinedFunction( | 1762 ProfileFunctionTrieNode* ProcessInlinedFunction( |
| 1669 ProfileFunctionTrieNode* current, | 1763 ProfileFunctionTrieNode* current, |
| 1670 intptr_t sample_index, | 1764 intptr_t sample_index, |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 1700 if (!function->is_visible()) { | 1794 if (!function->is_visible()) { |
| 1701 return current; | 1795 return current; |
| 1702 } | 1796 } |
| 1703 if (tick_functions_) { | 1797 if (tick_functions_) { |
| 1704 if (FLAG_trace_profiler_verbose) { | 1798 if (FLAG_trace_profiler_verbose) { |
| 1705 THR_Print("S[%" Pd "]F[%" Pd "] %s %s 0x%" Px "\n", sample_index, | 1799 THR_Print("S[%" Pd "]F[%" Pd "] %s %s 0x%" Px "\n", sample_index, |
| 1706 frame_index, function->Name(), token_position.ToCString(), | 1800 frame_index, function->Name(), token_position.ToCString(), |
| 1707 sample->At(frame_index)); | 1801 sample->At(frame_index)); |
| 1708 } | 1802 } |
| 1709 function->Tick(IsExecutingFrame(sample, frame_index), sample_index, | 1803 function->Tick(IsExecutingFrame(sample, frame_index), sample_index, |
| 1710 token_position); | 1804 token_position, sample); |
| 1711 } | 1805 } |
| 1712 function->AddProfileCode(code_index); | 1806 function->AddProfileCode(code_index); |
| 1713 current = current->GetChild(function->table_index()); | 1807 current = current->GetChild(function->table_index()); |
| 1714 if (ShouldTickNode(sample, frame_index)) { | 1808 if (ShouldTickNode(sample, frame_index)) { |
| 1715 current->Tick(); | 1809 current->Tick(); |
| 1810 current->IncrementAllocation(sample->native_allocation_size_bytes(), | |
| 1811 (frame_index == 0)); | |
| 1716 } | 1812 } |
| 1717 current->AddCodeObjectIndex(code_index); | 1813 current->AddCodeObjectIndex(code_index); |
| 1718 return current; | 1814 return current; |
| 1719 } | 1815 } |
| 1720 | 1816 |
| 1721 // Tick the truncated tag's inclusive tick count. | 1817 // Tick the truncated tag's inclusive tick count. |
| 1722 void InclusiveTickTruncatedTag() { | 1818 void InclusiveTickTruncatedTag(ProcessedSample* sample) { |
| 1723 ProfileCodeTable* tag_table = profile_->tag_code_; | 1819 ProfileCodeTable* tag_table = profile_->tag_code_; |
| 1724 intptr_t index = tag_table->FindCodeIndexForPC(VMTag::kTruncatedTagId); | 1820 intptr_t index = tag_table->FindCodeIndexForPC(VMTag::kTruncatedTagId); |
| 1725 ASSERT(index >= 0); | 1821 ASSERT(index >= 0); |
| 1726 ProfileCode* code = tag_table->At(index); | 1822 ProfileCode* code = tag_table->At(index); |
| 1727 code->IncInclusiveTicks(); | 1823 code->IncInclusiveTicks(); |
| 1728 ASSERT(code != NULL); | 1824 ASSERT(code != NULL); |
| 1729 ProfileFunction* function = code->function(); | 1825 ProfileFunction* function = code->function(); |
| 1730 function->IncInclusiveTicks(); | 1826 function->IncInclusiveTicks(); |
| 1827 | |
| 1828 code->AccumulateAllocation(sample->native_allocation_size_bytes(), false); | |
| 1829 function->AccumulateAllocation(sample->native_allocation_size_bytes(), | |
| 1830 false); | |
| 1731 } | 1831 } |
| 1732 | 1832 |
| 1733 | 1833 |
| 1734 // Tag append functions are overloaded for |ProfileCodeTrieNode| and | 1834 // Tag append functions are overloaded for |ProfileCodeTrieNode| and |
| 1735 // |ProfileFunctionTrieNode| types. | 1835 // |ProfileFunctionTrieNode| types. |
| 1736 | 1836 |
| 1737 // ProfileCodeTrieNode | 1837 // ProfileCodeTrieNode |
| 1738 ProfileCodeTrieNode* AppendUserTag(uword user_tag, | 1838 ProfileCodeTrieNode* AppendUserTag(uword user_tag, |
| 1739 ProfileCodeTrieNode* current) { | 1839 ProfileCodeTrieNode* current, |
| 1840 ProcessedSample* sample) { | |
| 1740 intptr_t user_tag_index = GetProfileCodeTagIndex(user_tag); | 1841 intptr_t user_tag_index = GetProfileCodeTagIndex(user_tag); |
| 1741 if (user_tag_index >= 0) { | 1842 if (user_tag_index >= 0) { |
| 1742 current = current->GetChild(user_tag_index); | 1843 current = current->GetChild(user_tag_index); |
| 1743 current->Tick(); | 1844 current->Tick(); |
| 1845 current->IncrementAllocation(sample->native_allocation_size_bytes(), | |
| 1846 false); | |
| 1744 } | 1847 } |
| 1745 return current; | 1848 return current; |
| 1746 } | 1849 } |
| 1747 | 1850 |
| 1748 ProfileCodeTrieNode* AppendTruncatedTag(ProfileCodeTrieNode* current) { | 1851 ProfileCodeTrieNode* AppendTruncatedTag(ProfileCodeTrieNode* current, |
| 1852 ProcessedSample* sample) { | |
| 1749 intptr_t truncated_tag_index = | 1853 intptr_t truncated_tag_index = |
| 1750 GetProfileCodeTagIndex(VMTag::kTruncatedTagId); | 1854 GetProfileCodeTagIndex(VMTag::kTruncatedTagId); |
| 1751 ASSERT(truncated_tag_index >= 0); | 1855 ASSERT(truncated_tag_index >= 0); |
| 1752 current = current->GetChild(truncated_tag_index); | 1856 current = current->GetChild(truncated_tag_index); |
| 1753 current->Tick(); | 1857 current->Tick(); |
| 1858 current->IncrementAllocation(sample->native_allocation_size_bytes(), false); | |
| 1754 return current; | 1859 return current; |
| 1755 } | 1860 } |
| 1756 | 1861 |
| 1757 ProfileCodeTrieNode* AppendVMTag(uword vm_tag, ProfileCodeTrieNode* current) { | 1862 ProfileCodeTrieNode* AppendVMTag(uword vm_tag, |
| 1863 ProfileCodeTrieNode* current, | |
| 1864 ProcessedSample* sample) { | |
| 1758 if (VMTag::IsNativeEntryTag(vm_tag)) { | 1865 if (VMTag::IsNativeEntryTag(vm_tag)) { |
| 1759 // Insert a dummy kNativeTagId node. | 1866 // Insert a dummy kNativeTagId node. |
| 1760 intptr_t tag_index = GetProfileCodeTagIndex(VMTag::kNativeTagId); | 1867 intptr_t tag_index = GetProfileCodeTagIndex(VMTag::kNativeTagId); |
| 1761 current = current->GetChild(tag_index); | 1868 current = current->GetChild(tag_index); |
| 1762 // Give the tag a tick. | 1869 // Give the tag a tick. |
| 1763 current->Tick(); | 1870 current->Tick(); |
| 1764 } else if (VMTag::IsRuntimeEntryTag(vm_tag)) { | 1871 } else if (VMTag::IsRuntimeEntryTag(vm_tag)) { |
| 1765 // Insert a dummy kRuntimeTagId node. | 1872 // Insert a dummy kRuntimeTagId node. |
| 1766 intptr_t tag_index = GetProfileCodeTagIndex(VMTag::kRuntimeTagId); | 1873 intptr_t tag_index = GetProfileCodeTagIndex(VMTag::kRuntimeTagId); |
| 1767 current = current->GetChild(tag_index); | 1874 current = current->GetChild(tag_index); |
| 1768 // Give the tag a tick. | 1875 // Give the tag a tick. |
| 1769 current->Tick(); | 1876 current->Tick(); |
| 1770 } else { | 1877 } else { |
| 1771 intptr_t tag_index = GetProfileCodeTagIndex(vm_tag); | 1878 intptr_t tag_index = GetProfileCodeTagIndex(vm_tag); |
| 1772 current = current->GetChild(tag_index); | 1879 current = current->GetChild(tag_index); |
| 1773 // Give the tag a tick. | 1880 // Give the tag a tick. |
| 1774 current->Tick(); | 1881 current->Tick(); |
| 1775 } | 1882 } |
| 1883 current->IncrementAllocation(sample->native_allocation_size_bytes(), false); | |
| 1776 return current; | 1884 return current; |
| 1777 } | 1885 } |
| 1778 | 1886 |
| 1779 ProfileCodeTrieNode* AppendSpecificNativeRuntimeEntryVMTag( | 1887 ProfileCodeTrieNode* AppendSpecificNativeRuntimeEntryVMTag( |
| 1780 uword vm_tag, | 1888 uword vm_tag, |
| 1781 ProfileCodeTrieNode* current) { | 1889 ProfileCodeTrieNode* current, |
| 1890 ProcessedSample* sample) { | |
| 1782 // Only Native and Runtime entries have a second VM tag. | 1891 // Only Native and Runtime entries have a second VM tag. |
| 1783 if (!VMTag::IsNativeEntryTag(vm_tag) && !VMTag::IsRuntimeEntryTag(vm_tag)) { | 1892 if (!VMTag::IsNativeEntryTag(vm_tag) && !VMTag::IsRuntimeEntryTag(vm_tag)) { |
| 1784 return current; | 1893 return current; |
| 1785 } | 1894 } |
| 1786 intptr_t tag_index = GetProfileCodeTagIndex(vm_tag); | 1895 intptr_t tag_index = GetProfileCodeTagIndex(vm_tag); |
| 1787 current = current->GetChild(tag_index); | 1896 current = current->GetChild(tag_index); |
| 1788 // Give the tag a tick. | 1897 // Give the tag a tick. |
| 1789 current->Tick(); | 1898 current->Tick(); |
| 1899 current->IncrementAllocation(sample->native_allocation_size_bytes(), false); | |
| 1790 return current; | 1900 return current; |
| 1791 } | 1901 } |
| 1792 | 1902 |
| 1793 uword ProfileInfoKindToVMTag(ProfileInfoKind kind) { | 1903 uword ProfileInfoKindToVMTag(ProfileInfoKind kind) { |
| 1794 switch (kind) { | 1904 switch (kind) { |
| 1795 case kNone: | 1905 case kNone: |
| 1796 return VMTag::kNoneCodeTagId; | 1906 return VMTag::kNoneCodeTagId; |
| 1797 case kOptimized: | 1907 case kOptimized: |
| 1798 return VMTag::kOptimizedCodeTagId; | 1908 return VMTag::kOptimizedCodeTagId; |
| 1799 case kUnoptimized: | 1909 case kUnoptimized: |
| 1800 return VMTag::kUnoptimizedCodeTagId; | 1910 return VMTag::kUnoptimizedCodeTagId; |
| 1801 case kNative: | 1911 case kNative: |
| 1802 return VMTag::kNativeCodeTagId; | 1912 return VMTag::kNativeCodeTagId; |
| 1803 case kInlineStart: | 1913 case kInlineStart: |
| 1804 return VMTag::kInlineStartCodeTagId; | 1914 return VMTag::kInlineStartCodeTagId; |
| 1805 case kInlineFinish: | 1915 case kInlineFinish: |
| 1806 return VMTag::kInlineEndCodeTagId; | 1916 return VMTag::kInlineEndCodeTagId; |
| 1807 default: | 1917 default: |
| 1808 UNIMPLEMENTED(); | 1918 UNIMPLEMENTED(); |
| 1809 return VMTag::kInvalidTagId; | 1919 return VMTag::kInvalidTagId; |
| 1810 } | 1920 } |
| 1811 } | 1921 } |
| 1812 | 1922 |
| 1813 ProfileCodeTrieNode* AppendKind(ProfileInfoKind kind, | 1923 ProfileCodeTrieNode* AppendKind(ProfileInfoKind kind, |
| 1814 ProfileCodeTrieNode* current) { | 1924 ProfileCodeTrieNode* current, |
| 1925 ProcessedSample* sample) { | |
| 1815 if (!TagsEnabled(ProfilerService::kCodeTransitionTagsBit)) { | 1926 if (!TagsEnabled(ProfilerService::kCodeTransitionTagsBit)) { |
| 1816 // Only emit if debug tags are requested. | 1927 // Only emit if debug tags are requested. |
| 1817 return current; | 1928 return current; |
| 1818 } | 1929 } |
| 1819 if (kind != info_kind_) { | 1930 if (kind != info_kind_) { |
| 1820 info_kind_ = kind; | 1931 info_kind_ = kind; |
| 1821 intptr_t tag_index = GetProfileCodeTagIndex(ProfileInfoKindToVMTag(kind)); | 1932 intptr_t tag_index = GetProfileCodeTagIndex(ProfileInfoKindToVMTag(kind)); |
| 1822 ASSERT(tag_index >= 0); | 1933 ASSERT(tag_index >= 0); |
| 1823 current = current->GetChild(tag_index); | 1934 current = current->GetChild(tag_index); |
| 1824 current->Tick(); | 1935 current->Tick(); |
| 1936 current->IncrementAllocation(sample->native_allocation_size_bytes(), | |
| 1937 false); | |
| 1825 } | 1938 } |
| 1826 return current; | 1939 return current; |
| 1827 } | 1940 } |
| 1828 | 1941 |
| 1829 ProfileCodeTrieNode* AppendKind(const Code& code, | 1942 ProfileCodeTrieNode* AppendKind(const Code& code, |
| 1830 ProfileCodeTrieNode* current) { | 1943 ProfileCodeTrieNode* current, |
| 1944 ProcessedSample* sample) { | |
| 1831 if (code.IsNull()) { | 1945 if (code.IsNull()) { |
| 1832 return AppendKind(kNone, current); | 1946 return AppendKind(kNone, current, sample); |
| 1833 } else if (code.is_optimized()) { | 1947 } else if (code.is_optimized()) { |
| 1834 return AppendKind(kOptimized, current); | 1948 return AppendKind(kOptimized, current, sample); |
| 1835 } else { | 1949 } else { |
| 1836 return AppendKind(kUnoptimized, current); | 1950 return AppendKind(kUnoptimized, current, sample); |
| 1837 } | 1951 } |
| 1838 } | 1952 } |
| 1839 | 1953 |
| 1840 ProfileCodeTrieNode* AppendVMTags(uword vm_tag, | 1954 ProfileCodeTrieNode* AppendVMTags(uword vm_tag, |
| 1841 ProfileCodeTrieNode* current) { | 1955 ProfileCodeTrieNode* current, |
| 1842 current = AppendVMTag(vm_tag, current); | 1956 ProcessedSample* sample) { |
| 1843 current = AppendSpecificNativeRuntimeEntryVMTag(vm_tag, current); | 1957 current = AppendVMTag(vm_tag, current, sample); |
| 1958 current = AppendSpecificNativeRuntimeEntryVMTag(vm_tag, current, sample); | |
| 1844 return current; | 1959 return current; |
| 1845 } | 1960 } |
| 1846 | 1961 |
| 1847 void TickExitFrame(uword vm_tag, intptr_t serial) { | 1962 void TickExitFrame(uword vm_tag, intptr_t serial, ProcessedSample* sample) { |
| 1848 if (FLAG_profile_vm) { | 1963 if (FLAG_profile_vm) { |
| 1849 return; | 1964 return; |
| 1850 } | 1965 } |
| 1851 if (!VMTag::IsExitFrameTag(vm_tag)) { | 1966 if (!VMTag::IsExitFrameTag(vm_tag)) { |
| 1852 return; | 1967 return; |
| 1853 } | 1968 } |
| 1854 ProfileCodeTable* tag_table = profile_->tag_code_; | 1969 ProfileCodeTable* tag_table = profile_->tag_code_; |
| 1855 ProfileCode* code = tag_table->FindCodeForPC(vm_tag); | 1970 ProfileCode* code = tag_table->FindCodeForPC(vm_tag); |
| 1856 ASSERT(code != NULL); | 1971 ASSERT(code != NULL); |
| 1857 code->Tick(vm_tag, true, serial); | 1972 code->Tick(vm_tag, true, serial, sample); |
| 1858 } | 1973 } |
| 1859 | 1974 |
| 1860 void TickExitFrameFunction(uword vm_tag, intptr_t serial) { | 1975 void TickExitFrameFunction(uword vm_tag, |
| 1976 intptr_t serial, | |
| 1977 ProcessedSample* sample) { | |
| 1861 if (FLAG_profile_vm) { | 1978 if (FLAG_profile_vm) { |
| 1862 return; | 1979 return; |
| 1863 } | 1980 } |
| 1864 if (!VMTag::IsExitFrameTag(vm_tag)) { | 1981 if (!VMTag::IsExitFrameTag(vm_tag)) { |
| 1865 return; | 1982 return; |
| 1866 } | 1983 } |
| 1867 ProfileCodeTable* tag_table = profile_->tag_code_; | 1984 ProfileCodeTable* tag_table = profile_->tag_code_; |
| 1868 ProfileCode* code = tag_table->FindCodeForPC(vm_tag); | 1985 ProfileCode* code = tag_table->FindCodeForPC(vm_tag); |
| 1869 ASSERT(code != NULL); | 1986 ASSERT(code != NULL); |
| 1870 ProfileFunction* function = code->function(); | 1987 ProfileFunction* function = code->function(); |
| 1871 ASSERT(function != NULL); | 1988 ASSERT(function != NULL); |
| 1872 function->Tick(true, serial, TokenPosition::kNoSource); | 1989 function->Tick(true, serial, TokenPosition::kNoSource, sample); |
| 1873 } | 1990 } |
| 1874 | 1991 |
| 1875 ProfileCodeTrieNode* AppendExitFrame(uword vm_tag, | 1992 ProfileCodeTrieNode* AppendExitFrame(uword vm_tag, |
| 1876 ProfileCodeTrieNode* current) { | 1993 ProfileCodeTrieNode* current, |
| 1994 ProcessedSample* sample) { | |
| 1877 if (FLAG_profile_vm) { | 1995 if (FLAG_profile_vm) { |
| 1878 return current; | 1996 return current; |
| 1879 } | 1997 } |
| 1880 | 1998 |
| 1881 if (!VMTag::IsExitFrameTag(vm_tag)) { | 1999 if (!VMTag::IsExitFrameTag(vm_tag)) { |
| 1882 return current; | 2000 return current; |
| 1883 } | 2001 } |
| 1884 | 2002 |
| 1885 if (VMTag::IsNativeEntryTag(vm_tag) || VMTag::IsRuntimeEntryTag(vm_tag)) { | 2003 if (VMTag::IsNativeEntryTag(vm_tag) || VMTag::IsRuntimeEntryTag(vm_tag)) { |
| 1886 current = AppendSpecificNativeRuntimeEntryVMTag(vm_tag, current); | 2004 current = AppendSpecificNativeRuntimeEntryVMTag(vm_tag, current, sample); |
| 1887 } else { | 2005 } else { |
| 1888 intptr_t tag_index = GetProfileCodeTagIndex(vm_tag); | 2006 intptr_t tag_index = GetProfileCodeTagIndex(vm_tag); |
| 1889 current = current->GetChild(tag_index); | 2007 current = current->GetChild(tag_index); |
| 1890 // Give the tag a tick. | 2008 // Give the tag a tick. |
| 1891 current->Tick(); | 2009 current->Tick(); |
| 2010 current->IncrementAllocation(sample->native_allocation_size_bytes(), | |
| 2011 false); | |
| 1892 } | 2012 } |
| 1893 return current; | 2013 return current; |
| 1894 } | 2014 } |
| 1895 | 2015 |
| 1896 ProfileCodeTrieNode* AppendTags(uword vm_tag, | 2016 ProfileCodeTrieNode* AppendTags(uword vm_tag, |
| 1897 uword user_tag, | 2017 uword user_tag, |
| 1898 ProfileCodeTrieNode* current) { | 2018 ProfileCodeTrieNode* current, |
| 2019 ProcessedSample* sample) { | |
| 1899 if (FLAG_profile_vm) { | 2020 if (FLAG_profile_vm) { |
| 1900 // None. | 2021 // None. |
| 1901 if (tag_order() == Profile::kNoTags) { | 2022 if (tag_order() == Profile::kNoTags) { |
| 1902 return current; | 2023 return current; |
| 1903 } | 2024 } |
| 1904 // User first. | 2025 // User first. |
| 1905 if ((tag_order() == Profile::kUserVM) || | 2026 if ((tag_order() == Profile::kUserVM) || |
| 1906 (tag_order() == Profile::kUser)) { | 2027 (tag_order() == Profile::kUser)) { |
| 1907 current = AppendUserTag(user_tag, current); | 2028 current = AppendUserTag(user_tag, current, sample); |
| 1908 // Only user. | 2029 // Only user. |
| 1909 if (tag_order() == Profile::kUser) { | 2030 if (tag_order() == Profile::kUser) { |
| 1910 return current; | 2031 return current; |
| 1911 } | 2032 } |
| 1912 return AppendVMTags(vm_tag, current); | 2033 return AppendVMTags(vm_tag, current, sample); |
| 1913 } | 2034 } |
| 1914 // VM first. | 2035 // VM first. |
| 1915 ASSERT((tag_order() == Profile::kVMUser) || | 2036 ASSERT((tag_order() == Profile::kVMUser) || |
| 1916 (tag_order() == Profile::kVM)); | 2037 (tag_order() == Profile::kVM)); |
| 1917 current = AppendVMTags(vm_tag, current); | 2038 current = AppendVMTags(vm_tag, current, sample); |
| 1918 // Only VM. | 2039 // Only VM. |
| 1919 if (tag_order() == Profile::kVM) { | 2040 if (tag_order() == Profile::kVM) { |
| 1920 return current; | 2041 return current; |
| 1921 } | 2042 } |
| 1922 return AppendUserTag(user_tag, current); | 2043 return AppendUserTag(user_tag, current, sample); |
| 1923 } | 2044 } |
| 1924 | 2045 |
| 1925 if (tag_order() == Profile::kNoTags) { | 2046 if (tag_order() == Profile::kNoTags) { |
| 1926 return current; | 2047 return current; |
| 1927 } | 2048 } |
| 1928 | 2049 |
| 1929 return AppendUserTag(user_tag, current); | 2050 return AppendUserTag(user_tag, current, sample); |
| 1930 } | 2051 } |
| 1931 | 2052 |
| 1932 // ProfileFunctionTrieNode | 2053 // ProfileFunctionTrieNode |
| 1933 void ResetKind() { info_kind_ = kNone; } | 2054 void ResetKind() { info_kind_ = kNone; } |
| 1934 | 2055 |
| 1935 ProfileFunctionTrieNode* AppendKind(ProfileInfoKind kind, | 2056 ProfileFunctionTrieNode* AppendKind(ProfileInfoKind kind, |
| 1936 ProfileFunctionTrieNode* current) { | 2057 ProfileFunctionTrieNode* current, |
| 2058 ProcessedSample* sample) { | |
| 1937 if (!TagsEnabled(ProfilerService::kCodeTransitionTagsBit)) { | 2059 if (!TagsEnabled(ProfilerService::kCodeTransitionTagsBit)) { |
| 1938 // Only emit if debug tags are requested. | 2060 // Only emit if debug tags are requested. |
| 1939 return current; | 2061 return current; |
| 1940 } | 2062 } |
| 1941 if (kind != info_kind_) { | 2063 if (kind != info_kind_) { |
| 1942 info_kind_ = kind; | 2064 info_kind_ = kind; |
| 1943 intptr_t tag_index = | 2065 intptr_t tag_index = |
| 1944 GetProfileFunctionTagIndex(ProfileInfoKindToVMTag(kind)); | 2066 GetProfileFunctionTagIndex(ProfileInfoKindToVMTag(kind)); |
| 1945 ASSERT(tag_index >= 0); | 2067 ASSERT(tag_index >= 0); |
| 1946 current = current->GetChild(tag_index); | 2068 current = current->GetChild(tag_index); |
| 1947 current->Tick(); | 2069 current->Tick(); |
| 2070 current->IncrementAllocation(sample->native_allocation_size_bytes(), | |
| 2071 false); | |
| 1948 } | 2072 } |
| 1949 return current; | 2073 return current; |
| 1950 } | 2074 } |
| 1951 | 2075 |
| 1952 ProfileFunctionTrieNode* AppendKind(const Code& code, | 2076 ProfileFunctionTrieNode* AppendKind(const Code& code, |
| 1953 ProfileFunctionTrieNode* current) { | 2077 ProfileFunctionTrieNode* current, |
| 2078 ProcessedSample* sample) { | |
| 1954 if (code.IsNull()) { | 2079 if (code.IsNull()) { |
| 1955 return AppendKind(kNone, current); | 2080 return AppendKind(kNone, current, sample); |
| 1956 } else if (code.is_optimized()) { | 2081 } else if (code.is_optimized()) { |
| 1957 return AppendKind(kOptimized, current); | 2082 return AppendKind(kOptimized, current, sample); |
| 1958 } else { | 2083 } else { |
| 1959 return AppendKind(kUnoptimized, current); | 2084 return AppendKind(kUnoptimized, current, sample); |
| 1960 } | 2085 } |
| 1961 } | 2086 } |
| 1962 | 2087 |
| 1963 ProfileFunctionTrieNode* AppendUserTag(uword user_tag, | 2088 ProfileFunctionTrieNode* AppendUserTag(uword user_tag, |
| 1964 ProfileFunctionTrieNode* current) { | 2089 ProfileFunctionTrieNode* current, |
| 2090 ProcessedSample* sample) { | |
| 1965 intptr_t user_tag_index = GetProfileFunctionTagIndex(user_tag); | 2091 intptr_t user_tag_index = GetProfileFunctionTagIndex(user_tag); |
| 1966 if (user_tag_index >= 0) { | 2092 if (user_tag_index >= 0) { |
| 1967 current = current->GetChild(user_tag_index); | 2093 current = current->GetChild(user_tag_index); |
| 1968 current->Tick(); | 2094 current->Tick(); |
| 2095 current->IncrementAllocation(sample->native_allocation_size_bytes(), | |
| 2096 false); | |
| 1969 } | 2097 } |
| 1970 return current; | 2098 return current; |
| 1971 } | 2099 } |
| 1972 | 2100 |
| 1973 ProfileFunctionTrieNode* AppendTruncatedTag( | 2101 ProfileFunctionTrieNode* AppendTruncatedTag(ProfileFunctionTrieNode* current, |
| 1974 ProfileFunctionTrieNode* current) { | 2102 ProcessedSample* sample) { |
| 1975 intptr_t truncated_tag_index = | 2103 intptr_t truncated_tag_index = |
| 1976 GetProfileFunctionTagIndex(VMTag::kTruncatedTagId); | 2104 GetProfileFunctionTagIndex(VMTag::kTruncatedTagId); |
| 1977 ASSERT(truncated_tag_index >= 0); | 2105 ASSERT(truncated_tag_index >= 0); |
| 1978 current = current->GetChild(truncated_tag_index); | 2106 current = current->GetChild(truncated_tag_index); |
| 1979 current->Tick(); | 2107 current->Tick(); |
| 2108 current->IncrementAllocation(sample->native_allocation_size_bytes(), false); | |
| 1980 return current; | 2109 return current; |
| 1981 } | 2110 } |
| 1982 | 2111 |
| 1983 ProfileFunctionTrieNode* AppendVMTag(uword vm_tag, | 2112 ProfileFunctionTrieNode* AppendVMTag(uword vm_tag, |
| 1984 ProfileFunctionTrieNode* current) { | 2113 ProfileFunctionTrieNode* current, |
| 2114 ProcessedSample* sample) { | |
| 1985 if (VMTag::IsNativeEntryTag(vm_tag)) { | 2115 if (VMTag::IsNativeEntryTag(vm_tag)) { |
| 1986 // Insert a dummy kNativeTagId node. | 2116 // Insert a dummy kNativeTagId node. |
| 1987 intptr_t tag_index = GetProfileFunctionTagIndex(VMTag::kNativeTagId); | 2117 intptr_t tag_index = GetProfileFunctionTagIndex(VMTag::kNativeTagId); |
| 1988 current = current->GetChild(tag_index); | 2118 current = current->GetChild(tag_index); |
| 1989 // Give the tag a tick. | 2119 // Give the tag a tick. |
| 1990 current->Tick(); | 2120 current->Tick(); |
| 1991 } else if (VMTag::IsRuntimeEntryTag(vm_tag)) { | 2121 } else if (VMTag::IsRuntimeEntryTag(vm_tag)) { |
| 1992 // Insert a dummy kRuntimeTagId node. | 2122 // Insert a dummy kRuntimeTagId node. |
| 1993 intptr_t tag_index = GetProfileFunctionTagIndex(VMTag::kRuntimeTagId); | 2123 intptr_t tag_index = GetProfileFunctionTagIndex(VMTag::kRuntimeTagId); |
| 1994 current = current->GetChild(tag_index); | 2124 current = current->GetChild(tag_index); |
| 1995 // Give the tag a tick. | 2125 // Give the tag a tick. |
| 1996 current->Tick(); | 2126 current->Tick(); |
| 1997 } else { | 2127 } else { |
| 1998 intptr_t tag_index = GetProfileFunctionTagIndex(vm_tag); | 2128 intptr_t tag_index = GetProfileFunctionTagIndex(vm_tag); |
| 1999 current = current->GetChild(tag_index); | 2129 current = current->GetChild(tag_index); |
| 2000 // Give the tag a tick. | 2130 // Give the tag a tick. |
| 2001 current->Tick(); | 2131 current->Tick(); |
| 2002 } | 2132 } |
| 2133 current->IncrementAllocation(sample->native_allocation_size_bytes(), false); | |
| 2003 return current; | 2134 return current; |
| 2004 } | 2135 } |
| 2005 | 2136 |
| 2006 ProfileFunctionTrieNode* AppendSpecificNativeRuntimeEntryVMTag( | 2137 ProfileFunctionTrieNode* AppendSpecificNativeRuntimeEntryVMTag( |
| 2007 uword vm_tag, | 2138 uword vm_tag, |
| 2008 ProfileFunctionTrieNode* current) { | 2139 ProfileFunctionTrieNode* current, |
| 2140 ProcessedSample* sample) { | |
| 2009 // Only Native and Runtime entries have a second VM tag. | 2141 // Only Native and Runtime entries have a second VM tag. |
| 2010 if (!VMTag::IsNativeEntryTag(vm_tag) && !VMTag::IsRuntimeEntryTag(vm_tag)) { | 2142 if (!VMTag::IsNativeEntryTag(vm_tag) && !VMTag::IsRuntimeEntryTag(vm_tag)) { |
| 2011 return current; | 2143 return current; |
| 2012 } | 2144 } |
| 2013 intptr_t tag_index = GetProfileFunctionTagIndex(vm_tag); | 2145 intptr_t tag_index = GetProfileFunctionTagIndex(vm_tag); |
| 2014 current = current->GetChild(tag_index); | 2146 current = current->GetChild(tag_index); |
| 2015 // Give the tag a tick. | 2147 // Give the tag a tick. |
| 2016 current->Tick(); | 2148 current->Tick(); |
| 2149 current->IncrementAllocation(sample->native_allocation_size_bytes(), false); | |
| 2017 return current; | 2150 return current; |
| 2018 } | 2151 } |
| 2019 | 2152 |
| 2020 ProfileFunctionTrieNode* AppendVMTags(uword vm_tag, | 2153 ProfileFunctionTrieNode* AppendVMTags(uword vm_tag, |
| 2021 ProfileFunctionTrieNode* current) { | 2154 ProfileFunctionTrieNode* current, |
| 2022 current = AppendVMTag(vm_tag, current); | 2155 ProcessedSample* sample) { |
| 2023 current = AppendSpecificNativeRuntimeEntryVMTag(vm_tag, current); | 2156 current = AppendVMTag(vm_tag, current, sample); |
| 2157 current = AppendSpecificNativeRuntimeEntryVMTag(vm_tag, current, sample); | |
| 2024 return current; | 2158 return current; |
| 2025 } | 2159 } |
| 2026 | 2160 |
| 2027 ProfileFunctionTrieNode* AppendExitFrame(uword vm_tag, | 2161 ProfileFunctionTrieNode* AppendExitFrame(uword vm_tag, |
| 2028 ProfileFunctionTrieNode* current) { | 2162 ProfileFunctionTrieNode* current, |
| 2163 ProcessedSample* sample) { | |
| 2029 if (FLAG_profile_vm) { | 2164 if (FLAG_profile_vm) { |
| 2030 return current; | 2165 return current; |
| 2031 } | 2166 } |
| 2032 | 2167 |
| 2033 if (!VMTag::IsExitFrameTag(vm_tag)) { | 2168 if (!VMTag::IsExitFrameTag(vm_tag)) { |
| 2034 return current; | 2169 return current; |
| 2035 } | 2170 } |
| 2036 if (VMTag::IsNativeEntryTag(vm_tag) || VMTag::IsRuntimeEntryTag(vm_tag)) { | 2171 if (VMTag::IsNativeEntryTag(vm_tag) || VMTag::IsRuntimeEntryTag(vm_tag)) { |
| 2037 current = AppendSpecificNativeRuntimeEntryVMTag(vm_tag, current); | 2172 current = AppendSpecificNativeRuntimeEntryVMTag(vm_tag, current, sample); |
| 2038 } else { | 2173 } else { |
| 2039 intptr_t tag_index = GetProfileFunctionTagIndex(vm_tag); | 2174 intptr_t tag_index = GetProfileFunctionTagIndex(vm_tag); |
| 2040 current = current->GetChild(tag_index); | 2175 current = current->GetChild(tag_index); |
| 2041 // Give the tag a tick. | 2176 // Give the tag a tick. |
| 2042 current->Tick(); | 2177 current->Tick(); |
| 2178 current->IncrementAllocation(sample->native_allocation_size_bytes(), | |
| 2179 false); | |
| 2043 } | 2180 } |
| 2044 return current; | 2181 return current; |
| 2045 } | 2182 } |
| 2046 | 2183 |
| 2047 ProfileFunctionTrieNode* AppendTags(uword vm_tag, | 2184 ProfileFunctionTrieNode* AppendTags(uword vm_tag, |
| 2048 uword user_tag, | 2185 uword user_tag, |
| 2049 ProfileFunctionTrieNode* current) { | 2186 ProfileFunctionTrieNode* current, |
| 2187 ProcessedSample* sample) { | |
| 2050 if (FLAG_profile_vm) { | 2188 if (FLAG_profile_vm) { |
| 2051 // None. | 2189 // None. |
| 2052 if (tag_order() == Profile::kNoTags) { | 2190 if (tag_order() == Profile::kNoTags) { |
| 2053 return current; | 2191 return current; |
| 2054 } | 2192 } |
| 2055 // User first. | 2193 // User first. |
| 2056 if ((tag_order() == Profile::kUserVM) || | 2194 if ((tag_order() == Profile::kUserVM) || |
| 2057 (tag_order() == Profile::kUser)) { | 2195 (tag_order() == Profile::kUser)) { |
| 2058 current = AppendUserTag(user_tag, current); | 2196 current = AppendUserTag(user_tag, current, sample); |
| 2059 // Only user. | 2197 // Only user. |
| 2060 if (tag_order() == Profile::kUser) { | 2198 if (tag_order() == Profile::kUser) { |
| 2061 return current; | 2199 return current; |
| 2062 } | 2200 } |
| 2063 return AppendVMTags(vm_tag, current); | 2201 return AppendVMTags(vm_tag, current, sample); |
| 2064 } | 2202 } |
| 2065 // VM first. | 2203 // VM first. |
| 2066 ASSERT((tag_order() == Profile::kVMUser) || | 2204 ASSERT((tag_order() == Profile::kVMUser) || |
| 2067 (tag_order() == Profile::kVM)); | 2205 (tag_order() == Profile::kVM)); |
| 2068 current = AppendVMTags(vm_tag, current); | 2206 current = AppendVMTags(vm_tag, current, sample); |
| 2069 // Only VM. | 2207 // Only VM. |
| 2070 if (tag_order() == Profile::kVM) { | 2208 if (tag_order() == Profile::kVM) { |
| 2071 return current; | 2209 return current; |
| 2072 } | 2210 } |
| 2073 return AppendUserTag(user_tag, current); | 2211 return AppendUserTag(user_tag, current, sample); |
| 2074 } | 2212 } |
| 2075 | 2213 |
| 2076 if (tag_order() == Profile::kNoTags) { | 2214 if (tag_order() == Profile::kNoTags) { |
| 2077 return current; | 2215 return current; |
| 2078 } | 2216 } |
| 2079 | 2217 |
| 2080 return AppendUserTag(user_tag, current); | 2218 return AppendUserTag(user_tag, current, sample); |
| 2081 } | 2219 } |
| 2082 | 2220 |
| 2083 intptr_t GetProfileCodeTagIndex(uword tag) { | 2221 intptr_t GetProfileCodeTagIndex(uword tag) { |
| 2084 ProfileCodeTable* tag_table = profile_->tag_code_; | 2222 ProfileCodeTable* tag_table = profile_->tag_code_; |
| 2085 intptr_t index = tag_table->FindCodeIndexForPC(tag); | 2223 intptr_t index = tag_table->FindCodeIndexForPC(tag); |
| 2086 ASSERT(index >= 0); | 2224 ASSERT(index >= 0); |
| 2087 ProfileCode* code = tag_table->At(index); | 2225 ProfileCode* code = tag_table->At(index); |
| 2088 ASSERT(code != NULL); | 2226 ASSERT(code != NULL); |
| 2089 return code->code_table_index(); | 2227 return code->code_table_index(); |
| 2090 } | 2228 } |
| (...skipping 629 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2720 (sample->allocation_cid() == cls_.id()); | 2858 (sample->allocation_cid() == cls_.id()); |
| 2721 } | 2859 } |
| 2722 | 2860 |
| 2723 private: | 2861 private: |
| 2724 const Class& cls_; | 2862 const Class& cls_; |
| 2725 }; | 2863 }; |
| 2726 | 2864 |
| 2727 | 2865 |
| 2728 class NativeAllocationSampleFilter : public SampleFilter { | 2866 class NativeAllocationSampleFilter : public SampleFilter { |
| 2729 public: | 2867 public: |
| 2730 NativeAllocationSampleFilter(intptr_t thread_task_mask, | 2868 NativeAllocationSampleFilter(int64_t time_origin_micros, |
| 2731 int64_t time_origin_micros, | |
| 2732 int64_t time_extent_micros) | 2869 int64_t time_extent_micros) |
| 2733 : SampleFilter(ILLEGAL_PORT, | 2870 : SampleFilter(ILLEGAL_PORT, |
| 2734 thread_task_mask, | 2871 SampleFilter::kNoTaskFilter, |
| 2735 time_origin_micros, | 2872 time_origin_micros, |
| 2736 time_extent_micros) {} | 2873 time_extent_micros) {} |
| 2737 bool FilterSample(Sample* sample) { | 2874 bool FilterSample(Sample* sample) { |
| 2738 return sample->is_native_allocation_sample(); | 2875 return sample->is_native_allocation_sample() && |
| 2876 !sample->NativeAllocationFreed(); | |
| 2739 } | 2877 } |
| 2740 }; | 2878 }; |
| 2741 | 2879 |
| 2742 | 2880 |
| 2743 void ProfilerService::PrintAllocationJSON(JSONStream* stream, | 2881 void ProfilerService::PrintAllocationJSON(JSONStream* stream, |
| 2744 Profile::TagOrder tag_order, | 2882 Profile::TagOrder tag_order, |
| 2745 const Class& cls, | 2883 const Class& cls, |
| 2746 int64_t time_origin_micros, | 2884 int64_t time_origin_micros, |
| 2747 int64_t time_extent_micros) { | 2885 int64_t time_extent_micros) { |
| 2748 Thread* thread = Thread::Current(); | 2886 Thread* thread = Thread::Current(); |
| 2749 Isolate* isolate = thread->isolate(); | 2887 Isolate* isolate = thread->isolate(); |
| 2750 ClassAllocationSampleFilter filter(isolate->main_port(), cls, | 2888 ClassAllocationSampleFilter filter(isolate->main_port(), cls, |
| 2751 Thread::kMutatorTask, time_origin_micros, | 2889 Thread::kMutatorTask, time_origin_micros, |
| 2752 time_extent_micros); | 2890 time_extent_micros); |
| 2753 const bool as_timeline = false; | 2891 const bool as_timeline = false; |
| 2754 PrintJSONImpl(thread, stream, tag_order, kNoExtraTags, &filter, as_timeline); | 2892 PrintJSONImpl(thread, stream, tag_order, kNoExtraTags, &filter, as_timeline); |
| 2755 } | 2893 } |
| 2756 | 2894 |
| 2757 | 2895 |
| 2758 void ProfilerService::PrintNativeAllocationJSON(JSONStream* stream, | 2896 void ProfilerService::PrintNativeAllocationJSON(JSONStream* stream, |
| 2759 Profile::TagOrder tag_order, | 2897 Profile::TagOrder tag_order, |
| 2760 int64_t time_origin_micros, | 2898 int64_t time_origin_micros, |
| 2761 int64_t time_extent_micros) { | 2899 int64_t time_extent_micros) { |
| 2762 Thread* thread = Thread::Current(); | 2900 Thread* thread = Thread::Current(); |
| 2763 const intptr_t thread_task_mask = Thread::kMutatorTask | | 2901 NativeAllocationSampleFilter filter(time_origin_micros, time_extent_micros); |
| 2764 Thread::kCompilerTask | | |
| 2765 Thread::kSweeperTask | Thread::kMarkerTask; | |
| 2766 NativeAllocationSampleFilter filter(thread_task_mask, time_origin_micros, | |
| 2767 time_extent_micros); | |
| 2768 const bool as_timeline = false; | 2902 const bool as_timeline = false; |
| 2769 PrintJSONImpl(thread, stream, tag_order, kNoExtraTags, &filter, as_timeline); | 2903 PrintJSONImpl(thread, stream, tag_order, kNoExtraTags, &filter, as_timeline); |
| 2770 } | 2904 } |
| 2771 | 2905 |
| 2772 | 2906 |
| 2773 void ProfilerService::PrintTimelineJSON(JSONStream* stream, | 2907 void ProfilerService::PrintTimelineJSON(JSONStream* stream, |
| 2774 Profile::TagOrder tag_order, | 2908 Profile::TagOrder tag_order, |
| 2775 int64_t time_origin_micros, | 2909 int64_t time_origin_micros, |
| 2776 int64_t time_extent_micros) { | 2910 int64_t time_extent_micros) { |
| 2777 Thread* thread = Thread::Current(); | 2911 Thread* thread = Thread::Current(); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 2798 // Disable thread interrupts while processing the buffer. | 2932 // Disable thread interrupts while processing the buffer. |
| 2799 DisableThreadInterruptsScope dtis(thread); | 2933 DisableThreadInterruptsScope dtis(thread); |
| 2800 | 2934 |
| 2801 ClearProfileVisitor clear_profile(isolate); | 2935 ClearProfileVisitor clear_profile(isolate); |
| 2802 sample_buffer->VisitSamples(&clear_profile); | 2936 sample_buffer->VisitSamples(&clear_profile); |
| 2803 } | 2937 } |
| 2804 | 2938 |
| 2805 #endif // !PRODUCT | 2939 #endif // !PRODUCT |
| 2806 | 2940 |
| 2807 } // namespace dart | 2941 } // namespace dart |
| OLD | NEW |