Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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/il_printer.h" | 5 #include "vm/il_printer.h" |
| 6 | 6 |
| 7 #include "vm/flow_graph_range_analysis.h" | 7 #include "vm/flow_graph_range_analysis.h" |
| 8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
| 9 #include "vm/os.h" | 9 #include "vm/os.h" |
| 10 #include "vm/parser.h" | 10 #include "vm/parser.h" |
| 11 | 11 |
| 12 namespace dart { | 12 namespace dart { |
| 13 | 13 |
| 14 #ifndef PRODUCT | 14 #ifndef PRODUCT |
| 15 | 15 |
| 16 DEFINE_FLAG(bool, display_sorted_ic_data, false, | |
| 17 "Calls display a unary, sorted-by count form of ICData"); | |
| 16 DEFINE_FLAG(bool, print_environments, false, "Print SSA environments."); | 18 DEFINE_FLAG(bool, print_environments, false, "Print SSA environments."); |
| 17 DEFINE_FLAG(charp, print_flow_graph_filter, NULL, | 19 DEFINE_FLAG(charp, print_flow_graph_filter, NULL, |
| 18 "Print only IR of functions with matching names"); | 20 "Print only IR of functions with matching names"); |
| 19 | 21 |
| 20 DECLARE_FLAG(bool, trace_inlining_intervals); | 22 DECLARE_FLAG(bool, trace_inlining_intervals); |
| 21 | 23 |
| 22 void BufferFormatter::Print(const char* format, ...) { | 24 void BufferFormatter::Print(const char* format, ...) { |
| 23 va_list args; | 25 va_list args; |
| 24 va_start(args, format); | 26 va_start(args, format); |
| 25 VPrint(format, args); | 27 VPrint(format, args); |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 184 | 186 |
| 185 | 187 |
| 186 const char* CompileType::ToCString() const { | 188 const char* CompileType::ToCString() const { |
| 187 char buffer[1024]; | 189 char buffer[1024]; |
| 188 BufferFormatter f(buffer, sizeof(buffer)); | 190 BufferFormatter f(buffer, sizeof(buffer)); |
| 189 PrintTo(&f); | 191 PrintTo(&f); |
| 190 return Thread::Current()->zone()->MakeCopyOfString(buffer); | 192 return Thread::Current()->zone()->MakeCopyOfString(buffer); |
| 191 } | 193 } |
| 192 | 194 |
| 193 | 195 |
| 194 static void PrintICDataHelper(BufferFormatter* f, const ICData& ic_data) { | 196 static void PrintICDataHelper(BufferFormatter* f, |
| 197 const ICData& ic_data, | |
| 198 intptr_t num_checks_to_print = -1) { | |
|
zra
2016/04/27 16:28:17
intptr_t num_checks_to_print = FlowGraphPrinter::k
srdjan
2016/04/27 18:10:22
Done.
| |
| 195 f->Print(" IC["); | 199 f->Print(" IC["); |
| 196 if (ic_data.HasRangeFeedback()) { | 200 if (ic_data.HasRangeFeedback()) { |
| 197 f->Print("{%s", | 201 f->Print("{%s", |
| 198 ICData::RangeFeedbackToString(ic_data.DecodeRangeFeedbackAt(0))); | 202 ICData::RangeFeedbackToString(ic_data.DecodeRangeFeedbackAt(0))); |
| 199 if (ic_data.NumArgsTested() == 2) { | 203 if (ic_data.NumArgsTested() == 2) { |
| 200 f->Print(" x %s", | 204 f->Print(" x %s", |
| 201 ICData::RangeFeedbackToString(ic_data.DecodeRangeFeedbackAt(1))); | 205 ICData::RangeFeedbackToString(ic_data.DecodeRangeFeedbackAt(1))); |
| 202 } | 206 } |
| 203 f->Print("->%s} ", | 207 f->Print("->%s} ", |
| 204 ICData::RangeFeedbackToString(ic_data.DecodeRangeFeedbackAt(2))); | 208 ICData::RangeFeedbackToString(ic_data.DecodeRangeFeedbackAt(2))); |
| 205 } | 209 } |
| 206 f->Print("%" Pd ": ", ic_data.NumberOfChecks()); | 210 f->Print("%" Pd ": ", ic_data.NumberOfChecks()); |
| 207 Function& target = Function::Handle(); | 211 Function& target = Function::Handle(); |
| 208 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) { | 212 if ((num_checks_to_print < 0) || |
|
zra
2016/04/27 16:28:17
Then, this would be (num_checks_to_print == FlowGr
srdjan
2016/04/27 18:10:22
Done.
| |
| 213 (num_checks_to_print > ic_data.NumberOfChecks())) { | |
| 214 num_checks_to_print = ic_data.NumberOfChecks(); | |
| 215 } | |
| 216 for (intptr_t i = 0; i < num_checks_to_print; i++) { | |
| 209 GrowableArray<intptr_t> class_ids; | 217 GrowableArray<intptr_t> class_ids; |
| 210 ic_data.GetCheckAt(i, &class_ids, &target); | 218 ic_data.GetCheckAt(i, &class_ids, &target); |
| 211 const intptr_t count = ic_data.GetCountAt(i); | 219 const intptr_t count = ic_data.GetCountAt(i); |
| 212 if (i > 0) { | 220 if (i > 0) { |
| 213 f->Print(" | "); | 221 f->Print(" | "); |
| 214 } | 222 } |
| 215 for (intptr_t k = 0; k < class_ids.length(); k++) { | 223 for (intptr_t k = 0; k < class_ids.length(); k++) { |
| 216 if (k > 0) { | 224 if (k > 0) { |
| 217 f->Print(", "); | 225 f->Print(", "); |
| 218 } | 226 } |
| 219 const Class& cls = | 227 const Class& cls = |
| 220 Class::Handle(Isolate::Current()->class_table()->At(class_ids[k])); | 228 Class::Handle(Isolate::Current()->class_table()->At(class_ids[k])); |
| 221 f->Print("%s", String::Handle(cls.Name()).ToCString()); | 229 f->Print("%s", String::Handle(cls.Name()).ToCString()); |
| 222 } | 230 } |
| 223 f->Print(" cnt:%" Pd " trgt:'%s'", count, target.ToQualifiedCString()); | 231 f->Print(" cnt:%" Pd " trgt:'%s'", count, target.ToQualifiedCString()); |
| 224 } | 232 } |
| 233 if (num_checks_to_print < ic_data.NumberOfChecks()) { | |
| 234 f->Print("..."); | |
| 235 } | |
| 225 f->Print("]"); | 236 f->Print("]"); |
| 226 } | 237 } |
| 227 | 238 |
| 228 | 239 |
| 229 void FlowGraphPrinter::PrintICData(const ICData& ic_data) { | 240 static void PrintICDataSortedHelper(BufferFormatter* f, |
| 241 const ICData& ic_data_orig) { | |
| 242 const ICData& ic_data = | |
| 243 ICData::Handle(ic_data_orig.AsUnaryClassChecksSortedByCount()); | |
| 244 f->Print(" IC[n:%" Pd"; ", ic_data.NumberOfChecks()); | |
| 245 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) { | |
| 246 const intptr_t count = ic_data.GetCountAt(i); | |
| 247 const intptr_t cid = ic_data.GetReceiverClassIdAt(i); | |
| 248 const Class& cls = | |
| 249 Class::Handle(Isolate::Current()->class_table()->At(cid)); | |
| 250 f->Print("%s : %" Pd ", ", | |
| 251 String::Handle(cls.Name()).ToCString(), count); | |
| 252 } | |
| 253 f->Print("]"); | |
| 254 } | |
| 255 | |
| 256 | |
| 257 void FlowGraphPrinter::PrintICData(const ICData& ic_data, | |
| 258 intptr_t num_checks_to_print) { | |
| 230 char buffer[1024]; | 259 char buffer[1024]; |
| 231 BufferFormatter f(buffer, sizeof(buffer)); | 260 BufferFormatter f(buffer, sizeof(buffer)); |
| 232 PrintICDataHelper(&f, ic_data); | 261 PrintICDataHelper(&f, ic_data, num_checks_to_print); |
| 233 THR_Print("%s ", buffer); | 262 THR_Print("%s ", buffer); |
| 234 const Array& a = Array::Handle(ic_data.arguments_descriptor()); | 263 const Array& a = Array::Handle(ic_data.arguments_descriptor()); |
| 235 THR_Print(" arg-desc %" Pd "\n", a.Length()); | 264 THR_Print(" arg-desc %" Pd "\n", a.Length()); |
| 236 } | 265 } |
| 237 | 266 |
| 238 | 267 |
| 239 static void PrintUse(BufferFormatter* f, const Definition& definition) { | 268 static void PrintUse(BufferFormatter* f, const Definition& definition) { |
| 240 if (definition.HasSSATemp()) { | 269 if (definition.HasSSATemp()) { |
| 241 if (definition.HasPairRepresentation()) { | 270 if (definition.HasPairRepresentation()) { |
| 242 f->Print("(v%" Pd ", v%" Pd ")", definition.ssa_temp_index(), | 271 f->Print("(v%" Pd ", v%" Pd ")", definition.ssa_temp_index(), |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 428 } | 457 } |
| 429 | 458 |
| 430 | 459 |
| 431 void InstanceCallInstr::PrintOperandsTo(BufferFormatter* f) const { | 460 void InstanceCallInstr::PrintOperandsTo(BufferFormatter* f) const { |
| 432 f->Print(" %s", function_name().ToCString()); | 461 f->Print(" %s", function_name().ToCString()); |
| 433 for (intptr_t i = 0; i < ArgumentCount(); ++i) { | 462 for (intptr_t i = 0; i < ArgumentCount(); ++i) { |
| 434 f->Print(", "); | 463 f->Print(", "); |
| 435 PushArgumentAt(i)->value()->PrintTo(f); | 464 PushArgumentAt(i)->value()->PrintTo(f); |
| 436 } | 465 } |
| 437 if (HasICData()) { | 466 if (HasICData()) { |
| 438 PrintICDataHelper(f, *ic_data()); | 467 if (FLAG_display_sorted_ic_data) { |
| 468 PrintICDataSortedHelper(f, *ic_data()); | |
| 469 } else { | |
| 470 PrintICDataHelper(f, *ic_data()); | |
| 471 } | |
| 439 } | 472 } |
| 440 } | 473 } |
| 441 | 474 |
| 442 | 475 |
| 443 void PolymorphicInstanceCallInstr::PrintOperandsTo(BufferFormatter* f) const { | 476 void PolymorphicInstanceCallInstr::PrintOperandsTo(BufferFormatter* f) const { |
| 444 f->Print(" %s", instance_call()->function_name().ToCString()); | 477 f->Print(" %s", instance_call()->function_name().ToCString()); |
| 445 for (intptr_t i = 0; i < ArgumentCount(); ++i) { | 478 for (intptr_t i = 0; i < ArgumentCount(); ++i) { |
| 446 f->Print(", "); | 479 f->Print(", "); |
| 447 PushArgumentAt(i)->value()->PrintTo(f); | 480 PushArgumentAt(i)->value()->PrintTo(f); |
| 448 } | 481 } |
| 449 PrintICDataHelper(f, ic_data()); | 482 PrintICDataHelper(f, ic_data()); |
|
zra
2016/04/27 16:28:17
Should the flag cause the others to be sorted, too
srdjan
2016/04/27 18:10:22
Done. Originally planned it only for megamorphic c
| |
| 450 if (with_checks()) { | 483 if (with_checks()) { |
| 451 f->Print(" WITH-CHECKS"); | 484 f->Print(" WITH-CHECKS"); |
| 452 } | 485 } |
| 453 if (complete()) { | 486 if (complete()) { |
| 454 f->Print(" COMPLETE"); | 487 f->Print(" COMPLETE"); |
| 455 } | 488 } |
| 456 } | 489 } |
| 457 | 490 |
| 458 | 491 |
| 459 void StrictCompareInstr::PrintOperandsTo(BufferFormatter* f) const { | 492 void StrictCompareInstr::PrintOperandsTo(BufferFormatter* f) const { |
| (...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 940 value()->PrintTo(f); | 973 value()->PrintTo(f); |
| 941 | 974 |
| 942 const Class& cls = | 975 const Class& cls = |
| 943 Class::Handle(Isolate::Current()->class_table()->At(cid())); | 976 Class::Handle(Isolate::Current()->class_table()->At(cid())); |
| 944 f->Print(", %s", String::Handle(cls.ScrubbedName()).ToCString()); | 977 f->Print(", %s", String::Handle(cls.ScrubbedName()).ToCString()); |
| 945 } | 978 } |
| 946 | 979 |
| 947 | 980 |
| 948 void CheckClassInstr::PrintOperandsTo(BufferFormatter* f) const { | 981 void CheckClassInstr::PrintOperandsTo(BufferFormatter* f) const { |
| 949 value()->PrintTo(f); | 982 value()->PrintTo(f); |
| 950 PrintICDataHelper(f, unary_checks()); | 983 PrintICDataHelper(f, unary_checks()); |
|
zra
2016/04/27 16:28:17
ditto
| |
| 951 if (IsNullCheck()) { | 984 if (IsNullCheck()) { |
| 952 f->Print(" nullcheck"); | 985 f->Print(" nullcheck"); |
| 953 } | 986 } |
| 954 } | 987 } |
| 955 | 988 |
| 956 | 989 |
| 957 void InvokeMathCFunctionInstr::PrintOperandsTo(BufferFormatter* f) const { | 990 void InvokeMathCFunctionInstr::PrintOperandsTo(BufferFormatter* f) const { |
| 958 f->Print("%s, ", MethodRecognizer::KindToCString(recognized_kind_)); | 991 f->Print("%s, ", MethodRecognizer::KindToCString(recognized_kind_)); |
| 959 Definition::PrintOperandsTo(f); | 992 Definition::PrintOperandsTo(f); |
| 960 } | 993 } |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1268 } | 1301 } |
| 1269 | 1302 |
| 1270 | 1303 |
| 1271 bool FlowGraphPrinter::ShouldPrint(const Function& function) { | 1304 bool FlowGraphPrinter::ShouldPrint(const Function& function) { |
| 1272 return false; | 1305 return false; |
| 1273 } | 1306 } |
| 1274 | 1307 |
| 1275 #endif // !PRODUCT | 1308 #endif // !PRODUCT |
| 1276 | 1309 |
| 1277 } // namespace dart | 1310 } // namespace dart |
| OLD | NEW |