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

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

Issue 2748403002: Added page to Observatory to display native memory allocation information. (Closed)
Patch Set: Added tests to verify sample tries inclusive/exclusive allocations. Element now displays memory con… Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« runtime/vm/profiler_service.h ('K') | « runtime/vm/profiler_service.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/profiler_service.h" 5 #include "vm/profiler_service.h"
6 6
7 #include "vm/growable_array.h" 7 #include "vm/growable_array.h"
8 #include "vm/hash_map.h" 8 #include "vm/hash_map.h"
9 #include "vm/log.h" 9 #include "vm/log.h"
10 #include "vm/native_symbol.h" 10 #include "vm/native_symbol.h"
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« runtime/vm/profiler_service.h ('K') | « runtime/vm/profiler_service.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698