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

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

Issue 1261963002: Refactor function tick code and add test (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 4 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
« no previous file with comments | « no previous file | runtime/vm/profiler_test.cc » ('j') | 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/native_symbol.h" 8 #include "vm/native_symbol.h"
9 #include "vm/object.h" 9 #include "vm/object.h"
10 #include "vm/os.h" 10 #include "vm/os.h"
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 } 110 }
111 ASSERT(!function_.IsNull()); 111 ASSERT(!function_.IsNull());
112 const String& func_name = 112 const String& func_name =
113 String::Handle(function_.QualifiedUserVisibleName()); 113 String::Handle(function_.QualifiedUserVisibleName());
114 return func_name.ToCString(); 114 return func_name.ToCString();
115 } 115 }
116 116
117 void ProfileFunction::Tick(bool exclusive, intptr_t inclusive_serial) { 117 void ProfileFunction::Tick(bool exclusive, intptr_t inclusive_serial) {
118 if (exclusive) { 118 if (exclusive) {
119 exclusive_ticks_++; 119 exclusive_ticks_++;
120 } else {
121 if (inclusive_serial_ == inclusive_serial) {
122 // Already ticket.
123 return;
124 }
125 inclusive_serial_ = inclusive_serial;
126 inclusive_ticks_++;
127 } 120 }
121 // Fall through and tick inclusive count too.
122 if (inclusive_serial_ == inclusive_serial) {
123 // Already ticked.
124 return;
125 }
126 inclusive_serial_ = inclusive_serial;
127 inclusive_ticks_++;
128 } 128 }
129 129
130 130
131 const char* ProfileFunction::KindToCString(Kind kind) { 131 const char* ProfileFunction::KindToCString(Kind kind) {
132 switch (kind) { 132 switch (kind) {
133 case kDartFunction: 133 case kDartFunction:
134 return "Dart"; 134 return "Dart";
135 case kNativeFunction: 135 case kNativeFunction:
136 return "Native"; 136 return "Native";
137 case kTagFunction: 137 case kTagFunction:
(...skipping 818 matching lines...) Expand 10 before | Expand all | Expand 10 after
956 Profile* profile) 956 Profile* profile)
957 : isolate_(isolate), 957 : isolate_(isolate),
958 vm_isolate_(Dart::vm_isolate()), 958 vm_isolate_(Dart::vm_isolate()),
959 filter_(filter), 959 filter_(filter),
960 tag_order_(tag_order), 960 tag_order_(tag_order),
961 profile_(profile), 961 profile_(profile),
962 deoptimized_code_(new DeoptimizedCodeSet(isolate)), 962 deoptimized_code_(new DeoptimizedCodeSet(isolate)),
963 null_code_(Code::ZoneHandle()), 963 null_code_(Code::ZoneHandle()),
964 null_function_(Function::ZoneHandle()), 964 null_function_(Function::ZoneHandle()),
965 tick_functions_(false), 965 tick_functions_(false),
966 inclusive_tree_(false),
966 samples_(NULL) { 967 samples_(NULL) {
967 ASSERT(profile_ != NULL); 968 ASSERT(profile_ != NULL);
968 } 969 }
969 970
970 void Build() { 971 void Build() {
971 ScopeTimer sw("ProfileBuilder::Build", FLAG_trace_profiler); 972 ScopeTimer sw("ProfileBuilder::Build", FLAG_trace_profiler);
972 FilterSamples(); 973 FilterSamples();
973 974
974 Setup(); 975 Setup();
975 BuildCodeTable(); 976 BuildCodeTable();
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1022 1023
1023 void UpdateMinMaxTimes(int64_t timestamp) { 1024 void UpdateMinMaxTimes(int64_t timestamp) {
1024 profile_->min_time_ = 1025 profile_->min_time_ =
1025 timestamp < profile_->min_time_ ? timestamp : profile_->min_time_; 1026 timestamp < profile_->min_time_ ? timestamp : profile_->min_time_;
1026 profile_->max_time_ = 1027 profile_->max_time_ =
1027 timestamp > profile_->max_time_ ? timestamp : profile_->max_time_; 1028 timestamp > profile_->max_time_ ? timestamp : profile_->max_time_;
1028 } 1029 }
1029 1030
1030 void BuildCodeTable() { 1031 void BuildCodeTable() {
1031 ScopeTimer sw("ProfileBuilder::BuildCodeTable", FLAG_trace_profiler); 1032 ScopeTimer sw("ProfileBuilder::BuildCodeTable", FLAG_trace_profiler);
1032 for (intptr_t i = 0; i < samples_->length(); i++) { 1033 for (intptr_t sample_index = 0;
1033 ProcessedSample* sample = samples_->At(i); 1034 sample_index < samples_->length();
1035 sample_index++) {
1036 ProcessedSample* sample = samples_->At(sample_index);
1034 const int64_t timestamp = sample->timestamp(); 1037 const int64_t timestamp = sample->timestamp();
1035 1038
1036 // This is our first pass over the sample buffer, use this as an 1039 // This is our first pass over the sample buffer, use this as an
1037 // opportunity to determine the min and max time ranges of this profile. 1040 // opportunity to determine the min and max time ranges of this profile.
1038 UpdateMinMaxTimes(timestamp); 1041 UpdateMinMaxTimes(timestamp);
1039 1042
1040 // Make sure VM tag exists. 1043 // Make sure VM tag exists.
1041 if (VMTag::IsNativeEntryTag(sample->vm_tag())) { 1044 if (VMTag::IsNativeEntryTag(sample->vm_tag())) {
1042 RegisterProfileCodeTag(VMTag::kNativeTagId); 1045 RegisterProfileCodeTag(VMTag::kNativeTagId);
1043 } else if (VMTag::IsRuntimeEntryTag(sample->vm_tag())) { 1046 } else if (VMTag::IsRuntimeEntryTag(sample->vm_tag())) {
1044 RegisterProfileCodeTag(VMTag::kRuntimeTagId); 1047 RegisterProfileCodeTag(VMTag::kRuntimeTagId);
1045 } 1048 }
1046 RegisterProfileCodeTag(sample->vm_tag()); 1049 RegisterProfileCodeTag(sample->vm_tag());
1047 // Make sure user tag exists. 1050 // Make sure user tag exists.
1048 RegisterProfileCodeTag(sample->user_tag()); 1051 RegisterProfileCodeTag(sample->user_tag());
1049 1052
1050 // Make sure that a ProfileCode objects exist for all pcs in the sample 1053 // Make sure that a ProfileCode objects exist for all pcs in the sample
1051 // and tick each one. 1054 // and tick each one.
1052 for (intptr_t j = 0; j < sample->length(); j++) { 1055 for (intptr_t frame_index = 0;
1053 const uword pc = sample->At(j); 1056 frame_index < sample->length();
1057 frame_index++) {
1058 const uword pc = sample->At(frame_index);
1054 ASSERT(pc != 0); 1059 ASSERT(pc != 0);
1055 ProfileCode* code = RegisterProfileCode(pc, timestamp); 1060 ProfileCode* code = RegisterProfileCode(pc, timestamp);
1056 ASSERT(code != NULL); 1061 ASSERT(code != NULL);
1057 code->Tick(pc, IsExecutingFrame(sample, j), i); 1062 code->Tick(pc, IsExecutingFrame(sample, frame_index), sample_index);
1058 } 1063 }
1059 } 1064 }
1060 } 1065 }
1061 1066
1062 void FinalizeCodeIndexes() { 1067 void FinalizeCodeIndexes() {
1063 ScopeTimer sw("ProfileBuilder::FinalizeCodeIndexes", FLAG_trace_profiler); 1068 ScopeTimer sw("ProfileBuilder::FinalizeCodeIndexes", FLAG_trace_profiler);
1064 ProfileCodeTable* live_table = profile_->live_code_; 1069 ProfileCodeTable* live_table = profile_->live_code_;
1065 ProfileCodeTable* dead_table = profile_->dead_code_; 1070 ProfileCodeTable* dead_table = profile_->dead_code_;
1066 ProfileCodeTable* tag_table = profile_->tag_code_; 1071 ProfileCodeTable* tag_table = profile_->tag_code_;
1067 const intptr_t dead_code_index_offset = live_table->length(); 1072 const intptr_t dead_code_index_offset = live_table->length();
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1114 for (intptr_t i = 0; i < tag_table->length(); i++) { 1119 for (intptr_t i = 0; i < tag_table->length(); i++) {
1115 ProfileCode* code = tag_table->At(i); 1120 ProfileCode* code = tag_table->At(i);
1116 ASSERT(code != NULL); 1121 ASSERT(code != NULL);
1117 code->SetFunctionAndName(function_table); 1122 code->SetFunctionAndName(function_table);
1118 } 1123 }
1119 } 1124 }
1120 1125
1121 void BuildCodeTrie(Profile::TrieKind kind) { 1126 void BuildCodeTrie(Profile::TrieKind kind) {
1122 ProfileCodeTrieNode* root = 1127 ProfileCodeTrieNode* root =
1123 new ProfileCodeTrieNode(GetProfileCodeTagIndex(VMTag::kRootTagId)); 1128 new ProfileCodeTrieNode(GetProfileCodeTagIndex(VMTag::kRootTagId));
1124 if (IsInclusiveTrie(kind)) { 1129 inclusive_tree_ = IsInclusiveTrie(kind);
1130 if (inclusive_tree_) {
1125 BuildInclusiveCodeTrie(root); 1131 BuildInclusiveCodeTrie(root);
1126 } else { 1132 } else {
1127 BuildExclusiveCodeTrie(root); 1133 BuildExclusiveCodeTrie(root);
1128 } 1134 }
1129 root->SortChildren(); 1135 root->SortChildren();
1130 profile_->roots_[static_cast<intptr_t>(kind)] = root; 1136 profile_->roots_[static_cast<intptr_t>(kind)] = root;
1131 } 1137 }
1132 1138
1133 void BuildInclusiveCodeTrie(ProfileCodeTrieNode* root) { 1139 void BuildInclusiveCodeTrie(ProfileCodeTrieNode* root) {
1134 ScopeTimer sw("ProfileBuilder::BuildInclusiveCodeTrie", 1140 ScopeTimer sw("ProfileBuilder::BuildInclusiveCodeTrie",
1135 FLAG_trace_profiler); 1141 FLAG_trace_profiler);
1136 for (intptr_t i = 0; i < samples_->length(); i++) { 1142 for (intptr_t sample_index = 0;
1137 ProcessedSample* sample = samples_->At(i); 1143 sample_index < samples_->length();
1144 sample_index++) {
1145 ProcessedSample* sample = samples_->At(sample_index);
1138 1146
1139 // Tick the root. 1147 // Tick the root.
1140 ProfileCodeTrieNode* current = root; 1148 ProfileCodeTrieNode* current = root;
1141 current->Tick(); 1149 current->Tick();
1142 1150
1143 // VM & User tags. 1151 // VM & User tags.
1144 current = AppendTags(sample->vm_tag(), sample->user_tag(), current); 1152 current = AppendTags(sample->vm_tag(), sample->user_tag(), current);
1145 1153
1146 // Truncated tag. 1154 // Truncated tag.
1147 if (sample->truncated()) { 1155 if (sample->truncated()) {
1148 current = AppendTruncatedTag(current); 1156 current = AppendTruncatedTag(current);
1149 } 1157 }
1150 1158
1151 // Walk the sampled PCs. 1159 // Walk the sampled PCs.
1152 for (intptr_t j = sample->length() - 1; j >= 0; j--) { 1160 for (intptr_t frame_index = sample->length() - 1;
1153 ASSERT(sample->At(j) != 0); 1161 frame_index >= 0;
1162 frame_index--) {
1163 ASSERT(sample->At(frame_index) != 0);
1154 intptr_t index = 1164 intptr_t index =
1155 GetProfileCodeIndex(sample->At(j), sample->timestamp()); 1165 GetProfileCodeIndex(sample->At(frame_index), sample->timestamp());
1156 ASSERT(index >= 0); 1166 ASSERT(index >= 0);
1157 current = current->GetChild(index); 1167 current = current->GetChild(index);
1158 current->Tick(); 1168 current->Tick();
1159 } 1169 }
1160 } 1170 }
1161 } 1171 }
1162 1172
1163 void BuildExclusiveCodeTrie(ProfileCodeTrieNode* root) { 1173 void BuildExclusiveCodeTrie(ProfileCodeTrieNode* root) {
1164 ScopeTimer sw("ProfileBuilder::BuildExclusiveCodeTrie", 1174 ScopeTimer sw("ProfileBuilder::BuildExclusiveCodeTrie",
1165 FLAG_trace_profiler); 1175 FLAG_trace_profiler);
1166 for (intptr_t i = 0; i < samples_->length(); i++) { 1176 for (intptr_t sample_index = 0;
1167 ProcessedSample* sample = samples_->At(i); 1177 sample_index < samples_->length();
1178 sample_index++) {
1179 ProcessedSample* sample = samples_->At(sample_index);
1168 1180
1169 // Tick the root. 1181 // Tick the root.
1170 ProfileCodeTrieNode* current = root; 1182 ProfileCodeTrieNode* current = root;
1171 current->Tick(); 1183 current->Tick();
1172 1184
1173 // VM & User tags. 1185 // VM & User tags.
1174 current = AppendTags(sample->vm_tag(), sample->user_tag(), current); 1186 current = AppendTags(sample->vm_tag(), sample->user_tag(), current);
1175 1187
1176 // Walk the sampled PCs. 1188 // Walk the sampled PCs.
1177 for (intptr_t j = 0; j < sample->length(); j++) { 1189 for (intptr_t frame_index = 0;
1178 ASSERT(sample->At(j) != 0); 1190 frame_index < sample->length();
1191 frame_index++) {
1192 ASSERT(sample->At(frame_index) != 0);
1179 intptr_t index = 1193 intptr_t index =
1180 GetProfileCodeIndex(sample->At(j), sample->timestamp()); 1194 GetProfileCodeIndex(sample->At(frame_index), sample->timestamp());
1181 ASSERT(index >= 0); 1195 ASSERT(index >= 0);
1182 current = current->GetChild(index); 1196 current = current->GetChild(index);
1183 current->Tick(); 1197 current->Tick();
1184 } 1198 }
1185 1199
1186 // Truncated tag. 1200 // Truncated tag.
1187 if (sample->truncated()) { 1201 if (sample->truncated()) {
1188 current = AppendTruncatedTag(current); 1202 current = AppendTruncatedTag(current);
1189 } 1203 }
1190 } 1204 }
1191 } 1205 }
1192 1206
1193 void BuildFunctionTrie(Profile::TrieKind kind) { 1207 void BuildFunctionTrie(Profile::TrieKind kind) {
1194 ProfileFunctionTrieNode* root = 1208 ProfileFunctionTrieNode* root =
1195 new ProfileFunctionTrieNode( 1209 new ProfileFunctionTrieNode(
1196 GetProfileFunctionTagIndex(VMTag::kRootTagId)); 1210 GetProfileFunctionTagIndex(VMTag::kRootTagId));
1197 // We tick the functions while building the trie, but, we don't want to do 1211 // We tick the functions while building the trie, but, we don't want to do
1198 // it for both tries, just one. 1212 // it for both tries, just the exclusive trie.
1199 tick_functions_ = IsInclusiveTrie(kind); 1213 inclusive_tree_ = IsInclusiveTrie(kind);
1200 if (IsInclusiveTrie(kind)) { 1214 tick_functions_ = !inclusive_tree_;
1215 if (inclusive_tree_) {
1201 BuildInclusiveFunctionTrie(root); 1216 BuildInclusiveFunctionTrie(root);
1202 } else { 1217 } else {
1203 BuildExclusiveFunctionTrie(root); 1218 BuildExclusiveFunctionTrie(root);
1204 } 1219 }
1205 root->SortChildren(); 1220 root->SortChildren();
1206 profile_->roots_[static_cast<intptr_t>(kind)] = root; 1221 profile_->roots_[static_cast<intptr_t>(kind)] = root;
1207 } 1222 }
1208 1223
1209 void BuildInclusiveFunctionTrie(ProfileFunctionTrieNode* root) { 1224 void BuildInclusiveFunctionTrie(ProfileFunctionTrieNode* root) {
1210 ScopeTimer sw("ProfileBuilder::BuildInclusiveFunctionTrie", 1225 ScopeTimer sw("ProfileBuilder::BuildInclusiveFunctionTrie",
1211 FLAG_trace_profiler); 1226 FLAG_trace_profiler);
1212 for (intptr_t i = 0; i < samples_->length(); i++) { 1227 for (intptr_t sample_index = 0;
1213 ProcessedSample* sample = samples_->At(i); 1228 sample_index < samples_->length();
1229 sample_index++) {
1230 ProcessedSample* sample = samples_->At(sample_index);
1214 1231
1215 // Tick the root. 1232 // Tick the root.
1216 ProfileFunctionTrieNode* current = root; 1233 ProfileFunctionTrieNode* current = root;
1217 current->Tick(); 1234 current->Tick();
1218 1235
1219 // VM & User tags. 1236 // VM & User tags.
1220 current = AppendTags(sample->vm_tag(), sample->user_tag(), current); 1237 current = AppendTags(sample->vm_tag(), sample->user_tag(), current);
1221 1238
1222 // Truncated tag. 1239 // Truncated tag.
1223 if (sample->truncated()) { 1240 if (sample->truncated()) {
1224 current = AppendTruncatedTag(current); 1241 current = AppendTruncatedTag(current);
1225 InclusiveTickTruncatedTag();
1226 } 1242 }
1227 1243
1228 // Walk the sampled PCs. 1244 // Walk the sampled PCs.
1229 for (intptr_t j = sample->length() - 1; j >= 0; j--) { 1245 for (intptr_t frame_index = sample->length() - 1;
1230 ASSERT(sample->At(j) != 0); 1246 frame_index >= 0;
1231 current = ProcessFunctionPC( 1247 frame_index--) {
1232 sample->At(j), 1248 ASSERT(sample->At(frame_index) != 0);
1233 sample->timestamp(), 1249 current = ProcessFrame(current, sample_index, sample, frame_index);
1234 current,
1235 i,
1236 (j == 0),
1237 sample->first_frame_executing() || sample->IsAllocationSample(),
1238 true);
1239 } 1250 }
1240 } 1251 }
1241 } 1252 }
1242 1253
1243 void BuildExclusiveFunctionTrie(ProfileFunctionTrieNode* root) { 1254 void BuildExclusiveFunctionTrie(ProfileFunctionTrieNode* root) {
1244 ScopeTimer sw("ProfileBuilder::BuildExclusiveFunctionTrie", 1255 ScopeTimer sw("ProfileBuilder::BuildExclusiveFunctionTrie",
1245 FLAG_trace_profiler); 1256 FLAG_trace_profiler);
1246 for (intptr_t i = 0; i < samples_->length(); i++) { 1257 for (intptr_t sample_index = 0;
1247 ProcessedSample* sample = samples_->At(i); 1258 sample_index < samples_->length();
1259 sample_index++) {
1260 ProcessedSample* sample = samples_->At(sample_index);
1248 1261
1249 // Tick the root. 1262 // Tick the root.
1250 ProfileFunctionTrieNode* current = root; 1263 ProfileFunctionTrieNode* current = root;
1251 current->Tick(); 1264 current->Tick();
1252 1265
1253 // VM & User tags. 1266 // VM & User tags.
1254 current = AppendTags(sample->vm_tag(), sample->user_tag(), current); 1267 current = AppendTags(sample->vm_tag(), sample->user_tag(), current);
1255 1268
1256 // Walk the sampled PCs. 1269 // Walk the sampled PCs.
1257 for (intptr_t j = 0; j < sample->length(); j++) { 1270 for (intptr_t frame_index = 0;
1258 ASSERT(sample->At(j) != 0); 1271 frame_index < sample->length();
1259 current = ProcessFunctionPC( 1272 frame_index++) {
1260 sample->At(j), 1273 ASSERT(sample->At(frame_index) != 0);
1261 sample->timestamp(), 1274 current = ProcessFrame(current, sample_index, sample, frame_index);
1262 current,
1263 i,
1264 (j == 0),
1265 sample->first_frame_executing() || sample->IsAllocationSample(),
1266 false);
1267 } 1275 }
1268 1276
1269 // Truncated tag. 1277 // Truncated tag.
1270 if (sample->truncated()) { 1278 if (sample->truncated()) {
1271 current = AppendTruncatedTag(current); 1279 current = AppendTruncatedTag(current);
1280 InclusiveTickTruncatedTag();
1272 } 1281 }
1273 } 1282 }
1274 } 1283 }
1275 1284
1276 ProfileFunctionTrieNode* ProcessFunctionPC( 1285 ProfileFunctionTrieNode* ProcessFrame(
1277 uword pc,
1278 int64_t timestamp,
1279 ProfileFunctionTrieNode* current, 1286 ProfileFunctionTrieNode* current,
1280 intptr_t inclusive_serial, 1287 intptr_t sample_index,
1281 bool top_frame, 1288 ProcessedSample* sample,
1282 bool top_frame_executing, 1289 intptr_t frame_index) {
1283 bool inclusive_tree) { 1290 const uword pc = sample->At(frame_index);
1284 ProfileCode* profile_code = GetProfileCode(pc, timestamp); 1291 ProfileCode* profile_code = GetProfileCode(pc,
1292 sample->timestamp());
1285 ASSERT(profile_code != NULL); 1293 ASSERT(profile_code != NULL);
1286 const char* code_name = profile_code->name();
1287 if (code_name == NULL) {
1288 code_name = "";
1289 }
1290 intptr_t code_index = profile_code->code_table_index();
1291 const Code& code = Code::ZoneHandle(profile_code->code()); 1294 const Code& code = Code::ZoneHandle(profile_code->code());
1292 GrowableArray<Function*> inlined_functions; 1295 GrowableArray<Function*> inlined_functions;
1293 if (!code.IsNull()) { 1296 if (!code.IsNull()) {
1294 intptr_t offset = pc - code.EntryPoint(); 1297 intptr_t offset = pc - code.EntryPoint();
1295 code.GetInlinedFunctionsAt(offset, &inlined_functions); 1298 code.GetInlinedFunctionsAt(offset, &inlined_functions);
1296 } 1299 }
1297 if (code.IsNull() || (inlined_functions.length() == 0)) { 1300 if (code.IsNull() || (inlined_functions.length() == 0)) {
1298 // No inlined functions. 1301 // No inlined functions.
1299 ProfileFunction* function = profile_code->function(); 1302 ProfileFunction* function = profile_code->function();
1300 ASSERT(function != NULL); 1303 ASSERT(function != NULL);
1301 current = ProcessFunction(function, 1304 current = ProcessFunction(current,
1302 current, 1305 sample_index,
1303 inclusive_serial, 1306 sample,
1304 top_frame, 1307 frame_index,
1305 top_frame_executing, 1308 function);
1306 code_index);
1307 return current; 1309 return current;
1308 } 1310 }
1309 1311
1310 if (inclusive_tree) { 1312 if (inclusive_tree_) {
1311 for (intptr_t i = inlined_functions.length() - 1; i >= 0; i--) { 1313 for (intptr_t i = inlined_functions.length() - 1; i >= 0; i--) {
1312 Function* inlined_function = inlined_functions[i]; 1314 Function* inlined_function = inlined_functions[i];
1313 ASSERT(inlined_function != NULL); 1315 ASSERT(inlined_function != NULL);
1314 ASSERT(!inlined_function->IsNull()); 1316 ASSERT(!inlined_function->IsNull());
1315 current = ProcessInlinedFunction(inlined_function, 1317 current = ProcessInlinedFunction(current,
1316 current, 1318 sample_index,
1317 inclusive_serial, 1319 sample,
1318 top_frame, 1320 frame_index,
1319 top_frame_executing, 1321 inlined_function);
1320 code_index);
1321 top_frame = false;
1322 } 1322 }
1323 } else { 1323 } else {
1324 for (intptr_t i = 0; i < inlined_functions.length(); i++) { 1324 for (intptr_t i = 0; i < inlined_functions.length(); i++) {
1325 Function* inlined_function = inlined_functions[i]; 1325 Function* inlined_function = inlined_functions[i];
1326 ASSERT(inlined_function != NULL); 1326 ASSERT(inlined_function != NULL);
1327 ASSERT(!inlined_function->IsNull()); 1327 ASSERT(!inlined_function->IsNull());
1328 current = ProcessInlinedFunction(inlined_function, 1328 current = ProcessInlinedFunction(current,
1329 current, 1329 sample_index,
1330 inclusive_serial, 1330 sample,
1331 top_frame, 1331 frame_index + i,
1332 top_frame_executing, 1332 inlined_function);
1333 code_index);
1334 top_frame = false;
1335 } 1333 }
1336 } 1334 }
1337 1335
1338 return current; 1336 return current;
1339 } 1337 }
1340 1338
1341 ProfileFunctionTrieNode* ProcessInlinedFunction( 1339 ProfileFunctionTrieNode* ProcessInlinedFunction(
1342 Function* inlined_function,
1343 ProfileFunctionTrieNode* current, 1340 ProfileFunctionTrieNode* current,
1344 intptr_t inclusive_serial, 1341 intptr_t sample_index,
1345 bool top_frame, 1342 ProcessedSample* sample,
1346 bool top_frame_executing, 1343 intptr_t frame_index,
1347 intptr_t code_index) { 1344 Function* inlined_function) {
1348 ProfileFunctionTable* function_table = profile_->functions_; 1345 ProfileFunctionTable* function_table = profile_->functions_;
1349 ProfileFunction* function = function_table->LookupOrAdd(*inlined_function); 1346 ProfileFunction* function = function_table->LookupOrAdd(*inlined_function);
1350 ASSERT(function != NULL); 1347 ASSERT(function != NULL);
1351 return ProcessFunction(function, 1348 return ProcessFunction(current,
1352 current, 1349 sample_index,
1353 inclusive_serial, 1350 sample,
1354 top_frame, 1351 frame_index,
1355 top_frame_executing, 1352 function);
1356 code_index);
1357 } 1353 }
1358 1354
1359 ProfileFunctionTrieNode* ProcessFunction(ProfileFunction* function, 1355 ProfileFunctionTrieNode* ProcessFunction(ProfileFunctionTrieNode* current,
1360 ProfileFunctionTrieNode* current, 1356 intptr_t sample_index,
1361 intptr_t inclusive_serial, 1357 ProcessedSample* sample,
1362 bool top_frame, 1358 intptr_t frame_index,
1363 bool top_frame_executing, 1359 ProfileFunction* function) {
1364 intptr_t code_index) {
1365 const bool exclusive = top_frame && top_frame_executing;
1366 if (tick_functions_) { 1360 if (tick_functions_) {
1367 function->Tick(exclusive, exclusive ? -1 : inclusive_serial); 1361 function->Tick(IsExecutingFrame(sample, frame_index), sample_index);
1368 } 1362 }
1369 function->AddProfileCode(code_index);
1370 current = current->GetChild(function->table_index()); 1363 current = current->GetChild(function->table_index());
1371 current->AddCodeObjectIndex(code_index); 1364 current->Tick();
1372 if (top_frame) {
1373 if (top_frame_executing || vm_tags_emitted()) {
1374 // Only tick if this function is using CPU time or VM tags are emitted.
1375 current->Tick();
1376 }
1377 } else {
1378 current->Tick();
1379 }
1380 return current; 1365 return current;
1381 } 1366 }
1382 1367
1383 // Tick the truncated tag's inclusive tick count. 1368 // Tick the truncated tag's inclusive tick count.
1384 void InclusiveTickTruncatedTag() { 1369 void InclusiveTickTruncatedTag() {
1385 ProfileCodeTable* tag_table = profile_->tag_code_; 1370 ProfileCodeTable* tag_table = profile_->tag_code_;
1386 intptr_t index = tag_table->FindCodeIndexForPC(VMTag::kTruncatedTagId); 1371 intptr_t index = tag_table->FindCodeIndexForPC(VMTag::kTruncatedTagId);
1387 ASSERT(index >= 0); 1372 ASSERT(index >= 0);
1388 ProfileCode* code = tag_table->At(index); 1373 ProfileCode* code = tag_table->At(index);
1389 code->IncInclusiveTicks(); 1374 code->IncInclusiveTicks();
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
1503 ProfileFunctionTrieNode* current) { 1488 ProfileFunctionTrieNode* current) {
1504 intptr_t truncated_tag_index = 1489 intptr_t truncated_tag_index =
1505 GetProfileFunctionTagIndex(VMTag::kTruncatedTagId); 1490 GetProfileFunctionTagIndex(VMTag::kTruncatedTagId);
1506 ASSERT(truncated_tag_index >= 0); 1491 ASSERT(truncated_tag_index >= 0);
1507 current = current->GetChild(truncated_tag_index); 1492 current = current->GetChild(truncated_tag_index);
1508 current->Tick(); 1493 current->Tick();
1509 return current; 1494 return current;
1510 } 1495 }
1511 1496
1512 ProfileFunctionTrieNode* AppendVMTag(uword vm_tag, 1497 ProfileFunctionTrieNode* AppendVMTag(uword vm_tag,
1513 ProfileFunctionTrieNode* current) { 1498 ProfileFunctionTrieNode* current) {
1514 if (VMTag::IsNativeEntryTag(vm_tag)) { 1499 if (VMTag::IsNativeEntryTag(vm_tag)) {
1515 // Insert a dummy kNativeTagId node. 1500 // Insert a dummy kNativeTagId node.
1516 intptr_t tag_index = GetProfileFunctionTagIndex(VMTag::kNativeTagId); 1501 intptr_t tag_index = GetProfileFunctionTagIndex(VMTag::kNativeTagId);
1517 current = current->GetChild(tag_index); 1502 current = current->GetChild(tag_index);
1518 // Give the tag a tick. 1503 // Give the tag a tick.
1519 current->Tick(); 1504 current->Tick();
1520 } else if (VMTag::IsRuntimeEntryTag(vm_tag)) { 1505 } else if (VMTag::IsRuntimeEntryTag(vm_tag)) {
1521 // Insert a dummy kRuntimeTagId node. 1506 // Insert a dummy kRuntimeTagId node.
1522 intptr_t tag_index = GetProfileFunctionTagIndex(VMTag::kRuntimeTagId); 1507 intptr_t tag_index = GetProfileFunctionTagIndex(VMTag::kRuntimeTagId);
1523 current = current->GetChild(tag_index); 1508 current = current->GetChild(tag_index);
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
1774 1759
1775 Isolate* isolate_; 1760 Isolate* isolate_;
1776 Isolate* vm_isolate_; 1761 Isolate* vm_isolate_;
1777 SampleFilter* filter_; 1762 SampleFilter* filter_;
1778 Profile::TagOrder tag_order_; 1763 Profile::TagOrder tag_order_;
1779 Profile* profile_; 1764 Profile* profile_;
1780 DeoptimizedCodeSet* deoptimized_code_; 1765 DeoptimizedCodeSet* deoptimized_code_;
1781 const Code& null_code_; 1766 const Code& null_code_;
1782 const Function& null_function_; 1767 const Function& null_function_;
1783 bool tick_functions_; 1768 bool tick_functions_;
1769 bool inclusive_tree_;
1784 1770
1785 ProcessedSampleBuffer* samples_; 1771 ProcessedSampleBuffer* samples_;
1786 }; 1772 };
1787 1773
1788 1774
1789 Profile::Profile(Isolate* isolate) 1775 Profile::Profile(Isolate* isolate)
1790 : isolate_(isolate), 1776 : isolate_(isolate),
1791 live_code_(NULL), 1777 live_code_(NULL),
1792 dead_code_(NULL), 1778 dead_code_(NULL),
1793 tag_code_(NULL), 1779 tag_code_(NULL),
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after
2089 ASSERT(sample_buffer != NULL); 2075 ASSERT(sample_buffer != NULL);
2090 2076
2091 ClearProfileVisitor clear_profile(isolate); 2077 ClearProfileVisitor clear_profile(isolate);
2092 sample_buffer->VisitSamples(&clear_profile); 2078 sample_buffer->VisitSamples(&clear_profile);
2093 2079
2094 // Enable profile interrupts. 2080 // Enable profile interrupts.
2095 Profiler::BeginExecution(isolate); 2081 Profiler::BeginExecution(isolate);
2096 } 2082 }
2097 2083
2098 } // namespace dart 2084 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/profiler_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698