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/flow_graph_optimizer.h" | 5 #include "vm/flow_graph_optimizer.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/cha.h" | 8 #include "vm/cha.h" |
| 9 #include "vm/flow_graph_builder.h" | 9 #include "vm/flow_graph_builder.h" |
| 10 #include "vm/flow_graph_compiler.h" | 10 #include "vm/flow_graph_compiler.h" |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 266 if (def != NULL) { | 266 if (def != NULL) { |
| 267 InsertConversionsFor(def); | 267 InsertConversionsFor(def); |
| 268 } | 268 } |
| 269 } | 269 } |
| 270 } | 270 } |
| 271 } | 271 } |
| 272 | 272 |
| 273 | 273 |
| 274 static bool ICDataHasReceiverClassId(const ICData& ic_data, intptr_t class_id) { | 274 static bool ICDataHasReceiverClassId(const ICData& ic_data, intptr_t class_id) { |
| 275 ASSERT(ic_data.num_args_tested() > 0); | 275 ASSERT(ic_data.num_args_tested() > 0); |
| 276 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) { | 276 const intptr_t len = ic_data.NumberOfChecks(); |
| 277 for (intptr_t i = 0; i < len; i++) { | |
| 277 const intptr_t test_class_id = ic_data.GetReceiverClassIdAt(i); | 278 const intptr_t test_class_id = ic_data.GetReceiverClassIdAt(i); |
| 278 if (test_class_id == class_id) { | 279 if (test_class_id == class_id) { |
| 279 return true; | 280 return true; |
| 280 } | 281 } |
| 281 } | 282 } |
| 282 return false; | 283 return false; |
| 283 } | 284 } |
| 284 | 285 |
| 285 | 286 |
| 286 static bool ICDataHasReceiverArgumentClassIds(const ICData& ic_data, | 287 static bool ICDataHasReceiverArgumentClassIds(const ICData& ic_data, |
| 287 intptr_t receiver_class_id, | 288 intptr_t receiver_class_id, |
| 288 intptr_t argument_class_id) { | 289 intptr_t argument_class_id) { |
| 289 ASSERT(receiver_class_id != kIllegalCid); | 290 ASSERT(receiver_class_id != kIllegalCid); |
| 290 ASSERT(argument_class_id != kIllegalCid); | 291 ASSERT(argument_class_id != kIllegalCid); |
| 291 if (ic_data.num_args_tested() != 2) return false; | 292 if (ic_data.num_args_tested() != 2) return false; |
| 292 | 293 |
| 293 Function& target = Function::Handle(); | 294 Function& target = Function::Handle(); |
| 294 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) { | 295 const intptr_t len = ic_data.NumberOfChecks(); |
| 296 for (intptr_t i = 0; i < len; i++) { | |
| 295 GrowableArray<intptr_t> class_ids; | 297 GrowableArray<intptr_t> class_ids; |
| 296 ic_data.GetCheckAt(i, &class_ids, &target); | 298 ic_data.GetCheckAt(i, &class_ids, &target); |
| 297 ASSERT(class_ids.length() == 2); | 299 ASSERT(class_ids.length() == 2); |
| 298 if ((class_ids[0] == receiver_class_id) && | 300 if ((class_ids[0] == receiver_class_id) && |
| 299 (class_ids[1] == argument_class_id)) { | 301 (class_ids[1] == argument_class_id)) { |
| 300 return true; | 302 return true; |
| 301 } | 303 } |
| 302 } | 304 } |
| 303 return false; | 305 return false; |
| 304 } | 306 } |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 316 | 318 |
| 317 | 319 |
| 318 // Returns true if ICData tests two arguments and all ICData cids are in the | 320 // Returns true if ICData tests two arguments and all ICData cids are in the |
| 319 // required sets 'receiver_class_ids' or 'argument_class_ids', respectively. | 321 // required sets 'receiver_class_ids' or 'argument_class_ids', respectively. |
| 320 static bool ICDataHasOnlyReceiverArgumentClassIds( | 322 static bool ICDataHasOnlyReceiverArgumentClassIds( |
| 321 const ICData& ic_data, | 323 const ICData& ic_data, |
| 322 const GrowableArray<intptr_t>& receiver_class_ids, | 324 const GrowableArray<intptr_t>& receiver_class_ids, |
| 323 const GrowableArray<intptr_t>& argument_class_ids) { | 325 const GrowableArray<intptr_t>& argument_class_ids) { |
| 324 if (ic_data.num_args_tested() != 2) return false; | 326 if (ic_data.num_args_tested() != 2) return false; |
| 325 Function& target = Function::Handle(); | 327 Function& target = Function::Handle(); |
| 326 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) { | 328 const intptr_t len = ic_data.NumberOfChecks(); |
| 329 for (intptr_t i = 0; i < len; i++) { | |
| 327 GrowableArray<intptr_t> class_ids; | 330 GrowableArray<intptr_t> class_ids; |
| 328 ic_data.GetCheckAt(i, &class_ids, &target); | 331 ic_data.GetCheckAt(i, &class_ids, &target); |
| 329 ASSERT(class_ids.length() == 2); | 332 ASSERT(class_ids.length() == 2); |
| 330 if (!ClassIdIsOneOf(class_ids[0], receiver_class_ids) || | 333 if (!ClassIdIsOneOf(class_ids[0], receiver_class_ids) || |
| 331 !ClassIdIsOneOf(class_ids[1], argument_class_ids)) { | 334 !ClassIdIsOneOf(class_ids[1], argument_class_ids)) { |
| 332 return false; | 335 return false; |
| 333 } | 336 } |
| 334 } | 337 } |
| 335 return true; | 338 return true; |
| 336 } | 339 } |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 440 } | 443 } |
| 441 InsertBefore(call, check, call->env(), Definition::kEffect); | 444 InsertBefore(call, check, call->env(), Definition::kEffect); |
| 442 } | 445 } |
| 443 | 446 |
| 444 | 447 |
| 445 static bool ArgIsAlwaysSmi(const ICData& ic_data, intptr_t arg_n) { | 448 static bool ArgIsAlwaysSmi(const ICData& ic_data, intptr_t arg_n) { |
| 446 ASSERT(ic_data.num_args_tested() > arg_n); | 449 ASSERT(ic_data.num_args_tested() > arg_n); |
| 447 if (ic_data.NumberOfChecks() == 0) return false; | 450 if (ic_data.NumberOfChecks() == 0) return false; |
| 448 GrowableArray<intptr_t> class_ids; | 451 GrowableArray<intptr_t> class_ids; |
| 449 Function& target = Function::Handle(); | 452 Function& target = Function::Handle(); |
| 450 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) { | 453 const intptr_t len = ic_data.NumberOfChecks(); |
| 454 for (intptr_t i = 0; i < len; i++) { | |
| 451 ic_data.GetCheckAt(i, &class_ids, &target); | 455 ic_data.GetCheckAt(i, &class_ids, &target); |
| 452 if (class_ids[arg_n] != kSmiCid) return false; | 456 if (class_ids[arg_n] != kSmiCid) return false; |
| 453 } | 457 } |
| 454 return true; | 458 return true; |
| 455 } | 459 } |
| 456 | 460 |
| 457 | 461 |
| 458 // Returns array classid to load from, array and idnex value | 462 // Returns array classid to load from, array and idnex value |
| 459 | 463 |
| 460 intptr_t FlowGraphOptimizer::PrepareIndexedOp(InstanceCallInstr* call, | 464 intptr_t FlowGraphOptimizer::PrepareIndexedOp(InstanceCallInstr* call, |
| (...skipping 704 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1165 if (!instr->HasICData() || (instr->ic_data()->NumberOfChecks() == 0)) { | 1169 if (!instr->HasICData() || (instr->ic_data()->NumberOfChecks() == 0)) { |
| 1166 // An instance call without ICData will trigger deoptimization. | 1170 // An instance call without ICData will trigger deoptimization. |
| 1167 return; | 1171 return; |
| 1168 } | 1172 } |
| 1169 | 1173 |
| 1170 const ICData& unary_checks = | 1174 const ICData& unary_checks = |
| 1171 ICData::ZoneHandle(instr->ic_data()->AsUnaryClassChecks()); | 1175 ICData::ZoneHandle(instr->ic_data()->AsUnaryClassChecks()); |
| 1172 if ((unary_checks.NumberOfChecks() > FLAG_max_polymorphic_checks) && | 1176 if ((unary_checks.NumberOfChecks() > FLAG_max_polymorphic_checks) && |
| 1173 InstanceCallNeedsClassCheck(instr)) { | 1177 InstanceCallNeedsClassCheck(instr)) { |
| 1174 // Too many checks, leave it megamorphic. | 1178 // Too many checks, leave it megamorphic. |
| 1179 instr->set_ic_data(&unary_checks); | |
|
siva
2012/11/02 01:09:18
The comment says 'too many checks, leave it megamo
srdjan
2012/11/02 15:32:45
Changed the comment:
// Too many checks it wil
| |
| 1175 return; | 1180 return; |
| 1176 } | 1181 } |
| 1177 | 1182 |
| 1178 const Token::Kind op_kind = instr->token_kind(); | 1183 const Token::Kind op_kind = instr->token_kind(); |
| 1179 if ((op_kind == Token::kASSIGN_INDEX) && | 1184 if ((op_kind == Token::kASSIGN_INDEX) && |
| 1180 TryReplaceWithStoreIndexed(instr)) { | 1185 TryReplaceWithStoreIndexed(instr)) { |
| 1181 return; | 1186 return; |
| 1182 } | 1187 } |
| 1183 if ((op_kind == Token::kINDEX) && TryReplaceWithLoadIndexed(instr)) { | 1188 if ((op_kind == Token::kINDEX) && TryReplaceWithLoadIndexed(instr)) { |
| 1184 return; | 1189 return; |
| (...skipping 2516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3701 | 3706 |
| 3702 if (FLAG_trace_constant_propagation) { | 3707 if (FLAG_trace_constant_propagation) { |
| 3703 OS::Print("\n==== After constant propagation ====\n"); | 3708 OS::Print("\n==== After constant propagation ====\n"); |
| 3704 FlowGraphPrinter printer(*graph_); | 3709 FlowGraphPrinter printer(*graph_); |
| 3705 printer.PrintBlocks(); | 3710 printer.PrintBlocks(); |
| 3706 } | 3711 } |
| 3707 } | 3712 } |
| 3708 | 3713 |
| 3709 | 3714 |
| 3710 } // namespace dart | 3715 } // namespace dart |
| OLD | NEW |